Mybatis Interceptor 經典場景

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 }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章