diff --git a/src/main/java/com/imyeyu/spring/bean/Page.java b/src/main/java/com/imyeyu/spring/bean/Page.java index 3eefc12..d0dbc24 100644 --- a/src/main/java/com/imyeyu/spring/bean/Page.java +++ b/src/main/java/com/imyeyu/spring/bean/Page.java @@ -17,6 +17,8 @@ public class Page extends BasePage { protected LinkedHashMap orderMap; + protected LinkedHashMap likeMap; + public Page() { } @@ -45,9 +47,11 @@ public class Page extends BasePage { orderMap.put(Text.camelCase2underscore(field), orderType); } - public static > R toResult(BaseMapper pageMapper, P page, R result) { - result.setList(pageMapper.listOrder(page.getOffset(), page.getLimit(), page.getOrderMap())); - result.setTotal(pageMapper.count()); - return result; + public LinkedHashMap getLikeMap() { + return likeMap; + } + + public void setLikeMap(LinkedHashMap likeMap) { + this.likeMap = likeMap; } } diff --git a/src/main/java/com/imyeyu/spring/mapper/BaseMapper.java b/src/main/java/com/imyeyu/spring/mapper/BaseMapper.java index a28401c..7121491 100644 --- a/src/main/java/com/imyeyu/spring/mapper/BaseMapper.java +++ b/src/main/java/com/imyeyu/spring/mapper/BaseMapper.java @@ -1,5 +1,7 @@ package com.imyeyu.spring.mapper; +import com.imyeyu.spring.bean.Page; +import com.imyeyu.spring.bean.PageResult; import com.imyeyu.spring.util.SQLProvider; import org.apache.ibatis.annotations.DeleteProvider; import org.apache.ibatis.annotations.InsertProvider; @@ -8,7 +10,6 @@ import org.apache.ibatis.annotations.SelectProvider; import org.apache.ibatis.annotations.UpdateProvider; import java.util.List; -import java.util.Map; /** * 基本 SQL 映射,子接口可以不实现 @@ -40,26 +41,35 @@ public interface BaseMapper { String PAGE = NOT_DELETE + " LIMIT #{offset}, #{limit}"; /** - * 统计数据量 + * 根据 Page 对象查询数据列表 * - * @return 数据量 - */ - @SelectProvider(type = SQLProvider.class, method = "count") - long count(); - - default List list(long offset, int limit) { - return listOrder(offset, limit, null); - } - - /** - * 获取部分数据 - * - * @param offset 偏移 - * @param limit 数据量 + * @param page 分页参数 * @return 数据列表 */ - @SelectProvider(type = SQLProvider.class, method = "listOrder") - List listOrder(long offset, int limit, Map orderMap); + @SelectProvider(type = SQLProvider.class, method = "listByPage") + List listByPage(Page page); + + /** + * 根据 Page 对象统计数据量 + * + * @param page 分页参数 + * @return 数据量 + */ + @SelectProvider(type = SQLProvider.class, method = "countByPage") + long countByPage(Page page); + + /** + * 分页查询 + * + * @param page 分页参数 + * @return 分页结果 + */ + default PageResult page(Page page) { + PageResult result = new PageResult<>(); + result.setTotal(countByPage(page)); + result.setList(listByPage(page)); + return result; + } @SelectProvider(type = SQLProvider.class, method = "listAll") List listAll(); diff --git a/src/main/java/com/imyeyu/spring/service/AbstractEntityService.java b/src/main/java/com/imyeyu/spring/service/AbstractEntityService.java index 2af8d30..b2dc2ff 100644 --- a/src/main/java/com/imyeyu/spring/service/AbstractEntityService.java +++ b/src/main/java/com/imyeyu/spring/service/AbstractEntityService.java @@ -32,7 +32,7 @@ public abstract class AbstractEntityService implements BaseService { @Override public PageResult page(Page page) { checkMapper(); - return Page.toResult(baseMapper, page, new PageResult<>()); + return baseMapper.page(page); } public void create(T t) { diff --git a/src/main/java/com/imyeyu/spring/util/SQLProvider.java b/src/main/java/com/imyeyu/spring/util/SQLProvider.java index 12edb2a..b2b42ea 100644 --- a/src/main/java/com/imyeyu/spring/util/SQLProvider.java +++ b/src/main/java/com/imyeyu/spring/util/SQLProvider.java @@ -10,6 +10,7 @@ import com.imyeyu.spring.annotation.table.DeleteColumn; import com.imyeyu.spring.annotation.table.Id; import com.imyeyu.spring.annotation.table.Table; import com.imyeyu.spring.annotation.table.Transient; +import com.imyeyu.spring.bean.Page; import com.imyeyu.spring.entity.Creatable; import com.imyeyu.spring.entity.Deletable; import com.imyeyu.spring.entity.Destroyable; @@ -42,39 +43,80 @@ public class SQLProvider { /** 反射缓存 */ private static final Map, EntityMeta> ENTITY_META_CACHE = new ConcurrentHashMap<>(); - public String count(ProviderContext context) { - 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())); - } - return sql.toString(); - } - - public String listOrder(ProviderContext context, @Param("offset") Long offset, @Param("limit") Integer limit, @Param("orderMap") Map orderMap) { + /** + * 根据 Page 对象查询数据列表 + * + * @param context 代理器上下文 + * @param page 分页参数 + * @return SQL + */ + public String listByPage(ProviderContext context, @Param("page") Page page) { EntityMeta meta = getEntityMeta(context); StringBuilder sql = new StringBuilder(); sql.append("SELECT %s FROM `%s` WHERE 1 = 1".formatted(meta.selectAllClause, meta.table)); + + // 处理软删除 if (meta.canDelete) { 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 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 "); - for (Map.Entry item : orderMap.entrySet()) { - sql.append(Text.camelCase2underscore(item.getKey())).append(' ').append(item.getValue().toString()); - sql.append(", "); + for (Map.Entry item : page.getOrderMap().entrySet()) { + sql.append("`%s` %s, ".formatted( + Text.camelCase2underscore(item.getKey()), + item.getValue().toString() + )); } sql.deleteCharAt(sql.length() - 2); } else { + // 默认排序 if (meta.canCreate && !meta.canUpdate) { - sql.append(" ORDER BY created_at DESC"); + sql.append(" ORDER BY `created_at` DESC"); } 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 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) {