Spring boot mybatis typehandler 自定义参数处理,去除插入更新查询重复typehandler指定,删除typehandler

数据库编码格式是latin1,而java项目代码都是UTF-8

导致所有String字段都需要转码,目前项目中方法是所有实体类的Set方法都包了一层转码

public void setMemberShortName(String memberShortName) {
    this.memberShortName = Code.StrCode(memberShortName);
  }

作为程序员当然是怎么偷懒怎么来了.这么多实体类这么多String都要挨个改,再来个Date时间类已经疯了

况且这实体类就区分DB和普通的还不能复用更令人炸毛了.

所以想办法得让mybatis读写存取数据的时候进行"转码",实现技术关键字就是TypeHandler 

放在官方网站链接http://www.mybatis.org/mybatis-3/configuration.html#typeHandlers

网上帖子都很多,原理我就不多说了,说说我的实现都干了哪些事吧

1.重写类,

package com.easyserp.config;

 
import org.apache.ibatis.type.*; 
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

@Component
@MappedTypes(String.class)
@MappedJdbcTypes(JdbcType.VARCHAR)
public class StringTypeHandlerConfig implements TypeHandler<String> { 

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i,
                                    String parameter, JdbcType jdbcType) throws SQLException {
        //这里处理参数parameter, 因为我是字符串,所以就转码业务
        //例如  
        parameter=转码工具类.Utf8Tolatin1(paramenter);
        ps.setString(i, parameter);
    }

    @Override
    public String getNullableResult(ResultSet rs, String columnName)
            throws SQLException {
        //注意这个处理的返回值是结果,需要转换它
        //例如 
        String result=转码工具类.Latin1ToUtf8(rs.getString(columnName));
        return result;
    }

    @Override
    public String getNullableResult(ResultSet rs, int columnIndex)
            throws SQLException {
        //同方法二,注意处理是getString以后的值
        return rs.getString(columnIndex);
    }

    @Override
    public String getNullableResult(CallableStatement cs, int columnIndex)
            throws SQLException {
         //同方法二,注意处理是getString以后的值
        return cs.getString(columnIndex);
    }
}

 

2.插入时,一定要将values后面的参数写上typeHandler

(因为的就测试这一个字段,所以就这一个字段添加了typeHandler)

 

3.查询还是问题的.还是会乱码

稍微填点东西就好了,只要将resultMap写好,返回用resultMap,里面指定typeHandler,这个调用的是剩下的三个方法.

  <resultMap id="braceletResult" type="com.***.pojo.BroadcastData">
        <result   column="stepCount" property="stepCount"  typeHandler="com.***.config.StringTypeHandlerConfig"/>
    </resultMap>
    <select id="getUserByOpenId"   resultMap="braceletResult">
        select stepCount from tb_broadcastdata where openId = #{openId}
    </select>

二更:这种写法不管是增删改查都要指定typeHandler,要死.

所以Spring 注入下手.@Bean  SqlSessionFactory的时候添加到Handler里面,我这个项目中有动态数据源,所以直接添加了一行

 TypeHandler<?>[]  typeHandlers=new TypeHandler[]{stringTypeHandlerConfig};
 fb.setTypeHandlers(typeHandlers);

 完整bean注入如下.(@Qualifier("memberDbDataSource")这些不用管,这都是动态数据源的东西,)主要是上面两行注入进去

这样在mapper中只要指定javaType和jdbcType就好了

      @Autowired
    StringTypeHandlerConfig stringTypeHandlerConfig;    

    /**
     * 根据数据源创建SqlSessionFactory
     */
    @Bean
    public SqlSessionFactory sqlSessionFactory(@Qualifier("memberDbDataSource") DataSource memberDbDataSource) throws Exception {
        fb = new SqlSessionFactoryBean();
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        // 指定数据源(这个必须有,否则报错)
        fb.setDataSource(this.dataSource(memberDbDataSource));
        // 下边两句仅仅用于*.xml文件,如果整个持久层操作不需要使用到xml文件的话(只用注解就可以搞定),则不加
        // 指定基包
        fb.setTypeAliasesPackage(env.getProperty("mybatis.type-aliases-package"));
        //
        fb.setMapperLocations(resolver.getResources(env.getProperty("mybatis.mapper-locations")));
        TypeHandler<?>[]  typeHandlers=new TypeHandler[]{stringTypeHandlerConfig};
        fb.setTypeHandlers(typeHandlers);
        return fb.getObject();
    }

 

 

ps:包名扫描我没有加也行,因为都指明了,如果失败可以加上这个试试

mybatis.type-handlers-package =com.***.config

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值