update BaseMapper.page

This commit is contained in:
Timi
2025-12-03 10:40:50 +08:00
parent 745b3acfef
commit 7aadec7306
4 changed files with 97 additions and 41 deletions

View File

@ -17,6 +17,8 @@ public class Page extends BasePage {
protected LinkedHashMap<String, BaseMapper.OrderType> orderMap; protected LinkedHashMap<String, BaseMapper.OrderType> orderMap;
protected LinkedHashMap<String, String> likeMap;
public Page() { public Page() {
} }
@ -45,9 +47,11 @@ public class Page extends BasePage {
orderMap.put(Text.camelCase2underscore(field), orderType); orderMap.put(Text.camelCase2underscore(field), orderType);
} }
public static <T, P extends Page, R extends PageResult<T>> R toResult(BaseMapper<T, ?> pageMapper, P page, R result) { public LinkedHashMap<String, String> getLikeMap() {
result.setList(pageMapper.listOrder(page.getOffset(), page.getLimit(), page.getOrderMap())); return likeMap;
result.setTotal(pageMapper.count()); }
return result;
public void setLikeMap(LinkedHashMap<String, String> likeMap) {
this.likeMap = likeMap;
} }
} }

View File

@ -1,5 +1,7 @@
package com.imyeyu.spring.mapper; package com.imyeyu.spring.mapper;
import com.imyeyu.spring.bean.Page;
import com.imyeyu.spring.bean.PageResult;
import com.imyeyu.spring.util.SQLProvider; import com.imyeyu.spring.util.SQLProvider;
import org.apache.ibatis.annotations.DeleteProvider; import org.apache.ibatis.annotations.DeleteProvider;
import org.apache.ibatis.annotations.InsertProvider; import org.apache.ibatis.annotations.InsertProvider;
@ -8,7 +10,6 @@ import org.apache.ibatis.annotations.SelectProvider;
import org.apache.ibatis.annotations.UpdateProvider; import org.apache.ibatis.annotations.UpdateProvider;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* 基本 SQL 映射,子接口可以不实现 * 基本 SQL 映射,子接口可以不实现
@ -40,26 +41,35 @@ public interface BaseMapper<T, P> {
String PAGE = NOT_DELETE + " LIMIT #{offset}, #{limit}"; String PAGE = NOT_DELETE + " LIMIT #{offset}, #{limit}";
/** /**
* 统计数据量 * 根据 Page 对象查询数据列表
* *
* @return 数据量 * @param page 分页参数
*/
@SelectProvider(type = SQLProvider.class, method = "count")
long count();
default List<T> list(long offset, int limit) {
return listOrder(offset, limit, null);
}
/**
* 获取部分数据
*
* @param offset 偏移
* @param limit 数据量
* @return 数据列表 * @return 数据列表
*/ */
@SelectProvider(type = SQLProvider.class, method = "listOrder") @SelectProvider(type = SQLProvider.class, method = "listByPage")
List<T> listOrder(long offset, int limit, Map<String, OrderType> orderMap); List<T> listByPage(Page page);
/**
* 根据 Page 对象统计数据量
*
* @param page 分页参数
* @return 数据量
*/
@SelectProvider(type = SQLProvider.class, method = "countByPage")
long countByPage(Page page);
/**
* 分页查询
*
* @param page 分页参数
* @return 分页结果
*/
default PageResult<T> page(Page page) {
PageResult<T> result = new PageResult<>();
result.setTotal(countByPage(page));
result.setList(listByPage(page));
return result;
}
@SelectProvider(type = SQLProvider.class, method = "listAll") @SelectProvider(type = SQLProvider.class, method = "listAll")
List<T> listAll(); List<T> listAll();

View File

@ -32,7 +32,7 @@ public abstract class AbstractEntityService<T, P> implements BaseService<T, P> {
@Override @Override
public PageResult<T> page(Page page) { public PageResult<T> page(Page page) {
checkMapper(); checkMapper();
return Page.toResult(baseMapper, page, new PageResult<>()); return baseMapper.page(page);
} }
public void create(T t) { public void create(T t) {

View File

@ -10,6 +10,7 @@ import com.imyeyu.spring.annotation.table.DeleteColumn;
import com.imyeyu.spring.annotation.table.Id; import com.imyeyu.spring.annotation.table.Id;
import com.imyeyu.spring.annotation.table.Table; import com.imyeyu.spring.annotation.table.Table;
import com.imyeyu.spring.annotation.table.Transient; import com.imyeyu.spring.annotation.table.Transient;
import com.imyeyu.spring.bean.Page;
import com.imyeyu.spring.entity.Creatable; import com.imyeyu.spring.entity.Creatable;
import com.imyeyu.spring.entity.Deletable; import com.imyeyu.spring.entity.Deletable;
import com.imyeyu.spring.entity.Destroyable; import com.imyeyu.spring.entity.Destroyable;
@ -42,39 +43,80 @@ public class SQLProvider {
/** 反射缓存 */ /** 反射缓存 */
private static final Map<Class<?>, EntityMeta> ENTITY_META_CACHE = new ConcurrentHashMap<>(); private static final Map<Class<?>, EntityMeta> ENTITY_META_CACHE = new ConcurrentHashMap<>();
public String count(ProviderContext context) { /**
EntityMeta meta = getEntityMeta(context); * 根据 Page 对象查询数据列表
StringBuilder sql = new StringBuilder(); *
sql.append("SELECT COUNT(*) FROM `%s` WHERE 1 = 1".formatted(meta.table)); * @param context 代理器上下文
if (meta.canDelete) { * @param page 分页参数
sql.append(" AND (`deleted_at` IS NULL OR %s < `deleted_at`)".formatted(Time.now())); * @return SQL
} */
return sql.toString(); public String listByPage(ProviderContext context, @Param("page") Page page) {
}
public String listOrder(ProviderContext context, @Param("offset") Long offset, @Param("limit") Integer limit, @Param("orderMap") Map<String, BaseMapper.OrderType> orderMap) {
EntityMeta meta = getEntityMeta(context); EntityMeta meta = getEntityMeta(context);
StringBuilder sql = new StringBuilder(); StringBuilder sql = new StringBuilder();
sql.append("SELECT %s FROM `%s` WHERE 1 = 1".formatted(meta.selectAllClause, meta.table)); sql.append("SELECT %s FROM `%s` WHERE 1 = 1".formatted(meta.selectAllClause, meta.table));
// 处理软删除
if (meta.canDelete) { if (meta.canDelete) {
sql.append(" AND (`deleted_at` IS NULL OR %s < `deleted_at`)".formatted(Time.now())); sql.append(" AND (`deleted_at` IS NULL OR %s < `deleted_at`)".formatted(Time.now()));
} }
if (TimiJava.isNotEmpty(orderMap)) { // 处理模糊查询
if (TimiJava.isNotEmpty(page.getLikeMap())) {
for (Map.Entry<String, String> item : page.getLikeMap().entrySet()) {
sql.append(" AND `%s` LIKE CONCAT('%%', #{page.likeMap.%s}, '%%')".formatted(
Text.camelCase2underscore(item.getKey()),
item.getKey()
));
}
}
// 处理排序
if (TimiJava.isNotEmpty(page.getOrderMap())) {
sql.append(" ORDER BY "); sql.append(" ORDER BY ");
for (Map.Entry<String, BaseMapper.OrderType> item : orderMap.entrySet()) { for (Map.Entry<String, BaseMapper.OrderType> item : page.getOrderMap().entrySet()) {
sql.append(Text.camelCase2underscore(item.getKey())).append(' ').append(item.getValue().toString()); sql.append("`%s` %s, ".formatted(
sql.append(", "); Text.camelCase2underscore(item.getKey()),
item.getValue().toString()
));
} }
sql.deleteCharAt(sql.length() - 2); sql.deleteCharAt(sql.length() - 2);
} else { } else {
// 默认排序
if (meta.canCreate && !meta.canUpdate) { if (meta.canCreate && !meta.canUpdate) {
sql.append(" ORDER BY created_at DESC"); sql.append(" ORDER BY `created_at` DESC");
} }
if (meta.canCreate && meta.canUpdate) { if (meta.canCreate && meta.canUpdate) {
sql.append(" ORDER BY COALESCE(updated_at, created_at) DESC"); sql.append(" ORDER BY COALESCE(`updated_at`, `created_at`) DESC");
} }
} }
return sql.append(" LIMIT %s, %s".formatted(offset, limit)).toString(); // 分页
sql.append(" LIMIT #{page.offset}, #{page.limit}");
return sql.toString();
}
/**
* 根据 Page 对象统计数据量
*
* @param context 代理器上下文
* @param page 分页参数
* @return SQL
*/
public String countByPage(ProviderContext context, @Param("page") com.imyeyu.spring.bean.Page page) {
EntityMeta meta = getEntityMeta(context);
StringBuilder sql = new StringBuilder();
sql.append("SELECT COUNT(*) FROM `%s` WHERE 1 = 1".formatted(meta.table));
// 处理软删除
if (meta.canDelete) {
sql.append(" AND (`deleted_at` IS NULL OR %s < `deleted_at`)".formatted(Time.now()));
}
// 处理模糊查询
if (TimiJava.isNotEmpty(page.getLikeMap())) {
for (Map.Entry<String, String> item : page.getLikeMap().entrySet()) {
sql.append(" AND `%s` LIKE CONCAT('%%', #{page.likeMap.%s}, '%%')".formatted(
Text.camelCase2underscore(item.getKey()),
item.getKey()
));
}
}
return sql.toString();
} }
public String listAll(ProviderContext context) { public String listAll(ProviderContext context) {