欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2023-02-02 09:55:07
在(一)敏感信息混淆中处理了加密字段,但如果要把这个加密字段使用mybatis入库,则会报以下错误: 简单看就是自定义的类型识别不了,这个时候我们就可以用到mybatis的TypeHandler了,TypeHandler有4个参数: public interface TypeHandler { ......

中处理了加密字段,但如果要把这个加密字段使用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