From 543a4234b14920151aaf49312c81c905290fde05 Mon Sep 17 00:00:00 2001 From: admin <570810310@qq.com> Date: Tue, 30 Mar 2021 11:49:54 +0800 Subject: [PATCH] 1.1.4 --- README.md | 16 +- pom.xml | 143 +++++++++++++++++- .../yulichang/interceptor/MPJInterceptor.java | 109 +++++++++---- 3 files changed, 226 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index f96f929..0144811 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ QQ群:1022221898 com.github.yulichang mybatis-plus-join - 1.1.2 + 1.1.4 ``` 或者clone代码到本地,执行mvn install,再引入以上依赖 @@ -37,21 +37,15 @@ QQ群:1022221898 @Configuration public class MybatisPlusConfig { /** - * 启用连表拦截器 + * 连表拦截器 */ @Bean - public MybatisPlusInterceptor mybatisPlusInterceptor() { - MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); - //分页插件 - interceptor.addInnerInterceptor(new PaginationInnerInterceptor()); - //连表插件 - interceptor.addInnerInterceptor(new MPJInterceptor()); - //其他mp插件...... - return interceptor; + public MPJInterceptor mpjInterceptor() { + return new MPJInterceptor(); } /** - * sql注入器 + * 连表sql注入器 */ @Bean public MPJSqlInjector sqlInjector() { diff --git a/pom.xml b/pom.xml index ca82329..671d59d 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 com.github.yulichang mybatis-plus-join - 1.1.2 + 1.1.4 mybatis-plus-join An enhanced toolkit of Mybatis-Plus to simplify development. https://github.com/yulichang/mybatis-plus-join @@ -42,4 +42,145 @@ provided + + + + + org.apache.maven.plugins + maven-source-plugin + 2.2.1 + + + attach-sources + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.9.1 + + + attach-javadocs + + jar + + + + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.5 + + + sign-artifacts + verify + + sign + + + + + + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.8 + true + + ossrh + https://oss.sonatype.org/ + + 30 + + + + + + + disable-javadoc-doclint + + [1.8,) + + + -Xdoclint:none + + + + release + + + + org.apache.maven.plugins + maven-source-plugin + 2.2.1 + + + attach-sources + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.9.1 + + + attach-javadocs + + jar + + + + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.5 + + + sign-artifacts + verify + + sign + + + + + + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.7 + true + + ossrh + https://oss.sonatype.org/ + + 30 + + + + + + + + + ossrh + https://oss.sonatype.org/content/repositories/snapshots + + + ossrh + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + diff --git a/src/main/java/com/github/yulichang/interceptor/MPJInterceptor.java b/src/main/java/com/github/yulichang/interceptor/MPJInterceptor.java index e2d524e..09c7d92 100644 --- a/src/main/java/com/github/yulichang/interceptor/MPJInterceptor.java +++ b/src/main/java/com/github/yulichang/interceptor/MPJInterceptor.java @@ -1,58 +1,107 @@ package com.github.yulichang.interceptor; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; -import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor; +import com.github.yulichang.method.MPJResultType; import com.github.yulichang.toolkit.Constant; import org.apache.ibatis.executor.Executor; -import org.apache.ibatis.mapping.BoundSql; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.mapping.ResultMap; +import org.apache.ibatis.mapping.ResultMapping; +import org.apache.ibatis.plugin.Interceptor; +import org.apache.ibatis.plugin.Intercepts; +import org.apache.ibatis.plugin.Invocation; +import org.apache.ibatis.plugin.Signature; import org.apache.ibatis.session.ResultHandler; import org.apache.ibatis.session.RowBounds; -import java.lang.reflect.Field; -import java.sql.SQLException; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; /** - * 结果封装拦截器 + * 连表拦截器 + * 用于实现动态resultType + * 之前的实现方式是mybatis-plus的Interceptor,无法修改args,存在并发问题 + * 所以将这个拦截器独立出来 * * @author yulichang */ -public class MPJInterceptor implements InnerInterceptor { +@SuppressWarnings("unchecked") +@Intercepts(@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})) +public class MPJInterceptor implements Interceptor { + private static final List EMPTY_RESULT_MAPPING = new ArrayList<>(0); - private static Field type = null; - - static { - try { - type = ResultMap.class.getDeclaredField("type"); - type.setAccessible(true); - } catch (NoSuchFieldException e) { - e.printStackTrace(); - } - } + /** + * 缓存MappedStatement,不需要每次都去重写构建MappedStatement + */ + private static final Map MS_CACHE = new ConcurrentHashMap<>(); @Override - @SuppressWarnings("unchecked") - public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException { - if (parameter instanceof Map) { - Map map = (Map) parameter; - if (CollectionUtils.isNotEmpty(map)) { - try { - Class clazz = (Class) map.get(Constant.CLAZZ); - if (Objects.nonNull(clazz)) { - List list = ms.getResultMaps(); - if (CollectionUtils.isNotEmpty(list)) { - ResultMap resultMap = list.get(0); - type.set(resultMap, clazz); + public Object intercept(Invocation invocation) throws Throwable { + Object[] args = invocation.getArgs(); + if (args[0] instanceof MappedStatement) { + MappedStatement ms = (MappedStatement) args[0]; + Object parameter = args[1]; + if (parameter instanceof Map) { + Map map = (Map) parameter; + if (CollectionUtils.isNotEmpty(map)) { + try { + Class clazz = (Class) map.get(Constant.CLAZZ); + if (Objects.nonNull(clazz)) { + List list = ms.getResultMaps(); + if (CollectionUtils.isNotEmpty(list)) { + ResultMap resultMap = list.get(0); + if (resultMap.getType() == MPJResultType.class) { + args[0] = newMappedStatement(ms, clazz); + } + } } + } catch (Exception e) { + //通常是MapperMethod内部类HashMap的子类ParamMap重写了了get方法抛出的BindingException } - } catch (Exception ignored) { - //通常是MapperMethod内部类HashMap的子类ParamMap重写了了get方法抛出的BindingException } } } + return invocation.proceed(); + } + + /** + * 构建新的MappedStatement + */ + public MappedStatement newMappedStatement(MappedStatement ms, Class resultType) { + String id = ms.getId() + "_" + resultType.getName(); + MappedStatement statement = MS_CACHE.get(id); + if (Objects.nonNull(statement)) { + return statement; + } + MappedStatement.Builder builder = new MappedStatement.Builder(ms.getConfiguration(), id, ms.getSqlSource(), ms.getSqlCommandType()); + builder.resource(ms.getResource()) + .fetchSize(ms.getFetchSize()) + .statementType(ms.getStatementType()) + .keyGenerator(ms.getKeyGenerator()); + if (ms.getKeyProperties() != null && ms.getKeyProperties().length != 0) { + StringBuilder keyProperties = new StringBuilder(); + for (String keyProperty : ms.getKeyProperties()) { + keyProperties.append(keyProperty).append(","); + } + keyProperties.delete(keyProperties.length() - 1, keyProperties.length()); + builder.keyProperty(keyProperties.toString()); + } + builder.timeout(ms.getTimeout()) + .parameterMap(ms.getParameterMap()); + //count查询返回值int + List resultMaps = new ArrayList<>(); + ResultMap resultMap = new ResultMap.Builder(ms.getConfiguration(), ms.getId(), resultType, EMPTY_RESULT_MAPPING).build(); + resultMaps.add(resultMap); + builder.resultMaps(resultMaps) + .resultSetType(ms.getResultSetType()) + .cache(ms.getCache()) + .flushCacheRequired(ms.isFlushCacheRequired()) + .useCache(ms.isUseCache()); + MappedStatement mappedStatement = builder.build(); + MS_CACHE.put(id, mappedStatement); + return mappedStatement; } }