mirror of
https://gitee.com/best_handsome/mybatis-plus-join
synced 2025-07-11 00:02:22 +08:00
合并&修改
This commit is contained in:
parent
2674d6e7b9
commit
7b282fd8da
33
README.md
33
README.md
@ -279,39 +279,6 @@ ORDER BY
|
|||||||
addr.id DESC
|
addr.id DESC
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 指定返回列实体类,按需要返回列
|
|
||||||
|
|
||||||
```java
|
|
||||||
|
|
||||||
class test {
|
|
||||||
@Resource
|
|
||||||
private UserMapper userMapper;
|
|
||||||
|
|
||||||
void testJoin() {
|
|
||||||
IPage<UserDTO> page = userMapper.selectJoinPage(new Page<>(1, 10), UserVo.class,
|
|
||||||
new MPJQueryWrapper<UserDO>()
|
|
||||||
.selectAsClass(UserDO.class, UserVo.class);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
说明:
|
|
||||||
比如我们需要查询用户表有10个字段,然而我们只需要3个就够了,用mybatis-plus提供的select
|
|
||||||
需要一个属性一个属性填入很不优雅,现在我们可以用selectAsClass(UserDO.class, UserVo.class)
|
|
||||||
;即可按所需的UserVo返回,前提是UserVo.class中的属性必须是UserDO.class中存在的
|
|
||||||
|
|
||||||
对应sql
|
|
||||||
|
|
||||||
```
|
|
||||||
SELECT
|
|
||||||
t.id,
|
|
||||||
t.name,
|
|
||||||
t.sex
|
|
||||||
FROM
|
|
||||||
user t
|
|
||||||
LIMIT ?,?
|
|
||||||
```
|
|
||||||
|
|
||||||
# [wiki](https://gitee.com/best_handsome/mybatis-plus-join/wikis)
|
# [wiki](https://gitee.com/best_handsome/mybatis-plus-join/wikis)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,70 +0,0 @@
|
|||||||
package com.baomidou.mybatisplus.core.metadata;
|
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Assert;
|
|
||||||
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
|
||||||
import com.baomidou.mybatisplus.core.toolkit.ReflectionKit;
|
|
||||||
import org.apache.ibatis.logging.Log;
|
|
||||||
import org.apache.ibatis.logging.LogFactory;
|
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Author Gy.13
|
|
||||||
* @Description: 用于构建查询返回列,由于mybatis-plus条件构造的select无法实现通过传入VO实体类查询想要的列,需要一个一个指定
|
|
||||||
* @Date: 2022/8/5 09:39
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public class MPJResultHelper {
|
|
||||||
|
|
||||||
|
|
||||||
private static final Log logger = LogFactory.getLog(MPJResultHelper.class);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 储存反射VO信息
|
|
||||||
*/
|
|
||||||
private static final Map<Class<?>, Map<String, Set<String>>> VO_INFO_CACHE = new ConcurrentHashMap<>();
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param sourceEntityClass
|
|
||||||
* @param resultEntityClass
|
|
||||||
* @Author Gy.13
|
|
||||||
* @Description: 获取VO实体映射表信息
|
|
||||||
* @return: java.util.Set<java.lang.String>
|
|
||||||
* @Date: 2022/8/5 09:59
|
|
||||||
*/
|
|
||||||
public static Map<String, Set<String>> getVoTableInfo(Class<?> resultEntityClass, Class<?>... sourceEntityClass) {
|
|
||||||
if (resultEntityClass == null || ReflectionKit.isPrimitiveOrWrapper(resultEntityClass) || resultEntityClass == String.class || resultEntityClass.isInterface()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
Map<String, Set<String>> maps = VO_INFO_CACHE.get(resultEntityClass);
|
|
||||||
if (maps == null) {
|
|
||||||
maps = CollectionUtils.newHashMap();
|
|
||||||
List<Field> allFields = TableInfoHelper.getAllFields(resultEntityClass);
|
|
||||||
Assert.notNull(allFields, "table can not be find");
|
|
||||||
Set<String> fieldNames = allFields.stream().collect(Collectors.groupingBy(Field::getName)).keySet();
|
|
||||||
for (Class<?> entityClass : sourceEntityClass) {
|
|
||||||
Set<String> set = new HashSet<>();
|
|
||||||
MPJTableInfo info = MPJTableInfoHelper.getTableInfo(entityClass);
|
|
||||||
Assert.notNull(info, "table can not be find");
|
|
||||||
info.getTableInfo().getFieldList().forEach(
|
|
||||||
i -> {
|
|
||||||
if (fieldNames.contains(i.getProperty())) {
|
|
||||||
set.add(i.getColumn());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
maps.put(entityClass.getName(), set);
|
|
||||||
}
|
|
||||||
/* 添加缓存 */
|
|
||||||
VO_INFO_CACHE.put(resultEntityClass, maps);
|
|
||||||
}
|
|
||||||
return VO_INFO_CACHE.get(resultEntityClass);
|
|
||||||
}
|
|
||||||
}
|
|
@ -2,7 +2,6 @@ package com.github.yulichang.wrapper;
|
|||||||
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.SharedString;
|
import com.baomidou.mybatisplus.core.conditions.SharedString;
|
||||||
import com.baomidou.mybatisplus.core.conditions.segments.MergeSegments;
|
import com.baomidou.mybatisplus.core.conditions.segments.MergeSegments;
|
||||||
import com.baomidou.mybatisplus.core.metadata.MPJResultHelper;
|
|
||||||
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
|
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
|
||||||
import com.baomidou.mybatisplus.core.metadata.TableInfo;
|
import com.baomidou.mybatisplus.core.metadata.TableInfo;
|
||||||
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
|
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
|
||||||
@ -11,6 +10,7 @@ import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
|
|||||||
import com.github.yulichang.toolkit.Constant;
|
import com.github.yulichang.toolkit.Constant;
|
||||||
import com.github.yulichang.toolkit.LambdaUtils;
|
import com.github.yulichang.toolkit.LambdaUtils;
|
||||||
import com.github.yulichang.toolkit.MPJWrappers;
|
import com.github.yulichang.toolkit.MPJWrappers;
|
||||||
|
import com.github.yulichang.toolkit.ReflectionKit;
|
||||||
import com.github.yulichang.wrapper.enums.BaseFuncEnum;
|
import com.github.yulichang.wrapper.enums.BaseFuncEnum;
|
||||||
import com.github.yulichang.wrapper.interfaces.LambdaJoin;
|
import com.github.yulichang.wrapper.interfaces.LambdaJoin;
|
||||||
import com.github.yulichang.wrapper.interfaces.Query;
|
import com.github.yulichang.wrapper.interfaces.Query;
|
||||||
@ -18,13 +18,15 @@ import com.github.yulichang.wrapper.interfaces.on.OnFunction;
|
|||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
import java.util.*;
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
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;
|
||||||
|
|
||||||
import static com.baomidou.mybatisplus.core.enums.SqlKeyword.GROUP_BY;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 参考 {@link com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper}
|
* 参考 {@link com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper}
|
||||||
* Lambda 语法使用 Wrapper
|
* Lambda 语法使用 Wrapper
|
||||||
@ -141,12 +143,18 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
|
|||||||
return typedThis;
|
return typedThis;
|
||||||
}
|
}
|
||||||
|
|
||||||
public <E> MPJLambdaWrapper<T> selectAsClass(Class<?> resultEntityClass, Class<?>... sourceEntityClass) {
|
@Override
|
||||||
Map<String, Set<String>> voTableInfo = MPJResultHelper.getVoTableInfo(resultEntityClass, sourceEntityClass);
|
public <E> MPJLambdaWrapper<T> selectAsClass(Class<E> source, Class<?> tag) {
|
||||||
Assert.notNull(voTableInfo, "table can not be find");
|
TableInfo tableInfo = TableInfoHelper.getTableInfo(source);
|
||||||
for (Class<?> entityClass : sourceEntityClass) {
|
Assert.notNull(tableInfo, "table can not be find");
|
||||||
Set<String> columns = voTableInfo.get(entityClass.getName());
|
List<Field> tagFields = ReflectionKit.getFieldList(tag);
|
||||||
columns.forEach(i -> selectColumns.add(SelectColumn.of(entityClass, i)));
|
tableInfo.getFieldList().forEach(i -> {
|
||||||
|
if (tagFields.stream().anyMatch(f -> f.getName().equals(i.getProperty()))) {
|
||||||
|
selectColumns.add(SelectColumn.of(source, i.getColumn()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (tableInfo.havePK() && tagFields.stream().anyMatch(i -> i.getName().equals(tableInfo.getKeyProperty()))) {
|
||||||
|
selectColumns.add(SelectColumn.of(source, tableInfo.getKeyProperty()));
|
||||||
}
|
}
|
||||||
return typedThis;
|
return typedThis;
|
||||||
}
|
}
|
||||||
@ -279,15 +287,6 @@ public class MPJLambdaWrapper<T> extends MPJAbstractLambdaWrapper<T, MPJLambdaWr
|
|||||||
return typedThis;
|
return typedThis;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public <R> MPJLambdaWrapper<T> groupBy(String... columns) {
|
|
||||||
return maybeDo(true, () -> {
|
|
||||||
final String finalOne = String.join(StringPool.COMMA, columns);
|
|
||||||
;
|
|
||||||
appendSqlSegments(GROUP_BY, () -> finalOne);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* select字段
|
* select字段
|
||||||
*/
|
*/
|
||||||
|
@ -12,11 +12,9 @@ package com.github.yulichang.wrapper.enums;
|
|||||||
* @author yulichang
|
* @author yulichang
|
||||||
*/
|
*/
|
||||||
public enum DefaultFuncEnum implements BaseFuncEnum {
|
public enum DefaultFuncEnum implements BaseFuncEnum {
|
||||||
DATE_FORMAT_Y_M_D("DATE_FORMAT(%s,'%%Y-%%m-%%d')"),
|
|
||||||
DATE_FORMAT_Y_M("DATE_FORMAT(%s,'%%Y-%%m')"),
|
|
||||||
SUM("SUM(%s)"),
|
SUM("SUM(%s)"),
|
||||||
COUNT("COUNT(%s)"),
|
COUNT("COUNT(%s)"),
|
||||||
COUNT_DISTINCT("COUNT(DISTINCT %s)"),
|
|
||||||
MAX("MAX(%s)"),
|
MAX("MAX(%s)"),
|
||||||
MIN("MIN(%s)"),
|
MIN("MIN(%s)"),
|
||||||
AVG("AVG(%s)"),
|
AVG("AVG(%s)"),
|
||||||
|
@ -187,8 +187,6 @@ public interface Func<Children> extends Serializable {
|
|||||||
*/
|
*/
|
||||||
<R> Children groupBy(boolean condition, List<SFunction<R, ?>> columns);
|
<R> Children groupBy(boolean condition, List<SFunction<R, ?>> columns);
|
||||||
|
|
||||||
<R> Children groupBy(String... columns);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ignore
|
* ignore
|
||||||
*/
|
*/
|
||||||
|
@ -39,6 +39,18 @@ public interface Query<Children> extends Serializable {
|
|||||||
*/
|
*/
|
||||||
<E> Children select(Class<E> entityClass, Predicate<TableFieldInfo> predicate);
|
<E> Children select(Class<E> entityClass, Predicate<TableFieldInfo> predicate);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 说明:
|
||||||
|
* 比如我们需要查询用户表有10个字段,然而我们只需要3个就够了,用mybatis-plus提供的select<p />
|
||||||
|
* 需要一个属性一个属性填入很不优雅,现在我们可以用selectAsClass(UserDO.class, UserVo.class)<p />
|
||||||
|
* 即可按所需的UserVo返回,前提是UserVo.class中的属性必须是UserDO.class中存在的
|
||||||
|
*
|
||||||
|
* @param source 数据源实体类
|
||||||
|
* @param tag 目标类
|
||||||
|
* @return children
|
||||||
|
*/
|
||||||
|
<E> Children selectAsClass(Class<E> source, Class<?> tag);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ignore
|
* ignore
|
||||||
*/
|
*/
|
||||||
@ -53,6 +65,11 @@ public interface Query<Children> extends Serializable {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 聚合函数查询
|
* 聚合函数查询
|
||||||
|
* <p>
|
||||||
|
* wrapper.selectFunc(() -> "COUNT(%s)", "t.id", "total");
|
||||||
|
* <p>
|
||||||
|
* lambda
|
||||||
|
* wrapper.selectFunc(() -> "COUNT(%s)", UserDO::getId, UserDTO::getTotal);
|
||||||
*
|
*
|
||||||
* @param funcEnum 函数枚举 {@link com.github.yulichang.wrapper.enums.DefaultFuncEnum}
|
* @param funcEnum 函数枚举 {@link com.github.yulichang.wrapper.enums.DefaultFuncEnum}
|
||||||
* @param column 函数作用的字段
|
* @param column 函数作用的字段
|
||||||
@ -190,49 +207,6 @@ public interface Query<Children> extends Serializable {
|
|||||||
return selectFunc(condition, DefaultFuncEnum.COUNT, column, alias);
|
return selectFunc(condition, DefaultFuncEnum.COUNT, column, alias);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* COUNT(DISTINCT)
|
|
||||||
*/
|
|
||||||
default <S> Children selectCountDistinct(SFunction<S, ?> column) {
|
|
||||||
return selectFunc(DefaultFuncEnum.COUNT_DISTINCT, column);
|
|
||||||
}
|
|
||||||
|
|
||||||
default <X> Children selectCountDistinct(Object column, SFunction<X, ?> alias) {
|
|
||||||
return selectFunc(DefaultFuncEnum.COUNT_DISTINCT, column, alias);
|
|
||||||
}
|
|
||||||
|
|
||||||
default Children selectCountDistinct(Object column, String alias) {
|
|
||||||
return selectFunc(DefaultFuncEnum.COUNT_DISTINCT, column, alias);
|
|
||||||
}
|
|
||||||
|
|
||||||
default <S, X> Children selectCountDistinct(SFunction<S, ?> column, SFunction<X, ?> alias) {
|
|
||||||
return selectFunc(DefaultFuncEnum.COUNT_DISTINCT, column, alias);
|
|
||||||
}
|
|
||||||
|
|
||||||
default <S, X> Children selectCountDistinct(SFunction<S, ?> column, String alias) {
|
|
||||||
return selectFunc(DefaultFuncEnum.COUNT_DISTINCT, column, alias);
|
|
||||||
}
|
|
||||||
|
|
||||||
default <S> Children selectCountDistinct(boolean condition, SFunction<S, ?> column) {
|
|
||||||
return selectFunc(condition, DefaultFuncEnum.COUNT_DISTINCT, column);
|
|
||||||
}
|
|
||||||
|
|
||||||
default <X> Children selectCountDistinct(boolean condition, Object column, SFunction<X, ?> alias) {
|
|
||||||
return selectFunc(condition, DefaultFuncEnum.COUNT_DISTINCT, column, alias);
|
|
||||||
}
|
|
||||||
|
|
||||||
default Children selectCountDistinct(boolean condition, Object column, String alias) {
|
|
||||||
return selectFunc(condition, DefaultFuncEnum.COUNT_DISTINCT, column, alias);
|
|
||||||
}
|
|
||||||
|
|
||||||
default <S, X> Children selectCountDistinct(boolean condition, SFunction<S, ?> column, SFunction<X, ?> alias) {
|
|
||||||
return selectFunc(condition, DefaultFuncEnum.COUNT_DISTINCT, column, alias);
|
|
||||||
}
|
|
||||||
|
|
||||||
default <S, X> Children selectCountDistinct(boolean condition, SFunction<S, ?> column, String alias) {
|
|
||||||
return selectFunc(condition, DefaultFuncEnum.COUNT_DISTINCT, column, alias);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MAX()
|
* MAX()
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user