mybatis攔截器 修改mybatis返回結果集中的欄位的值

  • 2020 年 11 月 14 日
  • 筆記

項目中使用了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'}

 

感謝!