首页 > 其他分享 >Mybatis Interceptor 经典场景

Mybatis Interceptor 经典场景

时间:2023-08-15 10:26:07浏览次数:38  
标签:场景 invocation ibatis apache org Mybatis import Interceptor class

1.Mybatis Interceptor 的应用场景很多,比如sql语句动态生成,resultMap动态生成

下面就用代码来分析下resultMap动态生成吧,这个是ORM框架常用的功能哦

 1 package com.xx.transjob.common.db;
 2 
 3 import com.baomidou.mybatisplus.annotation.TableName;
 4 import org.apache.ibatis.cache.CacheKey;
 5 import org.apache.ibatis.executor.Executor;
 6 import org.apache.ibatis.mapping.BoundSql;
 7 import org.apache.ibatis.mapping.MappedStatement;
 8 import org.apache.ibatis.mapping.ResultMap;
 9 import org.apache.ibatis.mapping.ResultMapping;
10 import org.apache.ibatis.plugin.Interceptor;
11 import org.apache.ibatis.plugin.Intercepts;
12 import org.apache.ibatis.plugin.Invocation;
13 import org.apache.ibatis.plugin.Signature;
14 import org.apache.ibatis.session.ResultHandler;
15 import org.apache.ibatis.session.RowBounds;
16 import org.springframework.stereotype.Component;
17 import org.springframework.util.ClassUtils;
18 import org.springframework.util.CollectionUtils;
19 import org.springframework.util.ReflectionUtils;
20 
21 import java.lang.reflect.Field;
22 import java.util.ArrayList;
23 import java.util.Collection;
24 import java.util.Collections;
25 import java.util.List;
26 
27 @Component
28 @Intercepts({
29         @Signature(type = Executor.class, method = "query",
30                 args = { MappedStatement.class, Object.class,
31                         RowBounds.class, ResultHandler.class }),
32         @Signature(type = Executor.class, method = "query",
33                 args = { MappedStatement.class, Object.class, RowBounds.class,
34                         ResultHandler.class, CacheKey.class, BoundSql.class }),
35 })
36 public class ResultInterceptor implements Interceptor {
37     @Override
38     public Object intercept(Invocation invocation) throws Throwable {
39         if (!(invocation.getTarget() instanceof Executor)) {
40             return invocation.proceed();
41         }
42         MappedStatement ms = (MappedStatement) invocation.getArgs()[0];
43         if (ms.getResource().contains(".xml")) {
44             return invocation.proceed();
45         }
46         ResultMap resultMap = ms.getResultMaps().iterator().next();
47         if (!CollectionUtils.isEmpty(resultMap.getResultMappings())) {
48             return invocation.proceed();
49         }
50         Class<?> mapType = resultMap.getType();
51         if (ClassUtils.isAssignable(mapType, Collection.class)
52             ||mapType.getAnnotation(TableName.class)==null) {
53             return invocation.proceed();
54         }
55         //根据返回类型查找model类型
56         DbUtils.ModelClassInfo modelClassInfo=DbUtils.getModelClassInfo(mapType);
57         List<ResultMapping> resultMappings = new ArrayList<>(modelClassInfo.modelFields.size());
58         //根据model动态生成resultMap
59         for(DbUtils.ModelFieldInfo fieldInfo:modelClassInfo.modelFields){
60             ResultMapping resultMapping = new ResultMapping.Builder(ms.getConfiguration(),
61                     fieldInfo.field.getName(),
62                     fieldInfo.column, fieldInfo.field.getType()).build();
63             resultMappings.add(resultMapping);
64         }
65         ResultMap resultMapReal=new ResultMap.Builder(ms.getConfiguration(),resultMap.getId(),mapType,resultMappings,true).build();
66         //替换原来的resultMaps
67         Field field = ReflectionUtils.findField(MappedStatement.class, "resultMaps");
68         ReflectionUtils.makeAccessible(field);
69         ReflectionUtils.setField(field, ms, Collections.singletonList(resultMapReal));
70         return invocation.proceed();
71     }
72 }

 

