数据库编码格式是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 {
@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,这个调用的是剩下的三个方法.
二更:这种写法不管是增删改查都要指定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