This commit is contained in:
admin 2021-03-30 11:49:54 +08:00
parent 2e08feca7f
commit 543a4234b1
3 changed files with 226 additions and 42 deletions

View File

@ -23,7 +23,7 @@ QQ群:1022221898
<dependency> <dependency>
<groupId>com.github.yulichang</groupId> <groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join</artifactId> <artifactId>mybatis-plus-join</artifactId>
<version>1.1.2</version> <version>1.1.4</version>
</dependency> </dependency>
``` ```
或者clone代码到本地,执行mvn install,再引入以上依赖 或者clone代码到本地,执行mvn install,再引入以上依赖
@ -37,21 +37,15 @@ QQ群:1022221898
@Configuration @Configuration
public class MybatisPlusConfig { public class MybatisPlusConfig {
/** /**
* 启用连表拦截器 * 连表拦截器
*/ */
@Bean @Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() { public MPJInterceptor mpjInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); return new MPJInterceptor();
//分页插件
interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
//连表插件
interceptor.addInnerInterceptor(new MPJInterceptor());
//其他mp插件......
return interceptor;
} }
/** /**
* sql注入器 * 连表sql注入器
*/ */
@Bean @Bean
public MPJSqlInjector sqlInjector() { public MPJSqlInjector sqlInjector() {

143
pom.xml
View File

@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>com.github.yulichang</groupId> <groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join</artifactId> <artifactId>mybatis-plus-join</artifactId>
<version>1.1.2</version> <version>1.1.4</version>
<name>mybatis-plus-join</name> <name>mybatis-plus-join</name>
<description>An enhanced toolkit of Mybatis-Plus to simplify development.</description> <description>An enhanced toolkit of Mybatis-Plus to simplify development.</description>
<url>https://github.com/yulichang/mybatis-plus-join</url> <url>https://github.com/yulichang/mybatis-plus-join</url>
@ -42,4 +42,145 @@
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
</dependencies> </dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>1.6.8</version>
<extensions>true</extensions>
<configuration>
<serverId>ossrh</serverId>
<nexusUrl>https://oss.sonatype.org/</nexusUrl>
<!-- <autoReleaseAfterClose>true</autoReleaseAfterClose>-->
<stagingProgressTimeoutMinutes>30</stagingProgressTimeoutMinutes>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>disable-javadoc-doclint</id>
<activation>
<jdk>[1.8,)</jdk>
</activation>
<properties>
<additionalparam>-Xdoclint:none</additionalparam>
</properties>
</profile>
<profile>
<id>release</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>1.6.7</version>
<extensions>true</extensions>
<configuration>
<serverId>ossrh</serverId>
<nexusUrl>https://oss.sonatype.org/</nexusUrl>
<!-- <autoReleaseAfterClose>true</autoReleaseAfterClose>-->
<stagingProgressTimeoutMinutes>30</stagingProgressTimeoutMinutes>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<distributionManagement>
<snapshotRepository>
<id>ossrh</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
</snapshotRepository>
<repository>
<id>ossrh</id>
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
</repository>
</distributionManagement>
</project> </project>

View File

@ -1,58 +1,107 @@
package com.github.yulichang.interceptor; package com.github.yulichang.interceptor;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; 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 com.github.yulichang.toolkit.Constant;
import org.apache.ibatis.executor.Executor; import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ResultMap; 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.ResultHandler;
import org.apache.ibatis.session.RowBounds; import org.apache.ibatis.session.RowBounds;
import java.lang.reflect.Field; import java.util.ArrayList;
import java.sql.SQLException;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
/** /**
* 结果封装拦截器 * 连表拦截器
* 用于实现动态resultType
* 之前的实现方式是mybatis-plus的Interceptor,无法修改args,存在并发问题
* 所以将这个拦截器独立出来
* *
* @author yulichang * @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<ResultMapping> EMPTY_RESULT_MAPPING = new ArrayList<>(0);
private static Field type = null; /**
* 缓存MappedStatement,不需要每次都去重写构建MappedStatement
static { */
try { private static final Map<String, MappedStatement> MS_CACHE = new ConcurrentHashMap<>();
type = ResultMap.class.getDeclaredField("type");
type.setAccessible(true);
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
@Override @Override
@SuppressWarnings("unchecked") public Object intercept(Invocation invocation) throws Throwable {
public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException { Object[] args = invocation.getArgs();
if (parameter instanceof Map) { if (args[0] instanceof MappedStatement) {
Map<String, ?> map = (Map<String, ?>) parameter; MappedStatement ms = (MappedStatement) args[0];
if (CollectionUtils.isNotEmpty(map)) { Object parameter = args[1];
try { if (parameter instanceof Map) {
Class<?> clazz = (Class<?>) map.get(Constant.CLAZZ); Map<String, ?> map = (Map<String, ?>) parameter;
if (Objects.nonNull(clazz)) { if (CollectionUtils.isNotEmpty(map)) {
List<ResultMap> list = ms.getResultMaps(); try {
if (CollectionUtils.isNotEmpty(list)) { Class<?> clazz = (Class<?>) map.get(Constant.CLAZZ);
ResultMap resultMap = list.get(0); if (Objects.nonNull(clazz)) {
type.set(resultMap, clazz); List<ResultMap> 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<ResultMap> 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;
} }
} }