Mybatis 插件 ResultSetHandler 笔记整理

编写基础功能部分
  1. 编写Interceptor实现类拦截ResultSetHandler的handleResultSets方法
    @Component
    @Intercepts(@Signature(method = "handleResultSets", type = ResultSetHandler.class, args = { Statement.class }))
    public class ResultHandlerInterceptor implements Interceptor {
        @Override
        public Object intercept(Invocation invocation) throws Throwable {
            ResultSetHandler resultSetHandler = (ResultSetHandler)invocation.getTarget() ;
            MetaObject metaObject = SystemMetaObject.forObject(resultSetHandler);
            MappedStatement mappedStatement = (MappedStatement)metaObject.getValue("mappedStatement") ;
            SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType();
            if (sqlCommandType == SqlCommandType.SELECT){
                String mapper = StringUtils.join(mappedStatement.getResultSets()) ;
                log.info("ResultHandlerInterceptor.intercept,mapperRow:{}", mapper);
                if (!StringUtils.isEmpty(mapper)){
                    Statement statement = (Statement)invocation.getArgs()[0] ;
                    return execHandlerResult(mapper, statement.getResultSet()) ;
                }
            }
            return invocation.proceed();
        }
        private Object execHandlerResult(String mapper, ResultSet rs) throws SQLException {
            try {
                ResultMapper resultMapper = ApplicationContextUtil.getBean4ResultMapper(mapper);
                if (resultMapper != null){
                    return resultMapper.handler(rs) ;
                }
            }finally {
                if (rs != null){
                    rs.close();
                }
            }
            return null ;
        }
    }
    
  2. 编写结果集映射接口
    public interface ResultMapper<T> {
        /**
         * 默认返回List集合,子类可重写此方法返回特定类型
         * eg: Map,或则Integer
         * @param rs
         * @return
         * @throws SQLException
         */
        default Object handler(ResultSet rs) throws SQLException {
            List<T> result = Lists.newArrayList() ;
            int row =1 ;
            while (rs !=null && rs.next()){
                result.add(handlerRow(rs, row)) ;
                row ++ ;
            }
            return result ;
        }
    
        T handlerRow(ResultSet rs, int rowNum) throws SQLException ;
    }
    
  3. 编写Spring工具获取ResultMapper实现类
    @Component
    public class ApplicationContextUtil implements ApplicationContextAware {
        private static ApplicationContext context ;
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            context = applicationContext ;
        }
        public static ResultMapper getBean4ResultMapper(String beanName){
            return (ResultMapper)context.getBean(beanName) ;
        }
    }
    
编写具体业务部分
  1. 编写查询sql, 注意resultSets中的内容userItemResultMapper与后面编写的结果集映射组件id保持一致
    <select id="selectByUserItemResultMapper" resultSets="userItemResultMapper">
        select id ,username, password, roles from user u
    </select>
    
  2. 定制查询返回值类型(如果仅返回普通list中封装对象,则不需要写此类)
    public class MyKeyList<T> extends ArrayList<T> {
        private Map<String, T> data = new HashMap<>() ;
        public boolean add(String id ,T t) {
            data.put(id, t) ;
            return super.add(t);
        }
        public Map<String,T> getData(){
            return data ;
        }
        public Set<String> getKeys(){
            return data.keySet() ;
        }
    }
    
  3. 编写Mapper方法
    @Mapper
    public interface UserMapper {
        MyKeyList<User> selectByUserItemResultMapper() ;
    }
    
  4. 编写selectByUserItemResultMapper方法对应结果集映射实现,注意这里bean的id与xml文件中的resultSets内容一致
    @Component("userItemResultMapper")
    public class UserItemResultMapper implements ResultMapper<User> {
        // 具体返回类型根据Mapper中定义(如果仅需要返回普通的list则此方法不需要重写)
        @Override
        public Object handler(ResultSet rs) throws SQLException {
            MyKeyList<User> list = new MyKeyList<>() ;
            int row = 1 ;
            while (rs != null && rs.next()){
                list.add(rs.getInt(1) +"", handlerRow(rs, row)) ;
            }
            return list;
        }
        @Override
        public User handlerRow(ResultSet rs, int rowNum) throws SQLException {
            User user = new User();
            user.setId(rs.getInt(1)) ;
            user.setUsername(rs.getString(2));
            user.setPassword(rs.getString(3));
            user.setRoles(rs.getString(4));
            return user;
        }
    }
    
  5. 编写单元测试
    @Test
    public void selectByUserItemResultMapper(){
        MyKeyList<User> list = userMapper.selectByUserItemResultMapper();
        list.forEach(user -> log.info("{}", user));
        Set<String> keys = list.getKeys();
        keys.forEach(id -> log.info("id : {}", id));
    }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值