搜索

首页  >  问答  >  正文

java - 关于mybatis拦截器,有谁知道怎么对结果集进行拦截,将指定字段查询结果进行格式化

阿神阿神2807 天前852

全部回复(2)我来回复

  • 高洛峰

    高洛峰2017-04-18 10:37:21

    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","region_area":"","region_city":"深圳市","region_country":"中国","region_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());

    回复
    0
  • PHP中文网

    PHP中文网2017-04-18 10:37:21

    Mybatis实现过如下需求

    查询用户基本信息表,查询结果返回是List<Map<String,Object>>的结果集,对其中的某个字段进行加密

    数据表

    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=张三 }

    回复
    0
  • 取消回复