标签:场景,invocation,ibatis,apache,org,Mybatis,import,Interceptor,class
From: https://www.cnblogs.com/dint/p/17630600.html

相关文章

  • 《高级程序员 面试攻略 》rabitmq rcoketmq kafka的区别 和应用场景
    RabbitMQ、RocketMQ和Kafka都是流行的消息中间件系统,用于实现分布式应用程序之间的异步通信。虽然它们都有类似的目标,但在设计和应用场景上存在一些区别。1.RabbitMQ(兔子消息队列):-描述:RabbitMQ是一个开源的消息代理系统,实现了高性能、可靠的消息传递机制。它使用AMQP(高......
  • Mybatis操作数据库流程源码
    Java操作数据库需要经过3个大步骤:获取数据库连接执行SQL语句关闭数据库连接Mybatis将这几个步骤进行了封装,将获取数据库连接的给工作交给了SqlSessionFactory,将执行SQL的工作交给了SqlSession。1获取SqlSession在程序启动时,会根据配置创建SqlSessionFactory:SqlSessionFa......
  • 设计模式大全:覆盖各类场景的实用模式与结构图
    设计模式大全:覆盖各类场景的实用模式与结构图目录设计模式大全:覆盖各类场景的实用模式与结构图1、设计模式六大原则(SOLID)2、设计模式分类及适用场景3、GOF经典设计模式及其结构图3-1、创建型1)工厂模式-FactoryPattern2)抽象工厂模式-AbstractFactoryPattern3)单例模式-Singleton......
  • Mybatis配置文件的空白模板和联系demo所用到的依赖
    核心配置文件模板<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPEconfigurationPUBLIC"-//mybatis.org//DTDConfig3.0//EN""https://mybatis.org/dtd/mybatis-3-config.dtd"><configuration><envir......
  • mybatis insert foreach批量添加
    mybatisinsertforeach批量添加intinsertSelectiveBatch(List<ImageDetailEntity>myList);//写法1<insertid="insertSelectiveBatch"><foreachitem="record"collection="list"separator=",">......
  • MyBatis-Plus中IdType策略不生效的问题
    问题背景在开发过程中,我们经常会使用MyBatis-Plus来简化与数据库的交互,其中IdType是一个重要的配置项,用于指定实体类中主键的生成策略。然而,在使用Mapper文件进行插入操作时,有时候会遇到IdType策略不生效的情况,这引发了我对问题的深入探索。今天在修改公司接口时,顺手测试了......
  • mybatis 插件
    插件的使用1、在配置文件配置plugins<plugins><plugininterceptor="com.test.plugin.MyBatisInterceptor"></plugin>...</plugins>2、拦截器开发实现Interceptor接口,在对应的拦截器类上配置注解,指定拦截方法@Intercepts(@Signature(type=Executor.cl......
  • mybatis中的日志
    日志工厂如果一个数据库操作,出现了异常,我们需要排错。日志就是最好的助手!曾经:sout、debug现在:日志工厂!在Mybatis中具体使用那个日志实现,在设置中设定!STDOUT_LOGGING标准日志输出在mybatis核心配置文件中,配置我们的日志!<settings><settingname="logImpl......
  • mybatis中生命周期和作用域
    生命周期,和作用域,是至关重要的,因为错误的使用会导致非常严重的并发问题。SqlSessionFactoryBuilder:●一旦创建了SqlSessionFactory,就不再需要它了●局部变量SqlSessionFactory:●说白了就是可以想象为:数据库连接池●SqlSessionFactory一旦被创建就应该在应用的运行期间一直存......
  • Mybatis中parameterType用map传参和resultMap结果集映射
    万能的map:假如实体类(数据库中的表)字段数或参数过多,应当考虑到使用map。(因为如果写一个sql语句,前端传回来的数据就几个而且需要传入的参数类型是实体类,那么我们在contorller层就要构造一个有很多null值的对象传入这样就很麻烦,使用map就很简便了)xml配置文件中parameterType属性是传......