Compare commits

...

5 Commits

Author SHA1 Message Date
413f376a15 fix pageExample 2025-12-09 10:21:41 +08:00
7a52560779 update Language.Enum 2025-12-08 16:57:03 +08:00
75c8f556a8 support equals or like Example for page 2025-12-08 16:56:41 +08:00
7654c3a360 ignored .claude 2025-12-08 16:54:54 +08:00
5239b469ac ignored illegal time for create and update 2025-12-08 16:07:31 +08:00
7 changed files with 95 additions and 42 deletions

1
.gitignore vendored
View File

@ -57,3 +57,4 @@ dependency-reduced-pom.xml
buildNumber.properties
.mvn/timing.properties
.claude

View File

@ -353,7 +353,7 @@ public class TimiSpring {
*
* @return 客户端地区语言
*/
public static Language getLanguage() {
public static Language.Enum getLanguage() {
String name = getRequestArg("lang");
if (TimiJava.isEmpty(name)) {
List<Locale.LanguageRange> rangeList = Locale.LanguageRange.parse(getLanguageRaw());
@ -368,9 +368,9 @@ public class TimiSpring {
name = name.replace("-", "_");
}
if (TimiJava.isEmpty(name)) { // use for not support
return Language.zh_CN;
return Language.Enum.zh_CN;
}
return Ref.toType(Language.class, name);
return Ref.toType(Language.Enum.class, name);
}
/**

View File

@ -13,12 +13,14 @@ import java.util.LinkedHashMap;
* @author 夜雨
* @version 2023-06-02 14:47
*/
public class Page extends BasePage {
public class Page<T> extends BasePage {
protected T equalsExample;
protected T likeExample;
protected LinkedHashMap<String, BaseMapper.OrderType> orderMap;
protected LinkedHashMap<String, String> likeMap;
public Page() {
}
@ -30,10 +32,26 @@ public class Page extends BasePage {
return (long) index * size;
}
public int getLimit() {
public long getLimit() {
return size;
}
public T getEqualsExample() {
return equalsExample;
}
public void setEqualsExample(T equalsExample) {
this.equalsExample = equalsExample;
}
public T getLikeExample() {
return likeExample;
}
public void setLikeExample(T likeExample) {
this.likeExample = likeExample;
}
public LinkedHashMap<String, BaseMapper.OrderType> getOrderMap() {
return orderMap;
}
@ -46,12 +64,4 @@ public class Page extends BasePage {
orderMap = TimiJava.firstNotNull(orderMap, new LinkedHashMap<>());
orderMap.put(Text.camelCase2underscore(field), orderType);
}
public LinkedHashMap<String, String> getLikeMap() {
return likeMap;
}
public void setLikeMap(LinkedHashMap<String, String> likeMap) {
this.likeMap = likeMap;
}
}

View File

@ -47,7 +47,7 @@ public interface BaseMapper<T, P> {
* @return 数据列表
*/
@SelectProvider(type = SQLProvider.class, method = "listByPage")
List<T> listByPage(Page page);
List<T> listByPage(Page<T> page);
/**
* 根据 Page 对象统计数据量
@ -56,7 +56,7 @@ public interface BaseMapper<T, P> {
* @return 数据量
*/
@SelectProvider(type = SQLProvider.class, method = "countByPage")
long countByPage(Page page);
long countByPage(Page<T> page);
/**
* 分页查询
@ -64,7 +64,7 @@ public interface BaseMapper<T, P> {
* @param page 分页参数
* @return 分页结果
*/
default PageResult<T> page(Page page) {
default PageResult<T> page(Page<T> page) {
PageResult<T> result = new PageResult<>();
result.setTotal(countByPage(page));
result.setList(listByPage(page));

View File

@ -3,6 +3,9 @@ package com.imyeyu.spring.service;
import com.imyeyu.java.bean.timi.TimiException;
import com.imyeyu.spring.bean.Page;
import com.imyeyu.spring.bean.PageResult;
import com.imyeyu.spring.entity.Creatable;
import com.imyeyu.spring.entity.Deletable;
import com.imyeyu.spring.entity.Updatable;
import com.imyeyu.spring.mapper.BaseMapper;
/**
@ -30,13 +33,19 @@ public abstract class AbstractEntityService<T, P> implements BaseService<T, P> {
}
@Override
public PageResult<T> page(Page page) {
public PageResult<T> page(Page<T> page) {
checkMapper();
return baseMapper.page(page);
}
public void create(T t) {
checkMapper();
if (t instanceof Updatable updatable) {
updatable.setUpdatedAt(null);
}
if (t instanceof Deletable deletable) {
deletable.setDeletedAt(null);
}
baseMapper.insert(t);
}
@ -47,6 +56,12 @@ public abstract class AbstractEntityService<T, P> implements BaseService<T, P> {
public void update(T t) {
checkMapper();
if (t instanceof Creatable creatable) {
creatable.setCreatedAt(null);
}
if (t instanceof Deletable deletable) {
deletable.setDeletedAt(null);
}
baseMapper.updateSelective(t);
}

View File

@ -18,5 +18,5 @@ public interface PageableService<T> {
* @param page 页面查询参数
* @return 查询页面结果
*/
PageResult<T> page(Page page);
PageResult<T> page(Page<T> page);
}

View File

@ -50,25 +50,34 @@ public class SQLProvider {
* @param page 分页参数
* @return SQL
*/
public String listByPage(ProviderContext context, @Param("page") Page page) {
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(page.getLikeMap())) {
for (Map.Entry<String, String> item : page.getLikeMap().entrySet()) {
sql.append(" AND `%s` LIKE CONCAT('%%', #{likeMap.%s}, '%%')".formatted(
Text.camelCase2underscore(item.getKey()),
item.getKey()
));
}
if (TimiJava.isNotEmpty(page.getEqualsExample())) {
// 精准查询
Object obj = page.getEqualsExample();
EntityMeta metaExample = getEntityMeta(obj.getClass());
String conditionClause = metaExample.fieldColumnList.stream()
.filter(fc -> fc.isNotNull(obj))
.map(fc -> "`%s` = '%s'".formatted(fc.columnName, fc.getAsString(obj)))
.collect(Collectors.joining(" AND "));
sql.append(" AND ").append(conditionClause);
}
// 处理排序
if (TimiJava.isNotEmpty(page.getLikeExample())) {
// 模糊查询
Object obj = page.getLikeExample();
EntityMeta metaExample = getEntityMeta(obj.getClass());
String conditionClause = metaExample.fieldColumnList.stream()
.filter(fc -> fc.isNotNull(obj))
.map(fc -> "`%s` LIKE CONCAT('%%', '%s', '%%')".formatted(fc.columnName, fc.getAsString(obj)))
.collect(Collectors.joining(" OR "));
sql.append(" AND (").append(conditionClause).append(')');
}
// 排序
if (TimiJava.isNotEmpty(page.getOrderMap())) {
sql.append(" ORDER BY ");
for (Map.Entry<String, BaseMapper.OrderType> item : page.getOrderMap().entrySet()) {
@ -99,22 +108,32 @@ public class SQLProvider {
* @param page 分页参数
* @return SQL
*/
public String countByPage(ProviderContext context, @Param("page") com.imyeyu.spring.bean.Page page) {
public String countByPage(ProviderContext context, @Param("page") 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('%%', #{likeMap.%s}, '%%')".formatted(
Text.camelCase2underscore(item.getKey()),
item.getKey()
));
}
if (TimiJava.isNotEmpty(page.getEqualsExample())) {
// 精准查询
Object obj = page.getEqualsExample();
EntityMeta metaExample = getEntityMeta(obj.getClass());
String conditionClause = metaExample.fieldColumnList.stream()
.filter(fc -> fc.isNotNull(obj))
.map(fc -> "`%s` = '%s'".formatted(fc.columnName, fc.getAsString(obj)))
.collect(Collectors.joining(" AND "));
sql.append(" AND ").append(conditionClause);
}
if (TimiJava.isNotEmpty(page.getLikeExample())) {
// 模糊查询
Object obj = page.getLikeExample();
EntityMeta metaExample = getEntityMeta(obj.getClass());
String conditionClause = metaExample.fieldColumnList.stream()
.filter(fc -> fc.isNotNull(obj))
.map(fc -> "`%s` LIKE CONCAT('%%', '%s', '%%')".formatted(fc.columnName, fc.getAsString(obj)))
.collect(Collectors.joining(" OR "));
sql.append(" AND (").append(conditionClause).append(')');
}
return sql.toString();
}
@ -528,6 +547,14 @@ public class SQLProvider {
return !isNull(entity);
}
public String getAsString(Object obj) {
try {
return field.get(obj).toString();
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
public Field getField() {
return field;
}