项目中使用了shardingJDBC,业务库做了分库,公共库没在一起,所以导致做码值转换的时候,需要在实现类里面做转码,重复的代码量大,故考虑用mybatis拦截器,将码值转换后再做返回给实现类。
import org.apache.commons.beanutils.BeanUtils; import org.apache.ibatis.executor.resultset.DefaultResultSetHandler; import org.apache.ibatis.executor.resultset.ResultSetHandler; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.mapping.ResultMap; import org.apache.ibatis.plugin.*; import org.apache.ibatis.reflection.MetaObject; import org.apache.ibatis.reflection.SystemMetaObject; import org.apache.ibatis.session.Configuration; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.Statement; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Properties; @Intercepts({ @Signature(type = ResultSetHandler.class, method = "handleResultSets", args = { Statement.class }) }) public class MyPlugin implements Interceptor { // //这里是每次执行操作的时候,都会进行这个拦截器的方法内 public Object intercept(Invocation invocation) throws Throwable { List resList = new ArrayList(); DefaultResultSetHandler defaultResultSetHandler = (DefaultResultSetHandler) invocation.getTarget(); MetaObject metaStatementHandler = SystemMetaObject.forObject(defaultResultSetHandler); MappedStatement mappedStatement = (MappedStatement) metaStatementHandler.getValue("mappedStatement"); //获取节点属性的集合 List<ResultMap> resultMaps = mappedStatement.getResultMaps(); Configuration configuration = (Configuration)metaStatementHandler.getValue("configuration"); Class<?> resultType = resultMaps.get(0).getType(); //获取mybatis返回的实体类类型名 int resultMapCount = resultMaps.size(); if (resultMapCount > 0) { Statement statement = (Statement) invocation.getArgs()[0]; ResultSet resultSet = statement.getResultSet(); if (resultSet != null) { //获得对应列名 ResultSetMetaData rsmd = resultSet.getMetaData(); List<String> columnList = new ArrayList<String>(); for (int i = 1; i <= rsmd.getColumnCount(); i++) { columnList.add(rsmd.getColumnName(i)); } while (resultSet.next()) { LinkedHashMap<String, Object> resultMap = new LinkedHashMap<String, Object>(); for (String colName : columnList) { resultMap.put(colName, resultSet.getString(colName)); //具体些要转换的码值这里就做个演示 if(colName.equals("username")){ resultMap.put(colName, "iui"); } } Object o = resultType.newInstance(); //将转换后的map转换为实体类中 BeanUtils.populate(o,resultMap); resList.add(o); } return resList; } } return invocation.proceed(); } /** * //主要是为了把这个拦截器生成一个代理放到拦截器链中 * ^Description包装目标对象 为目标对象创建代理对象 * @Param target为要拦截的对象 * @Return代理对象 */ public Object plugin(Object target) { System.out.println("将要包装的目标对象:"+target); return Plugin.wrap(target,this); } public void setProperties(Properties properties) { } }
sqlMapperConfig.xml中添加拦截器
<plugins> <plugin interceptor="com.lagou.plugin.MyPlugin"></plugin> </plugins>
mybatis查询的的原数据
<== Columns: id, username, password, birthday <== Row: 1, lys, 123, 2019-12-12 <== Row: 2, tom, 1223, 2019-12-12 <== Row: 3, zt, 3211645, 1988-02-01 <== Row: 5, jack, 37652, 1958-05-05 <== Row: 6, jacket, 37652, 2008-05-05 <== Row: 7, jack, 37652, 1958-05-05 <== Total: 6
加入插件后返回的实体类对象
User{id=1, username='iui', password='123', birthday='2019-12-12'} User{id=2, username='iui', password='1223', birthday='2019-12-12'} User{id=3, username='iui', password='3211645', birthday='1988-02-01'} User{id=5, username='iui', password='37652', birthday='1958-05-05'} User{id=6, username='iui', password='37652', birthday='2008-05-05'} User{id=7, username='iui', password='37652', birthday='1958-05-05'}
感谢!