java - 关于mybatis拦截器,有谁知道怎么对结果集进行拦截,将指定字段查询结果进行格式化
阿神
阿神 2017-04-18 10:35:21
0
2
842
阿神
阿神

闭关修行中......

全部回覆(2)
小葫芦

MyBatis結果集攔截器做過這樣一個需求:

由於專案需求經常變動,專案MySQL資料庫都是存放JSON字串,例如:使用者的基本資訊隨著版本升級可能會有變動

資料表

CREATE TABLE `account` (
  `id` bigint(11) unsigned NOT NULL AUTO_INCREMENT,
  `infos` text NOT NULL COMMENT '用户JSON基本信息',
  `createTime` int(10) unsigned NOT NULL COMMENT '创建时间',
  `updateTime` int(10) unsigned NOT NULL COMMENT '更新时间',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

資料:

id infos createTime updateTime
1 {"nickName":"Jan","re​​gion_area":"","re​​gion_city":"深圳市","re​​gion_country":"中國","re​​gion_province":"廣東省","sex":"男" ,"signature":"只要不放棄就還有機會!"} 1467793564 1470795733

JSONPlugin攔截器

使用MyBatis拦截器对ResultSetHandler接口的handleResultSets攔截器對ResultSetHandler介面的handleResultSets方法進行攔截:

package me.xuebai.modules.mybatis;

import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.executor.resultset.ResultSetHandler;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import me.xuebai.modules.entity.Account;

@Intercepts({@Signature(
          type= ResultSetHandler.class,
          method = "handleResultSets",
          args = {Statement.class})})
public class JSONPlugin implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Object[] args = invocation.getArgs();
        // 获取到当前的Statement
        Statement stmt =  (Statement) args[0];
        // 通过Statement获得当前结果集
        ResultSet resultSet = stmt.getResultSet();
        List<Object> resultList = new ArrayList<Object>();  
        if(resultSet != null && resultSet.next()) {
            Account account = new Account();
            // infos字段
            String infos = resultSet.getString("infos");
            // 判断是否为空
            if(StringUtils.isNotBlank(infos)) {
                // fastjson泛型反序列化
                Map<String, Object> infMap = JSON.parseObject(infos, new TypeReference<Map>(){});
                account.setInfos(infMap);
                resultList.add(account);
            }
            // handleResultSets返回结果一定是一个List
            // size为1时,Mybatis会取第一个元素作为接口的返回值。  
            return resultList;
        }
        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
         return Plugin.wrap(target, this); 
    }

    @Override
    public void setProperties(Properties properties) {
    }

}

mybatis-config.xml

在mybatis設定檔中註冊外掛程式:

<plugins>
        <plugin interceptor="me.xuebai.modules.mybatis.JSONPlugin"></plugin>
</plugins>

測試輸出

Account account = accountDao.get(1L);
// {sex=男, region_city=深圳市, region_area=, nickName=Jan, region_country=中国, signature=只要不放弃就还有机会!, region_province=广东省}
System.out.println(account.getInfos());
洪涛

Mybatis實現過以下需求

查詢使用者基本資訊表,查詢結果傳回是List>的結果集,對其中的某個欄位進行加密

資料表

CREATE TABLE usr_basic_inf(
    USR_ID               VARCHAR(20)       NOT NULL      COMMENT '用户ID,01+18位互斥随机数'    ,
    USR_REAL_NME         VARCHAR(50)       NOT NULL      COMMENT '用户真实姓名'              ,
    CERT_TYPE            VARCHAR(4)                      COMMENT '证件种类'                ,
    CERT_NO              VARCHAR(100)                    COMMENT '证件号码'                ,
    RES_FLD              VARCHAR(300)                    COMMENT '预留字段 '               ,
    PRIMARY KEY(USR_ID)
) COMMENT='用户基础信息表';

數據

USR_ID USR_REAL_NME CERT_TYPE CERT_NO RES_FLD
01000000000000000001 張三 0101 101222010199913291 (NULL)

使用MybatisExecutor.class'qurey'Executor.class'qurey'方法進行攔截,並對返回結果集進行處理

package com.ceabox.interceptor;

import java.util.ArrayList;
import java.util.Map;
import java.util.Properties;

import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;

@Intercepts({ @Signature(type = Executor.class, method = "query", args = { MappedStatement.class, Object.class,
        RowBounds.class, ResultHandler.class }) })
public class InterceptorForQry implements Interceptor {

    @SuppressWarnings({ "rawtypes", "unchecked" })
    public Object intercept(Invocation invocation) throws Throwable {
        Object result = invocation.proceed(); //执行请求方法,并将所得结果保存到result中
        if (result instanceof ArrayList) {
            ArrayList resultList = (ArrayList) result;
            for (int i = 0; i < resultList.size(); i++) {
                if (resultList.get(i) instanceof Map) {
                    Map resultMap = (Map) resultList.get(i);
                    resultMap.put("CERT_NO", "这个是加密结果"); //取出相应的字段进行加密
                }
            }
        }
        return result;
    }

    public Object plugin(Object target) {
        System.out.println("this is the proceed ===>>" + target);
        return Plugin.wrap(target, this);
    }

    public void setProperties(Properties arg0) {
        System.out.println("this is the properties ===>>" + arg0);
    }
}

mybatis-config.xml

在mybatis設定檔中註冊外掛程式:

<plugins>
    <plugin interceptor="com.ceabox.interceptor.InterceptorForQry"></plugin>
</plugins>

測試輸出

{ USR_ID=01000000000000000001, RES_FLD=null, CERT_NO=这个是加密结果, CERT_TYPE=0101, USR_REAL_NME=张三 }
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板