映射注解支持 order by

This commit is contained in:
bjdys 2021-08-24 10:35:26 +08:00
parent a4ab8a3b51
commit 214260ff99
9 changed files with 67 additions and 19 deletions

View File

@ -83,7 +83,7 @@ public class UserDO {
```java ```java
/** /**
* 一对一,一对多关系映射查询 * 一对一,一对多关系映射查询
* 映射只对MPJBaseDeepService中的方法有效果 ,一般以Deep结尾比如 getByIdDeep listByIdsDeep 等 * 映射只对以Deep结尾比如 getByIdDeep listByIdsDeep 等
* 如果不需要关系映射就使用mybatis plus原生方法即可比如 getById listByIds 等 * 如果不需要关系映射就使用mybatis plus原生方法即可比如 getById listByIds 等
* *
* @see com.github.yulichang.base.service.MPJDeepService * @see com.github.yulichang.base.service.MPJDeepService
@ -133,18 +133,19 @@ class MappingTest {
Page<UserDO> page = userMapper.selectPageDeep(new Page<>(2, 2), Wrappers.emptyWrapper()); Page<UserDO> page = userMapper.selectPageDeep(new Page<>(2, 2), Wrappers.emptyWrapper());
page.getRecords().forEach(System.out::println); page.getRecords().forEach(System.out::println);
} }
}
``` ```
MPJMapping 说明: MPJMapping 说明:
* MPJMapping tag 关联实体类 * @EntityMapping / @FieldMapping tag 关联实体类
* MPJMapping thisField 当前类关联对应的字段的属性名,可以不填,默认为当前类的主键 * @EntityMapping / @FieldMapping thisField 当前类关联对应的字段的属性名,可以不填,默认为当前类的主键
* MPJMapping joinField 关联类对应的字段的属性名,可以不填,默认为关联类的主键 * @EntityMapping / @FieldMapping joinField 关联类对应的字段的属性名,可以不填,默认为关联类的主键
* MPJMapping isThrowExp 一对一查询时,如果查询到多条记录是否抛出异常,true:抛出异常,false:获取列表第一条数据 * @EntityMapping / @FieldMapping isThrowExp 一对一查询时,如果查询到多条记录是否抛出异常,true:抛出异常,false:获取列表第一条数据
* *
更多功能请看代码注释 [MPJMapping](https://gitee.com/best_handsome/mybatis-plus-join/blob/master/src/main/java/com/github/yulichang/annotation/MPJMapping.java) 更多功能请看代码注释 [EntityMapping](https://gitee.com/best_handsome/mybatis-plus-join/blob/master/src/main/java/com/github/yulichang/annotation/EntityMapping.java)
[FieldMapping](https://gitee.com/best_handsome/mybatis-plus-join/blob/master/src/main/java/com/github/yulichang/annotation/FieldMapping.java)

View File

@ -2,6 +2,7 @@ package com.baomidou.mybatisplus.core.metadata;
import com.baomidou.mybatisplus.core.enums.SqlKeyword; import com.baomidou.mybatisplus.core.enums.SqlKeyword;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils; import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.github.yulichang.annotation.MPJMappingApply; import com.github.yulichang.annotation.MPJMappingApply;
import com.github.yulichang.annotation.MPJMappingCondition; import com.github.yulichang.annotation.MPJMappingCondition;
@ -9,6 +10,7 @@ import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
/** /**
@ -35,8 +37,14 @@ public class MPJMappingWrapper {
private final boolean hasLast; private final boolean hasLast;
private String last; private String last;
private final boolean hasOrderByAsc;
private List<String> orderByAsc;
private final boolean hasOrderByDesc;
private List<String> orderByDesc;
public MPJMappingWrapper(String first, String select, MPJMappingApply[] applys, public MPJMappingWrapper(String first, String select, MPJMappingApply[] applys,
MPJMappingCondition[] conditions, String last) { MPJMappingCondition[] conditions, String last, String orderByAsc, String orderByDesc) {
this.hasFirst = StringUtils.isNotBlank(first); this.hasFirst = StringUtils.isNotBlank(first);
if (this.hasFirst) { if (this.hasFirst) {
this.first = first; this.first = first;
@ -67,6 +75,16 @@ public class MPJMappingWrapper {
if (this.hasLast) { if (this.hasLast) {
this.last = last; this.last = last;
} }
this.hasOrderByAsc = StringUtils.isNotBlank(orderByAsc);
if (this.hasOrderByAsc) {
this.orderByAsc = Arrays.asList(orderByAsc.split(StringPool.COMMA));
}
this.hasOrderByDesc = StringUtils.isNotBlank(orderByDesc);
if (this.hasOrderByDesc) {
this.orderByDesc = Arrays.asList(orderByDesc.split(StringPool.COMMA));
}
} }
@Getter @Getter

View File

@ -135,7 +135,7 @@ public class MPJTableFieldInfo {
StringPool.COMMA)).contains(this.joinColumn.trim())); StringPool.COMMA)).contains(this.joinColumn.trim()));
this.wrapper = new MPJMappingWrapper(mapping.first(), StringUtils.isBlank(mapping.select()) ? null : this.wrapper = new MPJMappingWrapper(mapping.first(), StringUtils.isBlank(mapping.select()) ? null :
(this.isRemoveBindField ? this.joinColumn + StringPool.COMMA + mapping.select() : mapping.select()), (this.isRemoveBindField ? this.joinColumn + StringPool.COMMA + mapping.select() : mapping.select()),
mapping.apply(), mapping.condition(), mapping.last()); mapping.apply(), mapping.condition(), mapping.last(), mapping.orderByAsc(), mapping.orderByDesc());
} }
public MPJTableFieldInfo(Class<?> entityType, FieldMapping mappingField, Field field) { public MPJTableFieldInfo(Class<?> entityType, FieldMapping mappingField, Field field) {
@ -156,7 +156,7 @@ public class MPJTableFieldInfo {
this.isRemoveBindField = !mappingField.select().equals(this.joinColumn.trim()); this.isRemoveBindField = !mappingField.select().equals(this.joinColumn.trim());
this.wrapper = new MPJMappingWrapper(mappingField.first(), this.isRemoveBindField ? this.joinColumn + this.wrapper = new MPJMappingWrapper(mappingField.first(), this.isRemoveBindField ? this.joinColumn +
StringPool.COMMA + mappingField.select() : mappingField.select(), mappingField.apply(), StringPool.COMMA + mappingField.select() : mappingField.select(), mappingField.apply(),
mappingField.condition(), mappingField.last()); mappingField.condition(), mappingField.last(), mappingField.orderByAsc(), mappingField.orderByDesc());
initBindField(mappingField.select()); initBindField(mappingField.select());
} }
@ -191,9 +191,9 @@ public class MPJTableFieldInfo {
this.joinColumn = joinFieldInfo.getColumn(); this.joinColumn = joinFieldInfo.getColumn();
this.joinField = joinFieldInfo.getField(); this.joinField = joinFieldInfo.getField();
} }
Assert.notNull(this.joinField, "MPJMapping注解thisField不存在 %s , %s", this.joinClass.getName(), Assert.notNull(this.joinField, "注解属性thisField不存在 %s , %s", this.joinClass.getName(),
StringUtils.isBlank(this.joinProperty) ? "主键" : this.joinProperty); StringUtils.isBlank(this.joinProperty) ? "主键" : this.joinProperty);
Assert.notNull(this.joinColumn, "MPJMapping注解thisField不存在 %s , %s", this.joinClass.getName(), Assert.notNull(this.joinColumn, "注解属性thisField不存在 %s , %s", this.joinClass.getName(),
StringUtils.isBlank(this.joinProperty) ? "主键" : this.joinProperty); StringUtils.isBlank(this.joinProperty) ? "主键" : this.joinProperty);
this.joinField.setAccessible(true); this.joinField.setAccessible(true);
this.joinMapKey = StringUtils.isBlank(joinMapKey) ? this.joinColumn : joinMapKey; this.joinMapKey = StringUtils.isBlank(joinMapKey) ? this.joinColumn : joinMapKey;
@ -212,13 +212,13 @@ public class MPJTableFieldInfo {
if (tableInfo.havePK() && this.thisProperty.equals(tableInfo.getKeyProperty())) { if (tableInfo.havePK() && this.thisProperty.equals(tableInfo.getKeyProperty())) {
this.thisField = ReflectionKit.getFieldList(ClassUtils.getUserClass(entityType)).stream().filter(f -> this.thisField = ReflectionKit.getFieldList(ClassUtils.getUserClass(entityType)).stream().filter(f ->
f.getName().equals(tableInfo.getKeyProperty())).findFirst().orElse(null); f.getName().equals(tableInfo.getKeyProperty())).findFirst().orElse(null);
Assert.notNull(this.thisField, "MPJMapping注解thisField不存在 %s , %s", entityType.getName(), Assert.notNull(this.thisField, "注解属性thisField不存在 %s , %s", entityType.getName(),
StringUtils.isBlank(this.thisProperty) ? "主键" : this.thisProperty); StringUtils.isBlank(this.thisProperty) ? "主键" : this.thisProperty);
this.thisColumn = tableInfo.getKeyColumn(); this.thisColumn = tableInfo.getKeyColumn();
} else { } else {
TableFieldInfo fieldInfo = tableInfo.getFieldList().stream().filter(f -> TableFieldInfo fieldInfo = tableInfo.getFieldList().stream().filter(f ->
f.getField().getName().equals(this.thisProperty)).findFirst().orElse(null); f.getField().getName().equals(this.thisProperty)).findFirst().orElse(null);
Assert.notNull(fieldInfo, "MPJMapping注解thisField不存在 %s , %s", entityType.getName(), Assert.notNull(fieldInfo, "注解属性thisField不存在 %s , %s", entityType.getName(),
StringUtils.isBlank(this.thisProperty) ? "主键" : this.thisProperty); StringUtils.isBlank(this.thisProperty) ? "主键" : this.thisProperty);
assert fieldInfo != null; assert fieldInfo != null;
this.thisField = fieldInfo.getField(); this.thisField = fieldInfo.getField();

View File

@ -25,7 +25,7 @@ public class MPJTableInfo {
private TableInfo tableInfo; private TableInfo tableInfo;
/** /**
* 是否包含 MPJMapping 或者 MPJMappingField * 是否包含 EntityMapping 或者 FieldMapping
*/ */
private boolean hasMappingOrField; private boolean hasMappingOrField;

View File

@ -518,10 +518,10 @@ public class MPJTableInfoHelper {
* 初始化映射相关 * 初始化映射相关
*/ */
public static void initMapping(MPJTableInfo mpjTableInfo) { public static void initMapping(MPJTableInfo mpjTableInfo) {
// 是否存在 @MPJMapping 注解 // 是否存在 @EntityMapping 注解
boolean existMapping = isExistMapping(mpjTableInfo.getTableInfo().getEntityType()); boolean existMapping = isExistMapping(mpjTableInfo.getTableInfo().getEntityType());
mpjTableInfo.setHasMapping(existMapping); mpjTableInfo.setHasMapping(existMapping);
// 是否存在 @MPJMappingField 注解 // 是否存在 @FieldMapping 注解
boolean existMappingField = isExistMappingField(mpjTableInfo.getTableInfo().getEntityType()); boolean existMappingField = isExistMappingField(mpjTableInfo.getTableInfo().getEntityType());
mpjTableInfo.setHasMappingField(existMappingField); mpjTableInfo.setHasMappingField(existMappingField);
mpjTableInfo.setHasMappingOrField(existMapping || existMappingField); mpjTableInfo.setHasMappingOrField(existMapping || existMappingField);

View File

@ -81,6 +81,18 @@ public @interface EntityMapping {
*/ */
MPJMappingCondition[] condition() default {}; MPJMappingCondition[] condition() default {};
/**
* 映射表查询条件之 orderBy<br/>
* 等效于 Wrappers.<T>query().orderByAsc(xxx);
*/
String orderByAsc() default "";
/**
* 映射表查询条件之 orderByDesc<br/>
* 等效于 Wrappers.<T>query().orderByDesc(xxx);
*/
String orderByDesc() default "";
/** /**
* 映射表查询条件之 last<br/> * 映射表查询条件之 last<br/>
* 建议不要在这使用分页语句会导致关联查的时候查询不全<br/> * 建议不要在这使用分页语句会导致关联查的时候查询不全<br/>

View File

@ -80,6 +80,18 @@ public @interface FieldMapping {
*/ */
MPJMappingCondition[] condition() default {}; MPJMappingCondition[] condition() default {};
/**
* 映射表查询条件之 orderBy<br/>
* 等效于 Wrappers.<T>query().orderByAsc(xxx);
*/
String orderByAsc() default "";
/**
* 映射表查询条件之 orderByDesc<br/>
* 等效于 Wrappers.<T>query().orderByDesc(xxx);
*/
String orderByDesc() default "";
/** /**
* 映射表查询条件之 last<br/> * 映射表查询条件之 last<br/>
* 建议不要在这使用分页语句会导致关联查的时候查询不全<br/> * 建议不要在这使用分页语句会导致关联查的时候查询不全<br/>

View File

@ -503,8 +503,11 @@ public interface MPJDeepMapper<T> extends BaseMapper<T> {
} }
wrapper.eq(SqlKeyword.EQ == keyword, column, val) wrapper.eq(SqlKeyword.EQ == keyword, column, val)
.first(infoWrapper.isHasFirst(), infoWrapper.getFirst()) .first(infoWrapper.isHasFirst(), infoWrapper.getFirst())
.orderByAsc(infoWrapper.isHasOrderByAsc(), infoWrapper.getOrderByAsc())
.orderByDesc(infoWrapper.isHasOrderByDesc(), infoWrapper.getOrderByDesc())
.last(infoWrapper.isHasLast(), infoWrapper.getLast()); .last(infoWrapper.isHasLast(), infoWrapper.getLast());
if (SqlKeyword.IN == keyword) { if (SqlKeyword.IN == keyword) {
//由于Java发放调用机制 无法使用链式
wrapper.in(column, (List<?>) val); wrapper.in(column, (List<?>) val);
} }
if (infoWrapper.isHasSelect()) { if (infoWrapper.isHasSelect()) {

View File

@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction; import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.github.yulichang.annotation.EntityMapping; import com.github.yulichang.annotation.EntityMapping;
import com.github.yulichang.annotation.FieldMapping;
import com.github.yulichang.base.MPJBaseMapper; import com.github.yulichang.base.MPJBaseMapper;
import java.io.Serializable; import java.io.Serializable;
@ -17,12 +18,13 @@ import java.util.Map;
/** /**
* 深度查询 * 深度查询
* <p> * <p>
* 对配置了@MPJMapping注解的字段进行查询 * 对配置了映射注解的字段进行查询
* 目前查询深度只支持2级(只解析当前实体类的MPJMapping注解,不会对查询结果再次解析注解) * 目前查询深度只支持2级(只解析当前实体类的映射注解,不会对查询结果再次解析注解)
* 多级查询可能存在循环引用的问题也可能会导致全量查询 * 多级查询可能存在循环引用的问题也可能会导致全量查询
* *
* @author yulichang * @author yulichang
* @see EntityMapping * @see EntityMapping
* @see FieldMapping
* @since 1.2.0 * @since 1.2.0
*/ */
@SuppressWarnings({"unused", "unchecked"}) @SuppressWarnings({"unused", "unchecked"})