Pre Merge pull request !123 from Sor1e/master
This commit is contained in:
commit
510da15fae
14
pom.xml
14
pom.xml
|
|
@ -40,12 +40,24 @@
|
|||
<common-pool.version>2.10.0</common-pool.version>
|
||||
<commons-collections.version>3.2.2</commons-collections.version>
|
||||
<transmittable-thread-local.version>2.12.2</transmittable-thread-local.version>
|
||||
<mockito.version>4.1.0</mockito.version>
|
||||
</properties>
|
||||
|
||||
<!-- 依赖声明 -->
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-junit-jupiter</artifactId>
|
||||
<version>${mockito.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-inline</artifactId>
|
||||
<version>${mockito.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- SpringCloud 微服务 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
|
|
|
|||
|
|
@ -124,7 +124,21 @@
|
|||
<groupId>io.swagger</groupId>
|
||||
<artifactId>swagger-annotations</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/org.mockito/mockito-junit-jupiter -->
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-junit-jupiter</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-inline</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
package com.ruoyi.common.core.annotation.order;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Repeatable;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* 自定义排序
|
||||
* 如何使用:
|
||||
* @DefaultOrder(column="createTime", orderType="desc", tableName="user")
|
||||
* class UserVO {
|
||||
* ...
|
||||
* }
|
||||
* startPage(UserVO.class)
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Repeatable(CustomOrders.class)
|
||||
public @interface CustomOrder {
|
||||
// 列名 驼峰最终会转换为下划线命名法作为最终排序列名。
|
||||
String column() default "";
|
||||
|
||||
// 列对应的表名
|
||||
String tableName() default "";
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package com.ruoyi.common.core.annotation.order;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* 自定义排序组合注解
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Target({ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Component
|
||||
public @interface CustomOrders {
|
||||
CustomOrder[] value();
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package com.ruoyi.common.core.annotation.order;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* 默认排序
|
||||
* 如何使用:
|
||||
* @DefaultOrder(column="createTime", orderType="desc", tableName="user")
|
||||
* class UserVO {
|
||||
* ...
|
||||
* }
|
||||
* startPage(UserVO.class)
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface DefaultOrder {
|
||||
// 默认排序列 驼峰最终会转换为下划线命名法作为最终排序列名。
|
||||
String column() default "";
|
||||
// 排序类型, desc/asc
|
||||
String orderType() default "asc";
|
||||
// 表名, 可不指定
|
||||
String tableName() default "";
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package com.ruoyi.common.core.annotation.order;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* 字段表别名
|
||||
* 如何使用:
|
||||
* class UserVO {
|
||||
* ...
|
||||
* @TableAlias("dept")
|
||||
* private String deptName;
|
||||
* ...
|
||||
* }
|
||||
* startPage(UserVO.class)
|
||||
* 查询多表关联时, 指定表别名, 即可简单实现完成对应的字段排序。
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Target(ElementType.FIELD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface TableAlias {
|
||||
String value() default "";
|
||||
}
|
||||
|
|
@ -1,8 +1,14 @@
|
|||
package com.ruoyi.common.core.web.controller;
|
||||
|
||||
import java.beans.PropertyEditorSupport;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import com.ruoyi.common.core.annotation.order.CustomOrder;
|
||||
import com.ruoyi.common.core.annotation.order.DefaultOrder;
|
||||
import com.ruoyi.common.core.annotation.order.TableAlias;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.web.bind.WebDataBinder;
|
||||
|
|
@ -60,12 +66,162 @@ public class BaseController
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置请求分页数据
|
||||
* 并根据class的注解设置排序列
|
||||
* 列对应表名优先级
|
||||
* TableAlias > CustomOrder > DefaultOrder
|
||||
* @param clazz
|
||||
*/
|
||||
protected void startPage(Class<?> clazz) {
|
||||
// 正常分页的情况
|
||||
if (clazz == null) {
|
||||
startPage();
|
||||
return;
|
||||
}
|
||||
PageDomain pageDomain = TableSupport.buildPageRequest();
|
||||
Integer pageNum = pageDomain.getPageNum();
|
||||
Integer pageSize = pageDomain.getPageSize();
|
||||
if (pageNum != null && pageSize != null) {
|
||||
PageHelper.startPage(pageNum, pageSize);
|
||||
}
|
||||
|
||||
// 处理orderBy的情况。
|
||||
String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());
|
||||
String column = SqlUtil.escapeOrderBySql(pageDomain.getOrderByColumn());
|
||||
// 获取默认排序
|
||||
if (StringUtils.isEmpty(orderBy)) {
|
||||
orderBy = getDefaultOrderByAnnotation(clazz);
|
||||
}
|
||||
|
||||
if (StringUtils.isEmpty(orderBy)) {
|
||||
return;
|
||||
}
|
||||
// 根据列获取表名
|
||||
String tableName = getTableNameByColumn(clazz, column);
|
||||
if (StringUtils.isNotEmpty(tableName)) {
|
||||
orderBy = tableName + "." + orderBy;
|
||||
}
|
||||
PageHelper.orderBy(orderBy);
|
||||
}
|
||||
|
||||
/**
|
||||
* 尝试从field的TableAlias获取表别名
|
||||
* @param clazz
|
||||
* @param column
|
||||
* @return
|
||||
*/
|
||||
private static String getFieldTableName(Class<?> clazz, String column) {
|
||||
// 获取对象中所有的成员变量
|
||||
Field[] declaredFields = clazz.getDeclaredFields();
|
||||
for (Field field : declaredFields) {
|
||||
String fieldName = field.getName();
|
||||
if (Objects.equals(column, fieldName)) {
|
||||
if (field.isAnnotationPresent(TableAlias.class)) {
|
||||
TableAlias orderTableAlias = field.getAnnotation(TableAlias.class);
|
||||
return orderTableAlias.value();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 尝试从CustomOrder获取表别名
|
||||
* @param clazz
|
||||
* @param column
|
||||
* @return
|
||||
*/
|
||||
private static String getCustomOrderTableName(Class<?> clazz, String column) {
|
||||
// 获取对象中所有的成员变量
|
||||
if (clazz.isAnnotationPresent(CustomOrder.class)) {
|
||||
CustomOrder[] customOrders = clazz.getAnnotationsByType(CustomOrder.class);
|
||||
for (CustomOrder customOrder : customOrders) {
|
||||
String realColumn = column;
|
||||
if (column.contains("_")) {
|
||||
realColumn = StringUtils.toCamelCase(customOrder.column());
|
||||
}
|
||||
if (Objects.equals(column, realColumn)) {
|
||||
return customOrder.tableName();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* 获取默认排序
|
||||
* @param clazz
|
||||
* @return
|
||||
*/
|
||||
private static String getDefaultTableName(Class<?> clazz) {
|
||||
// 最后,查找类上的tableName
|
||||
if (clazz.isAnnotationPresent(DefaultOrder.class)) {
|
||||
DefaultOrder defaultOrder = clazz.getAnnotation(DefaultOrder.class);
|
||||
if (StringUtils.isNotEmpty(defaultOrder.tableName())) {
|
||||
return defaultOrder.tableName();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过过滤列获取对应的table
|
||||
* @param clazz
|
||||
* @param column
|
||||
* @return
|
||||
*/
|
||||
private static String getTableNameByColumn(Class<?> clazz, String column) {
|
||||
if (clazz == null) {
|
||||
return null;
|
||||
}
|
||||
String tableName = null;
|
||||
// 未指定排序 则尝试设置默认排序的Table
|
||||
if (StringUtils.isEmpty(column)) {
|
||||
tableName = getDefaultTableName(clazz);
|
||||
return tableName;
|
||||
}
|
||||
|
||||
|
||||
// 优先获取字段的tableName
|
||||
tableName = getFieldTableName(clazz, column);
|
||||
if (StringUtils.isNotEmpty(tableName)) {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
// 其次查找CustomOrder定义的column对应的TableName
|
||||
tableName = getCustomOrderTableName(clazz, column);
|
||||
if (StringUtils.isNotEmpty(tableName)) {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
// 获取默认排序
|
||||
tableName = getDefaultTableName(clazz);
|
||||
|
||||
return tableName;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取类注解获取默认过滤列
|
||||
* @param clazz
|
||||
* @return
|
||||
*/
|
||||
private String getDefaultOrderByAnnotation(Class<?> clazz) {
|
||||
if (!clazz.isAnnotationPresent(DefaultOrder.class)) {
|
||||
return null;
|
||||
}
|
||||
DefaultOrder defaultOrder = clazz.getAnnotation(DefaultOrder.class);
|
||||
String orderBy = null;
|
||||
if (StringUtils.isNotEmpty(defaultOrder.column())) {
|
||||
orderBy = StringUtils.toUnderScoreCase(defaultOrder.column()) + " " + defaultOrder.orderType();
|
||||
}
|
||||
return orderBy;
|
||||
}
|
||||
|
||||
/**
|
||||
* 响应请求分页数据
|
||||
*/
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
protected TableDataInfo getDataTable(List<?> list)
|
||||
{
|
||||
protected TableDataInfo getDataTable(List<?> list) {
|
||||
TableDataInfo rspData = new TableDataInfo();
|
||||
rspData.setCode(HttpStatus.SUCCESS);
|
||||
rspData.setRows(list);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,125 @@
|
|||
package com.ruoyi.common.core.web.controller;
|
||||
|
||||
import com.github.pagehelper.Page;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.ruoyi.common.core.annotation.order.CustomOrder;
|
||||
import com.ruoyi.common.core.annotation.order.DefaultOrder;
|
||||
import com.ruoyi.common.core.annotation.order.TableAlias;
|
||||
import com.ruoyi.common.core.web.domain.BaseEntity;
|
||||
import com.ruoyi.common.core.web.page.PageDomain;
|
||||
import com.ruoyi.common.core.web.page.TableSupport;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.MockedStatic;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
class BaseControllerTest {
|
||||
|
||||
@Test
|
||||
void testStartPageByDefaultOrder()
|
||||
{
|
||||
@DefaultOrder(tableName = "user", column = "userName")
|
||||
class UserVO {
|
||||
private String userName;
|
||||
}
|
||||
PageDomain pageDomain = new PageDomain();
|
||||
pageDomain.setPageNum(10);
|
||||
pageDomain.setPageSize(20);
|
||||
|
||||
MockedStatic<TableSupport> mocked = Mockito.mockStatic(TableSupport.class);
|
||||
mocked.when(TableSupport::buildPageRequest).thenReturn(
|
||||
pageDomain
|
||||
);
|
||||
new BaseController().startPage(UserVO.class);
|
||||
Page<Object> localPage = PageHelper.getLocalPage();
|
||||
String orderBy = localPage.getOrderBy();
|
||||
assertEquals("user.user_name asc", orderBy);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testStartPageByDefaultOrder2()
|
||||
{
|
||||
@DefaultOrder(tableName = "user", column = "user_name")
|
||||
class UserVO {
|
||||
private String userName;
|
||||
}
|
||||
PageDomain pageDomain = new PageDomain();
|
||||
pageDomain.setPageNum(10);
|
||||
pageDomain.setPageSize(20);
|
||||
|
||||
MockedStatic<TableSupport> mocked = Mockito.mockStatic(TableSupport.class);
|
||||
mocked.when(TableSupport::buildPageRequest).thenReturn(
|
||||
pageDomain
|
||||
);
|
||||
new BaseController().startPage(UserVO.class);
|
||||
Page<Object> localPage = PageHelper.getLocalPage();
|
||||
String orderBy = localPage.getOrderBy();
|
||||
assertEquals("user.user_name asc", orderBy);
|
||||
}
|
||||
@Test
|
||||
void testStartPageByTableAlias()
|
||||
{
|
||||
class UserVO {
|
||||
@TableAlias("user")
|
||||
private String userName;
|
||||
}
|
||||
PageDomain pageDomain = new PageDomain();
|
||||
pageDomain.setPageNum(10);
|
||||
pageDomain.setPageSize(20);
|
||||
pageDomain.setOrderByColumn("userName");
|
||||
MockedStatic<TableSupport> mocked = Mockito.mockStatic(TableSupport.class);
|
||||
mocked.when(TableSupport::buildPageRequest).thenReturn(
|
||||
pageDomain
|
||||
);
|
||||
new BaseController().startPage(UserVO.class);
|
||||
Page<Object> localPage = PageHelper.getLocalPage();
|
||||
String orderBy = localPage.getOrderBy();
|
||||
assertEquals("user.user_name asc", orderBy);
|
||||
}
|
||||
@Test
|
||||
void testStartPageByCustomOrder()
|
||||
{
|
||||
@CustomOrder(tableName = "user", column = "createTime")
|
||||
class UserVO extends BaseEntity {
|
||||
private String userName;
|
||||
}
|
||||
PageDomain pageDomain = new PageDomain();
|
||||
pageDomain.setPageNum(10);
|
||||
pageDomain.setPageSize(20);
|
||||
pageDomain.setOrderByColumn("createTime");
|
||||
pageDomain.setIsAsc("desc");
|
||||
|
||||
MockedStatic<TableSupport> mocked = Mockito.mockStatic(TableSupport.class);
|
||||
mocked.when(TableSupport::buildPageRequest).thenReturn(
|
||||
pageDomain
|
||||
);
|
||||
new BaseController().startPage(UserVO.class);
|
||||
Page<Object> localPage = PageHelper.getLocalPage();
|
||||
String orderBy = localPage.getOrderBy();
|
||||
assertEquals("user.create_time desc", orderBy);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testStartPageByCustomOrder2()
|
||||
{
|
||||
@CustomOrder(tableName = "user", column = "create_time")
|
||||
class UserVO extends BaseEntity {
|
||||
private String userName;
|
||||
}
|
||||
PageDomain pageDomain = new PageDomain();
|
||||
pageDomain.setPageNum(10);
|
||||
pageDomain.setPageSize(20);
|
||||
pageDomain.setOrderByColumn("createTime");
|
||||
pageDomain.setIsAsc("desc");
|
||||
|
||||
MockedStatic<TableSupport> mocked = Mockito.mockStatic(TableSupport.class);
|
||||
mocked.when(TableSupport::buildPageRequest).thenReturn(
|
||||
pageDomain
|
||||
);
|
||||
new BaseController().startPage(UserVO.class);
|
||||
Page<Object> localPage = PageHelper.getLocalPage();
|
||||
String orderBy = localPage.getOrderBy();
|
||||
assertEquals("user.create_time desc", orderBy);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue