mirror of
https://gitee.com/best_handsome/mybatis-plus-join
synced 2025-07-25 00:00:12 +08:00
update
This commit is contained in:
parent
e26aad80b2
commit
567cae431a
88
README.md
88
README.md
@ -8,31 +8,38 @@
|
|||||||
|
|
||||||
### 方法一
|
### 方法一
|
||||||
|
|
||||||
1. 将代码down到本地,使用maven install
|
1. 在项目中添加依赖,依赖已经包含了mybatis-plus3.4.2,依赖后无需再次引入mybatis-plus
|
||||||
|
|
||||||
2. 在自己的项目中添加依赖
|
|
||||||
|
|
||||||
```xml
|
```xml
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.yulichang</groupId>
|
<groupId>com.github.yulichang</groupId>
|
||||||
<artifactId>mybatis-plus-join</artifactId>
|
<artifactId>mybatis-plus-join</artifactId>
|
||||||
<version>1.0.0-SNAPSHOT</version>
|
<version>1.0.5</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
```
|
```
|
||||||
|
|
||||||
### 方法二
|
2. 配置插件,添加MyJoinInterceptor
|
||||||
|
|
||||||
1. 将mybatisplus目录复制到你的工程中的springboot扫描路径下
|
```java
|
||||||
|
|
||||||
2. 添加cglib依赖
|
@Configuration
|
||||||
|
public class MybatisPlusConfig {
|
||||||
|
|
||||||
```xml
|
/**
|
||||||
<dependency>
|
* 启用连表拦截器
|
||||||
<groupId>cglib</groupId>
|
*/
|
||||||
<artifactId>cglib</artifactId>
|
@Bean
|
||||||
<version>3.3.0</version>
|
public MybatisPlusInterceptor paginationInterceptor() {
|
||||||
</dependency>
|
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
|
||||||
```
|
//分页插件
|
||||||
|
mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
|
||||||
|
//连表插件
|
||||||
|
mybatisPlusInterceptor.addInnerInterceptor(new MyJoinInterceptor());
|
||||||
|
//可以添加多租户或其他插件
|
||||||
|
return mybatisPlusInterceptor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### 使用
|
### 使用
|
||||||
|
|
||||||
@ -40,12 +47,12 @@
|
|||||||
* service继承MyBaseService (可选)
|
* service继承MyBaseService (可选)
|
||||||
* serviceImpl继承MyBaseServiceImpl (可选)
|
* serviceImpl继承MyBaseServiceImpl (可选)
|
||||||
|
|
||||||
1. MyBaseMapper继承BaseMapper,在原有的方法基础上又添加了以下方法:
|
1. MyBaseMapper继承BaseMapper,在原有的方法基础上又添加了以下方法:
|
||||||
* selectJoinOne 连表查询一条记录对象
|
* selectJoinOne 连表查询一条记录对象
|
||||||
* selectJoinList 连表查询返回命中记录对象集合
|
* selectJoinList 连表查询返回命中记录对象集合
|
||||||
* selectJoinPage 连表分页查询对象集合
|
* selectJoinPage 连表分页查询对象集合
|
||||||
* selectJoinMap 连表查询一条记录返回Map
|
* selectJoinMap 连表查询一条记录返回Map
|
||||||
* selectJoinMaps 连表查询返回命中记录Map集合
|
* selectJoinMaps 连表查询返回命中记录Map集合
|
||||||
* selectJoinMapsPage 连表分页查询返回Map集合
|
* selectJoinMapsPage 连表分页查询返回Map集合
|
||||||
|
|
||||||
2. MyBaseService 继承了IService,同样添加以上方法
|
2. MyBaseService 继承了IService,同样添加以上方法
|
||||||
@ -189,34 +196,33 @@ class test {
|
|||||||
对应sql
|
对应sql
|
||||||
|
|
||||||
```mysql
|
```mysql
|
||||||
SELECT
|
SELECT t.id,
|
||||||
t.id,
|
t.name,
|
||||||
t.name,
|
t.sex,
|
||||||
t.sex,
|
t.head_img,
|
||||||
t.head_img,
|
addr.tel,
|
||||||
addr.tel,
|
addr.address,
|
||||||
addr.address,
|
CASE t.sex WHEN '男' THEN '1' ELSE '0' END AS sex,
|
||||||
CASE t.sex WHEN '男' THEN '1' ELSE '0' END AS sex,
|
sum(a.province) as province
|
||||||
sum(a.province) as province
|
FROM user t
|
||||||
FROM
|
LEFT JOIN (select * from user_address) addr on t.id = addr.user_id
|
||||||
user t
|
RIGHT JOIN area a on addr.area_id = a.id
|
||||||
LEFT JOIN (select * from user_address) addr on t.id = addr.user_id
|
WHERE t.id = ?
|
||||||
RIGHT JOIN area a on addr.area_id = a.id
|
AND addr.tel LIKE ?
|
||||||
WHERE
|
AND a.province <= ?)
|
||||||
t.id = ?
|
ORDER BY
|
||||||
AND addr.tel LIKE ?
|
addr.id
|
||||||
AND a.province <= ?)
|
DESC
|
||||||
ORDER BY
|
|
||||||
addr.id DESC
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## MyJoinLambdaQueryWrapper用法
|
## MyJoinLambdaQueryWrapper用法
|
||||||
|
|
||||||
MyJoinLambdaQueryWrapper与MyLambdaQueryWrapper不同,是一套新的支持多表的wrapper
|
MyJoinLambdaQueryWrapper与上面连个Wrapper不同,是一套新的支持多表的wrapper
|
||||||
|
MyQueryWrapper是基于QueryWrapper扩展的
|
||||||
MyLambdaQueryWrapper是基于LambdaQueryWrapper扩展的
|
MyLambdaQueryWrapper是基于LambdaQueryWrapper扩展的
|
||||||
而LambdaQueryWrapper由于泛型约束,不支持扩展成多表的lambdaWrapper
|
而LambdaQueryWrapper由于泛型约束,不支持扩展成多表的lambdaWrapper
|
||||||
|
|
||||||
#### MyJoinLambdaQueryWrapper更符合面向对象(OOP),没有魔术值,全部基于lambda,但灵活性不如上面的
|
#### MyJoinLambdaQueryWrapper示例
|
||||||
|
|
||||||
#### 简单的3表查询
|
#### 简单的3表查询
|
||||||
|
|
||||||
|
2
pom.xml
2
pom.xml
@ -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.0.2</version>
|
<version>1.0.5</version>
|
||||||
<name>mp</name>
|
<name>mp</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>
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package com.github.yulichang;
|
package com.github.yulichang;
|
||||||
|
|
||||||
import com.github.yulichang.injector.MySqlInjector;
|
import com.github.yulichang.injector.MySqlInjector;
|
||||||
import com.github.yulichang.interceptor.MyResultInterceptor;
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
@ -18,9 +17,9 @@ public class MybatisPlusConfiguration {
|
|||||||
return new MySqlInjector();
|
return new MySqlInjector();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
// @Bean
|
||||||
@ConditionalOnMissingBean(MyResultInterceptor.class)
|
// @ConditionalOnMissingBean(MyResultInterceptor.class)
|
||||||
public MyResultInterceptor myResultInterceptor() {
|
// public MyResultInterceptor myResultInterceptor() {
|
||||||
return new MyResultInterceptor();
|
// return new MyResultInterceptor();
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,55 @@
|
|||||||
|
package com.github.yulichang.interceptor;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
|
||||||
|
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.session.ResultHandler;
|
||||||
|
import org.apache.ibatis.session.RowBounds;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 结果封装拦截器
|
||||||
|
*
|
||||||
|
* @author yulichang
|
||||||
|
*/
|
||||||
|
public class MyJoinInterceptor implements InnerInterceptor {
|
||||||
|
|
||||||
|
private static Field type = null;
|
||||||
|
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
type = ResultMap.class.getDeclaredField("type");
|
||||||
|
type.setAccessible(true);
|
||||||
|
} catch (NoSuchFieldException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@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<String, ?> map = (Map<String, ?>) parameter;
|
||||||
|
if (CollectionUtils.isNotEmpty(map)) {
|
||||||
|
try {
|
||||||
|
Class<?> clazz = (Class<?>) map.get(Constant.CLAZZ);
|
||||||
|
List<ResultMap> list = ms.getResultMaps();
|
||||||
|
if (CollectionUtils.isNotEmpty(list)) {
|
||||||
|
ResultMap resultMap = list.get(0);
|
||||||
|
type.set(resultMap, clazz);
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
//通常是MapperMethod内部类HashMap的子类ParamMap重写了了get方法抛出的BindingException
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,73 +0,0 @@
|
|||||||
package com.github.yulichang.interceptor;
|
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.MybatisParameterHandler;
|
|
||||||
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
|
||||||
import com.github.yulichang.toolkit.Constant;
|
|
||||||
import org.apache.ibatis.executor.statement.StatementHandler;
|
|
||||||
import org.apache.ibatis.mapping.MappedStatement;
|
|
||||||
import org.apache.ibatis.mapping.ResultMap;
|
|
||||||
import org.apache.ibatis.plugin.*;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 结果封装
|
|
||||||
*
|
|
||||||
* @author yulichang
|
|
||||||
*/
|
|
||||||
@Intercepts({
|
|
||||||
@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class}),
|
|
||||||
})
|
|
||||||
//@SuppressWarnings("all")
|
|
||||||
public class MyResultInterceptor implements Interceptor {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 缓存初始化反射字段
|
|
||||||
* todo
|
|
||||||
* 应该可以想mybatis-plus那样用自定义的MybatisParameterHandler直接获取mappedStatement和resultMap,而不是反射获取
|
|
||||||
*/
|
|
||||||
private static Field mappedStatement = null;
|
|
||||||
private static Field type = null;
|
|
||||||
|
|
||||||
static {
|
|
||||||
try {
|
|
||||||
mappedStatement = MybatisParameterHandler.class.getDeclaredField("mappedStatement");
|
|
||||||
mappedStatement.setAccessible(true);
|
|
||||||
type = ResultMap.class.getDeclaredField("type");
|
|
||||||
type.setAccessible(true);
|
|
||||||
} catch (NoSuchFieldException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object intercept(Invocation invocation) throws Throwable {
|
|
||||||
if (Objects.nonNull(invocation.getTarget()) && invocation.getTarget() instanceof MybatisParameterHandler) {
|
|
||||||
MybatisParameterHandler mybatisParameterHandler = (MybatisParameterHandler) invocation.getTarget();
|
|
||||||
Map<String, ?> map = (Map<String, ?>) mybatisParameterHandler.getParameterObject();
|
|
||||||
if (CollectionUtils.isNotEmpty(map)) {
|
|
||||||
try {
|
|
||||||
Class<?> resClazz = (Class<?>) map.get(Constant.CLAZZ);
|
|
||||||
MappedStatement statement = (MappedStatement) mappedStatement.get(mybatisParameterHandler);
|
|
||||||
List<ResultMap> list = statement.getResultMaps();
|
|
||||||
if (CollectionUtils.isNotEmpty(list)) {
|
|
||||||
ResultMap resultMap = list.get(0);
|
|
||||||
type.set(resultMap, resClazz);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
return invocation.proceed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return invocation.proceed();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object plugin(Object target) {
|
|
||||||
return Plugin.wrap(target, this);
|
|
||||||
}
|
|
||||||
}
|
|
@ -153,7 +153,9 @@ public class MyLambdaQueryWrapper<T> extends MyAbstractLambdaWrapper<T, MyLambda
|
|||||||
public final MyLambdaQueryWrapper<T> selectAll(Class<T> clazz) {
|
public final MyLambdaQueryWrapper<T> selectAll(Class<T> clazz) {
|
||||||
TableInfo info = TableInfoHelper.getTableInfo(clazz);
|
TableInfo info = TableInfoHelper.getTableInfo(clazz);
|
||||||
List<String> list = new ArrayList<>();
|
List<String> list = new ArrayList<>();
|
||||||
list.add(Constant.TABLE_ALIAS + StringPool.DOT + info.getKeyColumn());
|
if (info.havePK()) {
|
||||||
|
list.add(Constant.TABLE_ALIAS + StringPool.DOT + info.getKeyColumn());
|
||||||
|
}
|
||||||
list.addAll(info.getFieldList().stream().map(i -> Constant.TABLE_ALIAS + StringPool.DOT + i.getColumn()).collect(Collectors.toList()));
|
list.addAll(info.getFieldList().stream().map(i -> Constant.TABLE_ALIAS + StringPool.DOT + i.getColumn()).collect(Collectors.toList()));
|
||||||
String join = String.join(StringPool.COMMA, list);
|
String join = String.join(StringPool.COMMA, list);
|
||||||
if (StringUtils.isBlank(sqlSelect.getStringValue())) {
|
if (StringUtils.isBlank(sqlSelect.getStringValue())) {
|
||||||
|
@ -97,7 +97,9 @@ public class MyQueryWrapper<T> extends AbstractWrapper<T, String, MyQueryWrapper
|
|||||||
public final MyQueryWrapper<T> selectAll(Class<T> clazz) {
|
public final MyQueryWrapper<T> selectAll(Class<T> clazz) {
|
||||||
TableInfo info = TableInfoHelper.getTableInfo(clazz);
|
TableInfo info = TableInfoHelper.getTableInfo(clazz);
|
||||||
List<String> list = new ArrayList<>();
|
List<String> list = new ArrayList<>();
|
||||||
list.add(Constant.TABLE_ALIAS + StringPool.DOT + info.getKeyColumn());
|
if (info.havePK()) {
|
||||||
|
list.add(Constant.TABLE_ALIAS + StringPool.DOT + info.getKeyColumn());
|
||||||
|
}
|
||||||
list.addAll(info.getFieldList().stream().map(i -> Constant.TABLE_ALIAS + StringPool.DOT + i.getColumn()).collect(Collectors.toList()));
|
list.addAll(info.getFieldList().stream().map(i -> Constant.TABLE_ALIAS + StringPool.DOT + i.getColumn()).collect(Collectors.toList()));
|
||||||
String join = String.join(StringPool.COMMA, list);
|
String join = String.join(StringPool.COMMA, list);
|
||||||
if (StringUtils.isBlank(sqlSelect.getStringValue())) {
|
if (StringUtils.isBlank(sqlSelect.getStringValue())) {
|
||||||
|
@ -1,29 +1,51 @@
|
|||||||
package com.github.yulichang.toolkit;
|
package com.github.yulichang.toolkit;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.LambdaUtils;
|
import com.baomidou.mybatisplus.core.toolkit.LambdaUtils;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
|
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.support.SerializedLambda;
|
||||||
import org.apache.ibatis.reflection.property.PropertyNamer;
|
import org.apache.ibatis.reflection.property.PropertyNamer;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author yulichang
|
* @author yulichang
|
||||||
* @see LambdaUtils
|
* @see LambdaUtils
|
||||||
* @see PropertyNamer
|
* @see PropertyNamer
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("all")
|
|
||||||
public final class MyLambdaUtils {
|
public final class MyLambdaUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取lambda属性名 UserDO::getId -> id
|
||||||
|
*/
|
||||||
public static <T> String getName(SFunction<T, ?> fn) {
|
public static <T> String getName(SFunction<T, ?> fn) {
|
||||||
return PropertyNamer.methodToProperty(LambdaUtils.resolve(fn).getImplMethodName());
|
return PropertyNamer.methodToProperty(LambdaUtils.resolve(fn).getImplMethodName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取列明
|
||||||
|
* 优先获取tableField中的值
|
||||||
|
*/
|
||||||
public static <T> String getColumn(SFunction<T, ?> fn) {
|
public static <T> String getColumn(SFunction<T, ?> fn) {
|
||||||
return StringUtils.camelToUnderline(getName(fn));
|
|
||||||
|
SerializedLambda lambda = LambdaUtils.resolve(fn);
|
||||||
|
String fieldName = PropertyNamer.methodToProperty(lambda.getImplMethodName());
|
||||||
|
try {
|
||||||
|
Field field = lambda.getImplClass().getDeclaredField(fieldName);
|
||||||
|
TableField annotation = field.getAnnotation(TableField.class);
|
||||||
|
if (Objects.nonNull(annotation)) {
|
||||||
|
return annotation.value();
|
||||||
|
}
|
||||||
|
} catch (NoSuchFieldException ignored) {
|
||||||
|
}
|
||||||
|
return StringUtils.camelToUnderline(fieldName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public static <T> Class<T> getEntityClass(SFunction<T, ?> fn) {
|
public static <T> Class<T> getEntityClass(SFunction<T, ?> fn) {
|
||||||
return (Class<T>) LambdaUtils.resolve(fn).getInstantiatedType();
|
return (Class<T>) LambdaUtils.resolve(fn).getInstantiatedType();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,10 @@
|
|||||||
package com.github.yulichang.wrapper;
|
package com.github.yulichang.wrapper;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.metadata.TableInfo;
|
|
||||||
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
|
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Assert;
|
|
||||||
import com.baomidou.mybatisplus.core.toolkit.LambdaUtils;
|
|
||||||
import com.baomidou.mybatisplus.core.toolkit.StringPool;
|
import com.baomidou.mybatisplus.core.toolkit.StringPool;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.support.ColumnCache;
|
import com.baomidou.mybatisplus.core.toolkit.support.ColumnCache;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
|
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.support.SerializedLambda;
|
import com.github.yulichang.toolkit.Constant;
|
||||||
import com.github.yulichang.toolkit.MyLambdaUtils;
|
import com.github.yulichang.toolkit.MyLambdaUtils;
|
||||||
import org.apache.ibatis.reflection.property.PropertyNamer;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -29,9 +24,9 @@ public abstract class MyAbstractLambdaWrapper<T, Children extends MyAbstractLamb
|
|||||||
private boolean initColumnMap = false;
|
private boolean initColumnMap = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 参与连接的表<class,别名>
|
* 关联的表
|
||||||
*/
|
*/
|
||||||
protected Map<Class<?>, SubClass<?, ?>> subTable = new HashMap<>();
|
protected final Map<Class<?>, Integer> subTable = new HashMap<>();
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
protected <X> String columnsToString(SFunction<X, ?>... columns) {
|
protected <X> String columnsToString(SFunction<X, ?>... columns) {
|
||||||
@ -54,89 +49,15 @@ public abstract class MyAbstractLambdaWrapper<T, Children extends MyAbstractLamb
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected String columnToString(SFunction<?, ?> column, boolean onlyColumn) {
|
protected String columnToString(SFunction<?, ?> column, boolean onlyColumn) {
|
||||||
TableInfo info = TableInfoHelper.getTableInfo(MyLambdaUtils.getEntityClass(column));
|
return Constant.TABLE_ALIAS + getDefault(subTable.get(MyLambdaUtils.getEntityClass(column))) + StringPool.DOT +
|
||||||
Assert.notNull(info, "can not find table for lambda");
|
MyLambdaUtils.getColumn(column);
|
||||||
return info.getTableName() + StringPool.DOT + getColumn(LambdaUtils.resolve(column), onlyColumn);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected String getDefault(Integer i) {
|
||||||
/**
|
if (Objects.nonNull(i)) {
|
||||||
* 获取 SerializedLambda 对应的列信息,从 lambda 表达式中推测实体类
|
return i.toString();
|
||||||
* <p>
|
}
|
||||||
* 如果获取不到列信息,那么本次条件组装将会失败
|
return StringPool.SPACE;
|
||||||
*
|
|
||||||
* @param lambda lambda 表达式
|
|
||||||
* @param onlyColumn 如果是,结果: "name", 如果否: "name" as "name"
|
|
||||||
* @return 列
|
|
||||||
* @throws com.baomidou.mybatisplus.core.exceptions.MybatisPlusException 获取不到列信息时抛出异常
|
|
||||||
* @see SerializedLambda#getImplClass()
|
|
||||||
* @see SerializedLambda#getImplMethodName()
|
|
||||||
*/
|
|
||||||
private String getColumn(SerializedLambda lambda, boolean onlyColumn) {
|
|
||||||
Class<?> aClass = lambda.getInstantiatedType();
|
|
||||||
tryInitCache(aClass);
|
|
||||||
String fieldName = PropertyNamer.methodToProperty(lambda.getImplMethodName());
|
|
||||||
ColumnCache columnCache = getColumnCache(fieldName, aClass);
|
|
||||||
return onlyColumn ? columnCache.getColumn() : columnCache.getColumnSelect();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tryInitCache(Class<?> lambdaClass) {
|
|
||||||
if (!initColumnMap) {
|
|
||||||
final Class<T> entityClass = getEntityClass();
|
|
||||||
if (entityClass != null) {
|
|
||||||
lambdaClass = entityClass;
|
|
||||||
}
|
|
||||||
columnMap = LambdaUtils.getColumnMap(lambdaClass);
|
|
||||||
initColumnMap = true;
|
|
||||||
}
|
|
||||||
Assert.notNull(columnMap, "can not find lambda cache for this entity [%s]", lambdaClass.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
private ColumnCache getColumnCache(String fieldName, Class<?> lambdaClass) {
|
|
||||||
ColumnCache columnCache = columnMap.get(LambdaUtils.formatKey(fieldName));
|
|
||||||
if (Objects.isNull(columnCache)) {
|
|
||||||
columnCache = new ColumnCache(fieldName, null);
|
|
||||||
}
|
|
||||||
return columnCache;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class SubClass<L, R> {
|
|
||||||
|
|
||||||
private String tableAlias;
|
|
||||||
|
|
||||||
private SFunction<L, ?> left;
|
|
||||||
|
|
||||||
private SFunction<R, ?> right;
|
|
||||||
|
|
||||||
|
|
||||||
public SubClass(String tableAlias, SFunction<L, ?> left, SFunction<R, ?> right) {
|
|
||||||
this.tableAlias = tableAlias;
|
|
||||||
this.left = left;
|
|
||||||
this.right = right;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTableAlias() {
|
|
||||||
return tableAlias;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTableAlias(String tableAlias) {
|
|
||||||
this.tableAlias = tableAlias;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SFunction<L, ?> getLeft() {
|
|
||||||
return left;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLeft(SFunction<L, ?> left) {
|
|
||||||
this.left = left;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SFunction<R, ?> getRight() {
|
|
||||||
return right;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRight(SFunction<R, ?> right) {
|
|
||||||
this.right = right;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -15,9 +15,7 @@ import com.github.yulichang.toolkit.MyLambdaUtils;
|
|||||||
import com.github.yulichang.wrapper.interfaces.MyLambdaJoin;
|
import com.github.yulichang.wrapper.interfaces.MyLambdaJoin;
|
||||||
import com.github.yulichang.wrapper.interfaces.MySFunctionQuery;
|
import com.github.yulichang.wrapper.interfaces.MySFunctionQuery;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@ -42,13 +40,17 @@ public class MyJoinLambdaQueryWrapper<T> extends MyAbstractLambdaWrapper<T, MyJo
|
|||||||
/**
|
/**
|
||||||
* 主表别名
|
* 主表别名
|
||||||
*/
|
*/
|
||||||
private final SharedString alias = new SharedString();
|
private final SharedString alias = new SharedString(Constant.TABLE_ALIAS);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询的字段
|
* 查询的字段
|
||||||
*/
|
*/
|
||||||
private final List<SelectColumn> selectColumns = new ArrayList<>();
|
private final List<SelectColumn> selectColumns = new ArrayList<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 表序号
|
||||||
|
*/
|
||||||
|
private int tableIndex = 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 不建议直接 new 该实例,使用 Wrappers.lambdaQuery(entity)
|
* 不建议直接 new 该实例,使用 Wrappers.lambdaQuery(entity)
|
||||||
@ -99,9 +101,7 @@ public class MyJoinLambdaQueryWrapper<T> extends MyAbstractLambdaWrapper<T, MyJo
|
|||||||
public final <S> MyJoinLambdaQueryWrapper<T> select(SFunction<S, ?>... columns) {
|
public final <S> MyJoinLambdaQueryWrapper<T> select(SFunction<S, ?>... columns) {
|
||||||
if (ArrayUtils.isNotEmpty(columns)) {
|
if (ArrayUtils.isNotEmpty(columns)) {
|
||||||
for (SFunction<S, ?> s : columns) {
|
for (SFunction<S, ?> s : columns) {
|
||||||
Class<S> clazz = MyLambdaUtils.getEntityClass(s);
|
selectColumns.add(new SelectColumn(MyLambdaUtils.getEntityClass(s), MyLambdaUtils.getColumn(s), null));
|
||||||
TableInfo info = TableInfoHelper.getTableInfo(clazz);
|
|
||||||
selectColumns.add(new SelectColumn(clazz, info.getTableName(), MyLambdaUtils.getColumn(s), null));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return typedThis;
|
return typedThis;
|
||||||
@ -112,25 +112,24 @@ public class MyJoinLambdaQueryWrapper<T> extends MyAbstractLambdaWrapper<T, MyJo
|
|||||||
TableInfo info = TableInfoHelper.getTableInfo(entityClass);
|
TableInfo info = TableInfoHelper.getTableInfo(entityClass);
|
||||||
Assert.notNull(info, "table can not be find");
|
Assert.notNull(info, "table can not be find");
|
||||||
info.getFieldList().stream().filter(predicate).collect(Collectors.toList()).forEach(
|
info.getFieldList().stream().filter(predicate).collect(Collectors.toList()).forEach(
|
||||||
i -> selectColumns.add(new SelectColumn(entityClass, info.getTableName(), i.getColumn(), null)));
|
i -> selectColumns.add(new SelectColumn(entityClass, i.getColumn(), null)));
|
||||||
return typedThis;
|
return typedThis;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public final <S, X> MyJoinLambdaQueryWrapper<T> selectAs(SFunction<S, ?> columns, SFunction<X, ?> alias) {
|
public final <S, X> MyJoinLambdaQueryWrapper<T> selectAs(SFunction<S, ?> columns, SFunction<X, ?> alias) {
|
||||||
Class<S> clazz = MyLambdaUtils.getEntityClass(columns);
|
selectColumns.add(new SelectColumn(MyLambdaUtils.getEntityClass(columns), MyLambdaUtils.getColumn(columns), MyLambdaUtils.getName(alias)));
|
||||||
TableInfo info = TableInfoHelper.getTableInfo(clazz);
|
|
||||||
Assert.notNull(info, "table can not be find for lambda");
|
|
||||||
selectColumns.add(new SelectColumn(clazz, info.getTableName(), MyLambdaUtils.getColumn(columns), MyLambdaUtils.getName(alias)));
|
|
||||||
return typedThis;
|
return typedThis;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final MyJoinLambdaQueryWrapper<T> selectAll(Class<?> clazz) {
|
public final MyJoinLambdaQueryWrapper<T> selectAll(Class<?> clazz) {
|
||||||
TableInfo info = TableInfoHelper.getTableInfo(clazz);
|
TableInfo info = TableInfoHelper.getTableInfo(clazz);
|
||||||
Assert.notNull(info, "table can not be find -> %s", clazz);
|
Assert.notNull(info, "table can not be find -> %s", clazz);
|
||||||
selectColumns.add(new SelectColumn(clazz, info.getTableName(), info.getKeyColumn(), null));
|
if (info.havePK()) {
|
||||||
|
selectColumns.add(new SelectColumn(clazz, info.getKeyColumn(), null));
|
||||||
|
}
|
||||||
info.getFieldList().forEach(c ->
|
info.getFieldList().forEach(c ->
|
||||||
selectColumns.add(new SelectColumn(clazz, info.getTableName(), c.getColumn(), null)));
|
selectColumns.add(new SelectColumn(clazz, c.getColumn(), null)));
|
||||||
return typedThis;
|
return typedThis;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,7 +137,7 @@ public class MyJoinLambdaQueryWrapper<T> extends MyAbstractLambdaWrapper<T, MyJo
|
|||||||
public String getSqlSelect() {
|
public String getSqlSelect() {
|
||||||
if (StringUtils.isBlank(sqlSelect.getStringValue())) {
|
if (StringUtils.isBlank(sqlSelect.getStringValue())) {
|
||||||
String s = selectColumns.stream().map(i ->
|
String s = selectColumns.stream().map(i ->
|
||||||
i.getTableName() + StringPool.DOT + i.getColumnName() +
|
Constant.TABLE_ALIAS + getDefault(subTable.get(i.getClazz())) + StringPool.DOT + i.getColumnName() +
|
||||||
(StringUtils.isBlank(i.getAlias()) ? StringPool.EMPTY : (Constant.AS + i.getAlias())))
|
(StringUtils.isBlank(i.getAlias()) ? StringPool.EMPTY : (Constant.AS + i.getAlias())))
|
||||||
.collect(Collectors.joining(StringPool.COMMA));
|
.collect(Collectors.joining(StringPool.COMMA));
|
||||||
sqlSelect.setStringValue(s);
|
sqlSelect.setStringValue(s);
|
||||||
@ -174,22 +173,37 @@ public class MyJoinLambdaQueryWrapper<T> extends MyAbstractLambdaWrapper<T, MyJo
|
|||||||
@Override
|
@Override
|
||||||
public <L, X> MyJoinLambdaQueryWrapper<T> join(String keyWord, boolean condition, Class<L> clazz, SFunction<L, ?> left, SFunction<X, ?> right) {
|
public <L, X> MyJoinLambdaQueryWrapper<T> join(String keyWord, boolean condition, Class<L> clazz, SFunction<L, ?> left, SFunction<X, ?> right) {
|
||||||
if (condition) {
|
if (condition) {
|
||||||
|
subTable.put(clazz, tableIndex);
|
||||||
TableInfo leftInfo = TableInfoHelper.getTableInfo(clazz);
|
TableInfo leftInfo = TableInfoHelper.getTableInfo(clazz);
|
||||||
TableInfo rightInfo = TableInfoHelper.getTableInfo(MyLambdaUtils.getEntityClass(right));
|
|
||||||
|
|
||||||
String s = keyWord + leftInfo.getTableName() + Constant.ON + leftInfo.getTableName() + StringPool.DOT
|
StringBuilder sb = new StringBuilder(keyWord)
|
||||||
+ MyLambdaUtils.getColumn(left) + Constant.EQUALS + rightInfo.getTableName() + StringPool.DOT
|
.append(leftInfo.getTableName())
|
||||||
+ MyLambdaUtils.getColumn(right);
|
.append(StringPool.SPACE)
|
||||||
|
.append(Constant.TABLE_ALIAS)
|
||||||
|
.append(tableIndex)
|
||||||
|
.append(StringPool.SPACE)
|
||||||
|
.append(Constant.ON)
|
||||||
|
.append(Constant.TABLE_ALIAS)
|
||||||
|
.append(tableIndex)
|
||||||
|
.append(StringPool.DOT)
|
||||||
|
.append(MyLambdaUtils.getColumn(left))
|
||||||
|
.append(Constant.EQUALS)
|
||||||
|
.append(Constant.TABLE_ALIAS)
|
||||||
|
.append(getDefault(subTable.get(MyLambdaUtils.getEntityClass(right))))
|
||||||
|
.append(StringPool.DOT)
|
||||||
|
.append(MyLambdaUtils.getColumn(right));
|
||||||
|
|
||||||
|
tableIndex++;
|
||||||
if (StringUtils.isBlank(from.getStringValue())) {
|
if (StringUtils.isBlank(from.getStringValue())) {
|
||||||
from.setStringValue(s);
|
from.setStringValue(sb.toString());
|
||||||
} else {
|
} else {
|
||||||
from.setStringValue(from.getStringValue() + s);
|
from.setStringValue(from.getStringValue() + sb.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return typedThis;
|
return typedThis;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* select字段
|
* select字段
|
||||||
*/
|
*/
|
||||||
@ -197,15 +211,12 @@ public class MyJoinLambdaQueryWrapper<T> extends MyAbstractLambdaWrapper<T, MyJo
|
|||||||
|
|
||||||
private Class<?> clazz;
|
private Class<?> clazz;
|
||||||
|
|
||||||
private String tableName;
|
|
||||||
|
|
||||||
private String columnName;
|
private String columnName;
|
||||||
|
|
||||||
private String alias;
|
private String alias;
|
||||||
|
|
||||||
public SelectColumn(Class<?> clazz, String tableName, String columnName, String alias) {
|
public SelectColumn(Class<?> clazz, String columnName, String alias) {
|
||||||
this.clazz = clazz;
|
this.clazz = clazz;
|
||||||
this.tableName = tableName;
|
|
||||||
this.columnName = columnName;
|
this.columnName = columnName;
|
||||||
this.alias = alias;
|
this.alias = alias;
|
||||||
}
|
}
|
||||||
@ -218,14 +229,6 @@ public class MyJoinLambdaQueryWrapper<T> extends MyAbstractLambdaWrapper<T, MyJo
|
|||||||
this.clazz = clazz;
|
this.clazz = clazz;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTableName() {
|
|
||||||
return tableName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTableName(String tableName) {
|
|
||||||
this.tableName = tableName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getColumnName() {
|
public String getColumnName() {
|
||||||
return columnName;
|
return columnName;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user