(六)加密的字段类型入库


(一)敏感信息混淆中处理了加密字段,但如果要把这个加密字段使用mybatis入库,则会报以下错误:

Caused by: java.lang.IllegalStateException: Type handler was null on parameter mapping for property 'secret'. It was either not specified and/or could not be found for the javaType (github.zhangq.secretstringtest.config.SecretString) : jdbcType (null) combination.
    at org.apache.ibatis.mapping.ParameterMapping$Builder.validate(ParameterMapping.java:119)
    at org.apache.ibatis.mapping.ParameterMapping$Builder.build(ParameterMapping.java:104)
    at org.apache.ibatis.builder.SqlSourceBuilder$ParameterMappingTokenHandler.buildParameterMapping(SqlSourceBuilder.java:123)
    at org.apache.ibatis.builder.SqlSourceBuilder$ParameterMappingTokenHandler.handleToken(SqlSourceBuilder.java:67)
    at org.apache.ibatis.parsing.GenericTokenParser.parse(GenericTokenParser.java:78)
    at org.apache.ibatis.builder.SqlSourceBuilder.parse(SqlSourceBuilder.java:45)
    at org.apache.ibatis.scripting.defaults.RawSqlSource.<init>(RawSqlSource.java:46)
    at org.apache.ibatis.scripting.defaults.RawSqlSource.<init>(RawSqlSource.java:40)
    at org.apache.ibatis.scripting.xmltags.XMLScriptBuilder.parseScriptNode(XMLScriptBuilder.java:72)
    at org.apache.ibatis.scripting.xmltags.XMLLanguageDriver.createSqlSource(XMLLanguageDriver.java:44)
    at org.apache.ibatis.builder.xml.XMLStatementBuilder.parseStatementNode(XMLStatementBuilder.java:94)
    at org.apache.ibatis.builder.xml.XMLMapperBuilder.buildStatementFromContext(XMLMapperBuilder.java:135)
    at org.apache.ibatis.builder.xml.XMLMapperBuilder.buildStatementFromContext(XMLMapperBuilder.java:128)
    at org.apache.ibatis.builder.xml.XMLMapperBuilder.configurationElement(XMLMapperBuilder.java:118)
    ... 82 more

简单看就是自定义的类型识别不了,这个时候我们就可以用到mybatis的TypeHandler了,TypeHandler有4个参数:

public interface TypeHandler<T> {

  void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException;

  T getResult(ResultSet rs, String columnName) throws SQLException;

  T getResult(ResultSet rs, int columnIndex) throws SQLException;

  T getResult(CallableStatement cs, int columnIndex) throws SQLException;

}
View Code

看参数命名,可以很简单的理解到方法的意思,那么我们定义一个TypeHandler,分别实现这4个方法,如下:

/**
 * @author zhangqiuyang
 * Created on 2018/8/17.
 */

@MappedTypes(value = {SecretString.class})
public class SecretStringTypeHandler implements TypeHandler<SecretString> {

    /**
     * @param rs
     * @param columnName
     * @return
     * @throws SQLException
     */
    @Override
    public SecretString getResult(ResultSet rs, String columnName) throws SQLException {
        String value = rs.getString(columnName);
        if (value != null) {
            return new SecretString(value);
        }
        return null;
    }

    /**
     * @param rs
     * @param columnIndex
     * @return
     * @throws SQLException
     */
    @Override
    public SecretString getResult(ResultSet rs, int columnIndex) throws SQLException {
        String value = rs.getString(columnIndex);
        if (value != null) {
            return new SecretString(value);
        }
        return null;
    }

    /**
     * @param cs
     * @param columnIndex
     * @return
     * @throws SQLException
     */
    @Override
    public SecretString getResult(CallableStatement cs, int columnIndex) throws SQLException {
        String value = cs.getString(columnIndex);
        if (value != null) {
            return new SecretString(value);
        }
        return null;
    }

    /**
     * @param ps
     * @param i
     * @param parameter
     * @param arg3
     * @throws SQLException
     */
    @Override
    public void setParameter(PreparedStatement ps, int i, SecretString parameter, JdbcType arg3) throws SQLException {
        String value = "";
        if (parameter != null) {
            value = parameter.toString();
        }
        ps.setString(i, value);
    }
}
View Code

实现完成后,需要指定下配置,让mybatis扫描到这个TypeHandler,在application.yml增加mybatis.type-handlers-package:typehandler所在的包名。如果想从代码中注入配置,则需要在SqlSessionFactory的时候setVfs

 @Bean(name = "sqlSessionFactory")
 @Primary
 public SqlSessionFactory sqlSessionFactory(@Qualifier("dataSource") DataSource dataSource,
                                                   @Qualifier("configuration") org.apache.ibatis.session.Configuration configuration) throws Exception {
     SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
     bean.setVfs(SpringBootVFS.class);
     bean.setTypeHandlersPackage("xxxxxx");
     bean.setDataSource(dataSource);
     bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapping/*.xml"));
     bean.setConfiguration(configuration);return bean.getObject();
 }

 github:https://github.com/zqyx5201/SecretStringTest


作者:张q,发布于:2018/10/11
原文:https://www.cnblogs.com/zqyx/p/9774215.html