feat(eq): 完成easy-query框架的适配
This commit is contained in:
1
pom.xml
1
pom.xml
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
<module>spring-boot-service-template-common</module>
|
<module>spring-boot-service-template-common</module>
|
||||||
|
<module>spring-boot-service-template-eq</module>
|
||||||
<module>spring-boot-service-template-jpa</module>
|
<module>spring-boot-service-template-jpa</module>
|
||||||
<module>spring-boot-service-template-xbatis</module>
|
<module>spring-boot-service-template-xbatis</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|||||||
80
spring-boot-service-template-eq/pom.xml
Normal file
80
spring-boot-service-template-eq/pom.xml
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>com.lanyuanxiaoyao</groupId>
|
||||||
|
<artifactId>spring-boot-service-template</artifactId>
|
||||||
|
<version>1.1.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>spring-boot-service-template-eq</artifactId>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.lanyuanxiaoyao</groupId>
|
||||||
|
<artifactId>spring-boot-service-template-common</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.easy-query</groupId>
|
||||||
|
<artifactId>sql-springboot4-starter</artifactId>
|
||||||
|
<version>3.1.68</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.gavlyukovskiy</groupId>
|
||||||
|
<artifactId>p6spy-spring-boot-starter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jspecify</groupId>
|
||||||
|
<artifactId>jspecify</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.h2database</groupId>
|
||||||
|
<artifactId>h2</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-source-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>jar-no-fork</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<annotationProcessorPaths>
|
||||||
|
<path>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
</path>
|
||||||
|
<path>
|
||||||
|
<groupId>com.easy-query</groupId>
|
||||||
|
<artifactId>sql-processor</artifactId>
|
||||||
|
<version>3.1.68</version>
|
||||||
|
</path>
|
||||||
|
</annotationProcessorPaths>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,209 @@
|
|||||||
|
package com.lanyuanxiaoyao.service.template.eq.controller;
|
||||||
|
|
||||||
|
import com.easy.query.core.proxy.AbstractProxyEntity;
|
||||||
|
import com.easy.query.core.proxy.ProxyEntityAvailable;
|
||||||
|
import com.lanyuanxiaoyao.service.template.common.controller.SimpleController;
|
||||||
|
import com.lanyuanxiaoyao.service.template.common.entity.GlobalResponse;
|
||||||
|
import com.lanyuanxiaoyao.service.template.common.entity.Query;
|
||||||
|
import com.lanyuanxiaoyao.service.template.common.helper.ObjectHelper;
|
||||||
|
import com.lanyuanxiaoyao.service.template.eq.entity.SimpleEntity;
|
||||||
|
import com.lanyuanxiaoyao.service.template.eq.service.SimpleServiceSupport;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 简单控制器支持类,提供基础的CRUD操作实现
|
||||||
|
* <p>
|
||||||
|
* 该类实现了基本的增删改查功能,通过泛型支持不同类型的数据转换。
|
||||||
|
* 子类需要实现对应的Mapper函数来完成实体类与传输对象之间的转换。
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <h3>设计特点</h3>
|
||||||
|
* <ul>
|
||||||
|
* <li>泛型设计,支持任意实体类型和数据转换</li>
|
||||||
|
* <li>统一的异常处理和事务管理</li>
|
||||||
|
* <li>支持条件查询、分页查询和详情查询</li>
|
||||||
|
* <li>提供抽象的Mapper方法,便于子类实现数据转换逻辑</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* <h3>使用说明</h3>
|
||||||
|
* <p>子类需要实现以下抽象方法:</p>
|
||||||
|
* <ul>
|
||||||
|
* <li>saveItemMapper(): 保存项到实体的转换函数</li>
|
||||||
|
* <li>listItemMapper(): 实体到列表项的转换函数</li>
|
||||||
|
* <li>detailItemMapper(): 实体到详情项的转换函数</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @param <ENTITY> 实体类型,必须继承SimpleEntity
|
||||||
|
* @param <SAVE_ITEM> 保存项类型
|
||||||
|
* @param <LIST_ITEM> 列表项类型
|
||||||
|
* @param <DETAIL_ITEM> 详情项类型
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public abstract class SimpleControllerSupport<ENTITY extends SimpleEntity & ProxyEntityAvailable<ENTITY, PROXY>, PROXY extends AbstractProxyEntity<PROXY, ENTITY>, SAVE_ITEM, LIST_ITEM, DETAIL_ITEM> implements SimpleController<SAVE_ITEM, LIST_ITEM, DETAIL_ITEM> {
|
||||||
|
protected final SimpleServiceSupport<ENTITY, PROXY> service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存实体对象
|
||||||
|
* <p>
|
||||||
|
* 将保存项转换为实体对象后保存,返回保存后的实体ID。
|
||||||
|
* 支持新增和更新操作,通过事务保证数据一致性。
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param item 需要保存的项
|
||||||
|
* @return 返回保存后的实体ID响应对象,格式:{status: 0, message: "OK", data: 实体ID}
|
||||||
|
* @throws Exception 保存过程中可能抛出的异常
|
||||||
|
*/
|
||||||
|
@Transactional(rollbackFor = Throwable.class)
|
||||||
|
@PostMapping(SAVE)
|
||||||
|
@Override
|
||||||
|
public GlobalResponse<Long> save(@RequestBody SAVE_ITEM item) throws Exception {
|
||||||
|
var mapper = saveItemMapper();
|
||||||
|
return GlobalResponse.responseSuccess(service.save(mapper.apply(item)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有实体列表
|
||||||
|
* <p>
|
||||||
|
* 查询所有记录,不带任何过滤条件,返回分页格式的数据。
|
||||||
|
* 将实体对象转换为列表项对象后返回。
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @return 返回实体列表响应对象,格式:{status: 0, message: "OK", data: {items: [...], total: total}}
|
||||||
|
* @throws Exception 查询过程中可能抛出的异常
|
||||||
|
*/
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
@GetMapping(LIST)
|
||||||
|
@Override
|
||||||
|
public GlobalResponse<GlobalResponse.ListItem<LIST_ITEM>> list() throws Exception {
|
||||||
|
var mapper = listItemMapper();
|
||||||
|
var result = service.list();
|
||||||
|
return GlobalResponse.responseListData(
|
||||||
|
result
|
||||||
|
.stream()
|
||||||
|
.map(entity -> {
|
||||||
|
try {
|
||||||
|
return mapper.apply(entity);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.toList(),
|
||||||
|
result.size()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据查询条件获取实体列表
|
||||||
|
* <p>
|
||||||
|
* 支持复杂的查询条件、排序和分页,返回符合条件的数据。
|
||||||
|
* 将实体对象转换为列表项对象后返回。
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param query 查询条件对象,包含过滤条件、排序规则和分页信息
|
||||||
|
* @return 返回符合条件的实体列表响应对象,格式:{status: 0, message: "OK", data: {items: [...], total: total}}
|
||||||
|
* @throws Exception 查询过程中可能抛出的异常
|
||||||
|
*/
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
@PostMapping(LIST)
|
||||||
|
@Override
|
||||||
|
public GlobalResponse<GlobalResponse.ListItem<LIST_ITEM>> list(@RequestBody Query query) throws Exception {
|
||||||
|
if (ObjectHelper.isNull(query)) {
|
||||||
|
return GlobalResponse.responseListData();
|
||||||
|
}
|
||||||
|
var mapper = listItemMapper();
|
||||||
|
var result = service.list(query);
|
||||||
|
return GlobalResponse.responseListData(
|
||||||
|
result.items()
|
||||||
|
.stream()
|
||||||
|
.map(entity -> {
|
||||||
|
try {
|
||||||
|
return mapper.apply(entity);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.toList(),
|
||||||
|
result.total()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据ID获取实体详情
|
||||||
|
* <p>
|
||||||
|
* 根据主键ID查询单条记录的详细信息,转换为详情项对象后返回。
|
||||||
|
* 如果记录不存在则抛出异常。
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param id 实体主键ID
|
||||||
|
* @return 返回实体详情响应对象,格式:{status: 0, message: "OK", data: 详情数据}
|
||||||
|
* @throws Exception 查询过程中可能抛出的异常
|
||||||
|
*/
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
@GetMapping(DETAIL)
|
||||||
|
@Override
|
||||||
|
public GlobalResponse<DETAIL_ITEM> detail(@PathVariable("id") Long id) throws Exception {
|
||||||
|
var mapper = detailItemMapper();
|
||||||
|
return GlobalResponse.responseSuccess(mapper.apply(service.detailOrThrow(id)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据ID删除实体对象
|
||||||
|
* <p>
|
||||||
|
* 根据主键ID删除指定的记录,执行成功后返回成功响应。
|
||||||
|
* 通过事务保证删除操作的一致性。
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param id 需要删除的实体主键ID
|
||||||
|
* @return 返回删除结果响应对象,格式:{status: 0, message: "OK", data: null}
|
||||||
|
* @throws Exception 删除过程中可能抛出的异常
|
||||||
|
*/
|
||||||
|
@Transactional(rollbackFor = Throwable.class)
|
||||||
|
@GetMapping(REMOVE)
|
||||||
|
@Override
|
||||||
|
public GlobalResponse<Object> remove(@PathVariable("id") Long id) throws Exception {
|
||||||
|
service.remove(id);
|
||||||
|
return GlobalResponse.responseSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存项映射器,将保存项转换为实体对象
|
||||||
|
* <p>
|
||||||
|
* 子类需要实现此方法,定义保存项到实体的转换逻辑。
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @return Function<SAVE_ITEM, ENTITY> 保存项到实体的转换函数
|
||||||
|
*/
|
||||||
|
protected abstract Function<SAVE_ITEM, ENTITY> saveItemMapper();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 列表项映射器,将实体对象转换为列表项
|
||||||
|
* <p>
|
||||||
|
* 子类需要实现此方法,定义实体到列表项的转换逻辑。
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @return Function<ENTITY, LIST_ITEM> 实体到列表项的转换函数
|
||||||
|
*/
|
||||||
|
protected abstract Function<ENTITY, LIST_ITEM> listItemMapper();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 详情项映射器,将实体对象转换为详情项
|
||||||
|
* <p>
|
||||||
|
* 子类需要实现此方法,定义实体到详情项的转换逻辑。
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @return Function<ENTITY, DETAIL_ITEM> 实体到详情项的转换函数
|
||||||
|
*/
|
||||||
|
protected abstract Function<ENTITY, DETAIL_ITEM> detailItemMapper();
|
||||||
|
|
||||||
|
public interface Mapper<S, T> {
|
||||||
|
T map(S source) throws Exception;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package com.lanyuanxiaoyao.service.template.eq.entity;
|
||||||
|
|
||||||
|
import com.easy.query.core.annotation.Column;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import lombok.ToString;
|
||||||
|
import lombok.experimental.FieldNameConstants;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@ToString
|
||||||
|
@FieldNameConstants
|
||||||
|
public class IdOnlyEntity {
|
||||||
|
@Column(primaryKey = true, primaryKeyGenerator = SnowflakeIdGenerator.class)
|
||||||
|
private Long id;
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package com.lanyuanxiaoyao.service.template.eq.entity;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import lombok.ToString;
|
||||||
|
import lombok.experimental.FieldNameConstants;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
@FieldNameConstants
|
||||||
|
public class SimpleEntity extends IdOnlyEntity {
|
||||||
|
private LocalDateTime createdTime;
|
||||||
|
private LocalDateTime modifiedTime;
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package com.lanyuanxiaoyao.service.template.eq.entity;
|
||||||
|
|
||||||
|
import com.easy.query.core.basic.extension.generated.PrimaryKeyGenerator;
|
||||||
|
import com.lanyuanxiaoyao.service.template.common.helper.SnowflakeHelper;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class SnowflakeIdGenerator implements PrimaryKeyGenerator {
|
||||||
|
@Override
|
||||||
|
public Serializable getPrimaryKey() {
|
||||||
|
return SnowflakeHelper.next();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,270 @@
|
|||||||
|
package com.lanyuanxiaoyao.service.template.eq.service;
|
||||||
|
|
||||||
|
import com.easy.query.api.proxy.client.EasyEntityQuery;
|
||||||
|
import com.easy.query.core.enums.SQLExecuteStrategyEnum;
|
||||||
|
import com.easy.query.core.proxy.AbstractProxyEntity;
|
||||||
|
import com.easy.query.core.proxy.ProxyEntityAvailable;
|
||||||
|
import com.lanyuanxiaoyao.service.template.common.entity.Page;
|
||||||
|
import com.lanyuanxiaoyao.service.template.common.entity.Query;
|
||||||
|
import com.lanyuanxiaoyao.service.template.common.exception.IdNotFoundException;
|
||||||
|
import com.lanyuanxiaoyao.service.template.common.helper.ObjectHelper;
|
||||||
|
import com.lanyuanxiaoyao.service.template.common.service.QueryParser;
|
||||||
|
import com.lanyuanxiaoyao.service.template.common.service.SimpleService;
|
||||||
|
import com.lanyuanxiaoyao.service.template.eq.entity.SimpleEntity;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public abstract class SimpleServiceSupport<ENTITY extends SimpleEntity & ProxyEntityAvailable<ENTITY, PROXY>, PROXY extends AbstractProxyEntity<PROXY, ENTITY>> implements SimpleService<ENTITY> {
|
||||||
|
private static final int DEFAULT_PAGE_INDEX = 1;
|
||||||
|
private static final int DEFAULT_PAGE_SIZE = 10;
|
||||||
|
|
||||||
|
protected final EasyEntityQuery entityQuery;
|
||||||
|
private final Class<ENTITY> target;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long save(ENTITY entity) {
|
||||||
|
if (ObjectHelper.isNull(entity.getId())) {
|
||||||
|
entityQuery.insertable(entity).executeRows();
|
||||||
|
} else {
|
||||||
|
entityQuery.updatable(entity)
|
||||||
|
.setSQLStrategy(SQLExecuteStrategyEnum.ONLY_NOT_NULL_COLUMNS)
|
||||||
|
.executeRows();
|
||||||
|
}
|
||||||
|
return entity.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void save(Iterable<ENTITY> entities) {
|
||||||
|
var insertList = new ArrayList<ENTITY>();
|
||||||
|
var updateList = new ArrayList<ENTITY>();
|
||||||
|
for (var entity : entities) {
|
||||||
|
if (ObjectHelper.isNull(entity.getId())) {
|
||||||
|
insertList.add(entity);
|
||||||
|
} else {
|
||||||
|
updateList.add(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ObjectHelper.isNotEmpty(insertList)) {
|
||||||
|
entityQuery.insertable(insertList).executeRows();
|
||||||
|
}
|
||||||
|
if (ObjectHelper.isNotEmpty(updateList)) {
|
||||||
|
entityQuery.updatable(updateList)
|
||||||
|
.setSQLStrategy(SQLExecuteStrategyEnum.ONLY_NOT_NULL_COLUMNS)
|
||||||
|
.executeRows();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long count() {
|
||||||
|
return entityQuery.queryable(target).count();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ENTITY> list() {
|
||||||
|
return entityQuery.queryable(target).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<ENTITY> list(Set<Long> ids) {
|
||||||
|
if (ObjectHelper.isEmpty(ids)) {
|
||||||
|
return List.of();
|
||||||
|
}
|
||||||
|
return entityQuery.queryable(target)
|
||||||
|
.whereByIds(ids)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void commonPredicates(PROXY proxy) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Page<ENTITY> list(Query query) {
|
||||||
|
var index = DEFAULT_PAGE_INDEX;
|
||||||
|
var size = DEFAULT_PAGE_SIZE;
|
||||||
|
if (ObjectHelper.isNotNull(query.page())) {
|
||||||
|
index = Math.max(ObjectHelper.defaultIfNull(query.page().index(), DEFAULT_PAGE_INDEX), 1);
|
||||||
|
size = Math.max(ObjectHelper.defaultIfNull(query.page().size(), DEFAULT_PAGE_SIZE), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = entityQuery.queryable(target)
|
||||||
|
.where(this::commonPredicates)
|
||||||
|
.where(proxy -> new EqQueryParser<ENTITY, PROXY>(proxy).build(query.query()))
|
||||||
|
.orderBy(ObjectHelper.isNotEmpty(query.sort()), proxy -> query.sort().forEach(sort -> proxy.anyColumn(sort.column()).orderBy(Query.Sortable.Direction.ASC.equals(sort.direction()))))
|
||||||
|
.toPageResult(index, size);
|
||||||
|
|
||||||
|
return new Page<>(result.getData(), result.getTotal());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<ENTITY> detailOptional(Long id) {
|
||||||
|
if (ObjectHelper.isNull(id)) {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
return entityQuery.queryable(target)
|
||||||
|
.whereById(id)
|
||||||
|
.singleOptional();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ENTITY detail(Long id) {
|
||||||
|
return detailOptional(id).orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ENTITY detailOrThrow(Long id) {
|
||||||
|
return detailOptional(id).orElseThrow(() -> new IdNotFoundException(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remove(Long id) {
|
||||||
|
if (ObjectHelper.isNotNull(id)) {
|
||||||
|
entityQuery.deletable(target)
|
||||||
|
.whereById(id)
|
||||||
|
.allowDeleteStatement(true)
|
||||||
|
.executeRows();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void remove(Set<Long> ids) {
|
||||||
|
if (ObjectHelper.isNotEmpty(ids)) {
|
||||||
|
entityQuery.deletable(target)
|
||||||
|
.whereByIds(ids)
|
||||||
|
.allowDeleteStatement(true)
|
||||||
|
.executeRows();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
private static final class EqQueryParser<ENTITY extends SimpleEntity & ProxyEntityAvailable<ENTITY, PROXY>, PROXY extends AbstractProxyEntity<PROXY, ENTITY>> extends QueryParser<Void> {
|
||||||
|
private final PROXY proxy;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void nullEqual(Query.Queryable queryable) {
|
||||||
|
queryable.nullEqual().forEach(column -> proxy.anyColumn(column).isNull());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void notNullEqual(Query.Queryable queryable) {
|
||||||
|
queryable.notNullEqual().forEach(column -> proxy.anyColumn(column).isNotNull());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void empty(Query.Queryable queryable) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void notEmpty(Query.Queryable queryable) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void equal(Query.Queryable queryable) {
|
||||||
|
queryable.equal().forEach((column, value) -> proxy.anyColumn(column).eq(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void notEqual(Query.Queryable queryable) {
|
||||||
|
queryable.notEqual().forEach((column, value) -> proxy.anyColumn(column).ne(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void like(Query.Queryable queryable) {
|
||||||
|
queryable.like().forEach((column, value) -> proxy.anyColumn(column).likeRaw(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void notLike(Query.Queryable queryable) {
|
||||||
|
queryable.notLike().forEach((column, value) -> proxy.anyColumn(column).notLikeRaw(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void contain(Query.Queryable queryable) {
|
||||||
|
queryable.contain().forEach((column, value) -> proxy.anyColumn(column).like(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void notContain(Query.Queryable queryable) {
|
||||||
|
queryable.notContain().forEach((column, value) -> proxy.anyColumn(column).notLike(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void startWith(Query.Queryable queryable) {
|
||||||
|
queryable.startWith().forEach((column, value) -> proxy.anyColumn(column).likeMatchLeft(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void notStartWith(Query.Queryable queryable) {
|
||||||
|
queryable.notStartWith().forEach((column, value) -> proxy.anyColumn(column).notLikeMatchLeft(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void endWith(Query.Queryable queryable) {
|
||||||
|
queryable.endWith().forEach((column, value) -> proxy.anyColumn(column).likeMatchRight(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void notEndWith(Query.Queryable queryable) {
|
||||||
|
queryable.notEndWith().forEach((column, value) -> proxy.anyColumn(column).notLikeMatchRight(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void great(Query.Queryable queryable) {
|
||||||
|
queryable.great().forEach((column, value) -> proxy.anyColumn(column).gt(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void less(Query.Queryable queryable) {
|
||||||
|
queryable.less().forEach((column, value) -> proxy.anyColumn(column).lt(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void greatEqual(Query.Queryable queryable) {
|
||||||
|
queryable.greatEqual().forEach((column, value) -> proxy.anyColumn(column).ge(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void lessEqual(Query.Queryable queryable) {
|
||||||
|
queryable.lessEqual().forEach((column, value) -> proxy.anyColumn(column).le(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void inside(Query.Queryable queryable) {
|
||||||
|
queryable.inside()
|
||||||
|
.entrySet()
|
||||||
|
.stream()
|
||||||
|
.filter(entry -> ObjectHelper.isNotEmpty(entry.getValue()))
|
||||||
|
.forEach(entry -> proxy.anyColumn(entry.getKey()).in(entry.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void notInside(Query.Queryable queryable) {
|
||||||
|
queryable.notInside()
|
||||||
|
.entrySet()
|
||||||
|
.stream()
|
||||||
|
.filter(entry -> ObjectHelper.isNotEmpty(entry.getValue()))
|
||||||
|
.forEach(entry -> proxy.anyColumn(entry.getKey()).notIn(entry.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void between(Query.Queryable queryable) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void notBetween(Query.Queryable queryable) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Void build() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
17
spring-boot-service-template-eq/src/test/initial.sql
Normal file
17
spring-boot-service-template-eq/src/test/initial.sql
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
create table if not exists Company
|
||||||
|
(
|
||||||
|
id bigint primary key,
|
||||||
|
name varchar(255) not null,
|
||||||
|
members int not null,
|
||||||
|
created_time timestamp not null default current_timestamp(),
|
||||||
|
modified_time timestamp not null default current_timestamp() on update current_timestamp()
|
||||||
|
);
|
||||||
|
|
||||||
|
create table if not exists Employee
|
||||||
|
(
|
||||||
|
id bigint primary key,
|
||||||
|
name varchar(255) not null,
|
||||||
|
age int not null,
|
||||||
|
created_time timestamp not null default current_timestamp(),
|
||||||
|
modified_time timestamp not null default current_timestamp() on update current_timestamp()
|
||||||
|
);
|
||||||
@@ -0,0 +1,167 @@
|
|||||||
|
package com.lanyuanxiaoyao.service.template.eq;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.boot.context.event.ApplicationReadyEvent;
|
||||||
|
import org.springframework.context.event.EventListener;
|
||||||
|
import org.springframework.http.HttpEntity;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
import tools.jackson.databind.JsonNode;
|
||||||
|
import tools.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@SpringBootApplication
|
||||||
|
public class TestApplication {
|
||||||
|
private static final String BASE_URL = "http://localhost:2490";
|
||||||
|
private static final RestTemplate REST_CLIENT = new RestTemplate();
|
||||||
|
private static final ObjectMapper MAPPER = new ObjectMapper();
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(TestApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventListener(ApplicationReadyEvent.class)
|
||||||
|
public void runTests() {
|
||||||
|
// 增
|
||||||
|
var cid1 = saveItem("company", "{\"name\": \"Apple\",\"members\": 10}").get("data").asLong();
|
||||||
|
var cid2 = saveItem("company", "{\"name\": \"Banana\",\"members\": 20}").get("data").asLong();
|
||||||
|
var cid3 = saveItem("company", "{\"name\": \"Cheery\",\"members\": 20}").get("data").asLong();
|
||||||
|
|
||||||
|
// 查
|
||||||
|
var companies = listItems("company");
|
||||||
|
Assert.isTrue(companies.at("/data/items").size() == 3, "数量错误");
|
||||||
|
Assert.isTrue(companies.at("/data/total").asLong() == 3, "返回数量错误");
|
||||||
|
|
||||||
|
// language=JSON
|
||||||
|
var companies2 = listItems("company", "{\n" +
|
||||||
|
" \"page\": {\n" +
|
||||||
|
" \"index\": 1,\n" +
|
||||||
|
" \"size\": 2\n" +
|
||||||
|
" }\n" +
|
||||||
|
"}");
|
||||||
|
Assert.isTrue(companies2.at("/data/items").size() == 2, "数量错误");
|
||||||
|
Assert.isTrue(companies2.at("/data/total").asLong() == 3, "返回数量错误");
|
||||||
|
// language=JSON
|
||||||
|
var companies3 = listItems("company", "{\n" +
|
||||||
|
" \"query\": {\n" +
|
||||||
|
" \"notNullEqual\": [\n" +
|
||||||
|
" \"name\"\n" +
|
||||||
|
" ],\n" +
|
||||||
|
" \"equal\": {\n" +
|
||||||
|
" \"name\": \"Apple\"\n" +
|
||||||
|
" },\n" +
|
||||||
|
" \"like\": {\n" +
|
||||||
|
" \"name\": \"Appl%\"\n" +
|
||||||
|
" },\n" +
|
||||||
|
" \"contain\": {\n" +
|
||||||
|
" \"name\": \"ple\"\n" +
|
||||||
|
" },\n" +
|
||||||
|
" \"startWith\": {\n" +
|
||||||
|
" \"name\": \"Appl\"\n" +
|
||||||
|
" },\n" +
|
||||||
|
" \"endWith\": {\n" +
|
||||||
|
" \"name\": \"le\"\n" +
|
||||||
|
" },\n" +
|
||||||
|
" \"less\": {\n" +
|
||||||
|
" \"members\": 50\n" +
|
||||||
|
" },\n" +
|
||||||
|
" \"greatEqual\": {\n" +
|
||||||
|
" \"members\": 0,\n" +
|
||||||
|
" \"createdTime\": \"2025-01-01 00:00:00\"\n" +
|
||||||
|
" },\n" +
|
||||||
|
" \"inside\": {\n" +
|
||||||
|
" \"name\": [\n" +
|
||||||
|
" \"Apple\",\n" +
|
||||||
|
" \"Banana\"\n" +
|
||||||
|
" ]\n" +
|
||||||
|
" }\n" +
|
||||||
|
" },\n" +
|
||||||
|
" \"page\": {\n" +
|
||||||
|
" \"index\": 1,\n" +
|
||||||
|
" \"size\": 2\n" +
|
||||||
|
" }\n" +
|
||||||
|
"}");
|
||||||
|
Assert.isTrue(companies3.at("/data/items").size() == 1, "数量错误");
|
||||||
|
Assert.isTrue(companies3.at("/data/total").asLong() == 1, "返回数量错误");
|
||||||
|
|
||||||
|
var company1 = detailItem("company", cid1);
|
||||||
|
Assert.isTrue(cid1 == company1.at("/data/id").asLong(), "id错误");
|
||||||
|
Assert.isTrue("Apple".equals(company1.at("/data/name").asString()), "name错误");
|
||||||
|
|
||||||
|
// 改
|
||||||
|
var cid4 = saveItem("company", "{\"id\": %d, \"name\": \"Dog\"}".formatted(cid2)).get("data").asLong();
|
||||||
|
Assert.isTrue(cid2 == cid4, "id错误");
|
||||||
|
var company2 = detailItem("company", cid2);
|
||||||
|
Assert.isTrue("Dog".equals(company2.at("/data/name").asString()), "name错误");
|
||||||
|
|
||||||
|
// 删
|
||||||
|
removeItem("company", cid3);
|
||||||
|
Assert.isTrue(listItems("company").at("/data/items").size() == 2, "数量错误");
|
||||||
|
Assert.isTrue(listItems("company").at("/data/total").asLong() == 2, "返回数量错误");
|
||||||
|
|
||||||
|
log.info(listItems("company").toPrettyString());
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private HttpHeaders headers() {
|
||||||
|
var headers = new HttpHeaders();
|
||||||
|
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
private JsonNode saveItem(String path, String body) {
|
||||||
|
var response = REST_CLIENT.postForEntity(
|
||||||
|
"%s/%s/save".formatted(BASE_URL, path),
|
||||||
|
new HttpEntity<>(body, headers()),
|
||||||
|
String.class
|
||||||
|
);
|
||||||
|
Assert.isTrue(response.getStatusCode().is2xxSuccessful(), "请求失败");
|
||||||
|
Assert.notNull(response.getBody(), "请求失败");
|
||||||
|
return MAPPER.readTree(response.getBody());
|
||||||
|
}
|
||||||
|
|
||||||
|
private JsonNode listItems(String path) {
|
||||||
|
var response = REST_CLIENT.getForEntity(
|
||||||
|
"%s/%s/list".formatted(BASE_URL, path),
|
||||||
|
String.class
|
||||||
|
);
|
||||||
|
Assert.isTrue(response.getStatusCode().is2xxSuccessful(), "请求失败");
|
||||||
|
Assert.notNull(response.getBody(), "请求失败");
|
||||||
|
return MAPPER.readTree(response.getBody());
|
||||||
|
}
|
||||||
|
|
||||||
|
private JsonNode listItems(String path, String query) {
|
||||||
|
var response = REST_CLIENT.postForEntity(
|
||||||
|
"%s/%s/list".formatted(BASE_URL, path),
|
||||||
|
new HttpEntity<>(query, headers()),
|
||||||
|
String.class
|
||||||
|
);
|
||||||
|
Assert.isTrue(response.getStatusCode().is2xxSuccessful(), "请求失败");
|
||||||
|
Assert.notNull(response.getBody(), "请求失败");
|
||||||
|
return MAPPER.readTree(response.getBody());
|
||||||
|
}
|
||||||
|
|
||||||
|
private JsonNode detailItem(String path, Long id) {
|
||||||
|
var response = REST_CLIENT.getForEntity(
|
||||||
|
"%s/%s/detail/%d".formatted(BASE_URL, path, id),
|
||||||
|
String.class
|
||||||
|
);
|
||||||
|
Assert.isTrue(response.getStatusCode().is2xxSuccessful(), "请求失败");
|
||||||
|
Assert.notNull(response.getBody(), "请求失败");
|
||||||
|
return MAPPER.readTree(response.getBody());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeItem(String path, Long id) {
|
||||||
|
var response = REST_CLIENT.getForEntity(
|
||||||
|
"%s/%s/remove/%d".formatted(BASE_URL, path, id),
|
||||||
|
Void.class
|
||||||
|
);
|
||||||
|
Assert.isTrue(response.getStatusCode().is2xxSuccessful(), "请求失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
package com.lanyuanxiaoyao.service.template.eq.controller;
|
||||||
|
|
||||||
|
import com.lanyuanxiaoyao.service.template.eq.entity.Company;
|
||||||
|
import com.lanyuanxiaoyao.service.template.eq.entity.proxy.CompanyProxy;
|
||||||
|
import com.lanyuanxiaoyao.service.template.eq.service.CompanyService;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("company")
|
||||||
|
public class CompanyController extends SimpleControllerSupport<Company, CompanyProxy, CompanyController.SaveItem, CompanyController.ListItem, CompanyController.DetailItem> {
|
||||||
|
public CompanyController(CompanyService service) {
|
||||||
|
super(service);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Function<SaveItem, Company> saveItemMapper() {
|
||||||
|
return item -> {
|
||||||
|
var company = new Company();
|
||||||
|
company.setId(item.id());
|
||||||
|
company.setName(item.name());
|
||||||
|
company.setMembers(item.members());
|
||||||
|
return company;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Function<Company, ListItem> listItemMapper() {
|
||||||
|
return company -> new ListItem(
|
||||||
|
company.getId(),
|
||||||
|
company.getName(),
|
||||||
|
company.getMembers()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Function<Company, DetailItem> detailItemMapper() {
|
||||||
|
return company -> new DetailItem(
|
||||||
|
company.getId(),
|
||||||
|
company.getName(),
|
||||||
|
company.getMembers(),
|
||||||
|
company.getCreatedTime(),
|
||||||
|
company.getModifiedTime()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public record SaveItem(
|
||||||
|
Long id,
|
||||||
|
String name,
|
||||||
|
Integer members
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public record ListItem(
|
||||||
|
Long id,
|
||||||
|
String name,
|
||||||
|
Integer members
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public record DetailItem(
|
||||||
|
Long id,
|
||||||
|
String name,
|
||||||
|
Integer members,
|
||||||
|
LocalDateTime createdTime,
|
||||||
|
LocalDateTime modifiedTime
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package com.lanyuanxiaoyao.service.template.eq.entity;
|
||||||
|
|
||||||
|
import com.easy.query.core.annotation.EntityProxy;
|
||||||
|
import com.easy.query.core.annotation.Table;
|
||||||
|
import com.easy.query.core.proxy.ProxyEntityAvailable;
|
||||||
|
import com.lanyuanxiaoyao.service.template.eq.entity.proxy.CompanyProxy;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import lombok.ToString;
|
||||||
|
import lombok.experimental.FieldNameConstants;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
@FieldNameConstants
|
||||||
|
@Table
|
||||||
|
@EntityProxy
|
||||||
|
public class Company extends SimpleEntity implements ProxyEntityAvailable<Company, CompanyProxy> {
|
||||||
|
private String name;
|
||||||
|
private Integer members;
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package com.lanyuanxiaoyao.service.template.eq.entity;
|
||||||
|
|
||||||
|
import com.easy.query.core.annotation.EntityProxy;
|
||||||
|
import com.easy.query.core.annotation.Table;
|
||||||
|
import com.easy.query.core.proxy.ProxyEntityAvailable;
|
||||||
|
import com.lanyuanxiaoyao.service.template.eq.entity.proxy.EmployeeProxy;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import lombok.ToString;
|
||||||
|
import lombok.experimental.FieldNameConstants;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
@FieldNameConstants
|
||||||
|
@Table
|
||||||
|
@EntityProxy
|
||||||
|
public class Employee extends SimpleEntity implements ProxyEntityAvailable<Employee, EmployeeProxy> {
|
||||||
|
private String name;
|
||||||
|
private Integer age;
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package com.lanyuanxiaoyao.service.template.eq.service;
|
||||||
|
|
||||||
|
import com.easy.query.api.proxy.client.EasyEntityQuery;
|
||||||
|
import com.lanyuanxiaoyao.service.template.eq.entity.Company;
|
||||||
|
import com.lanyuanxiaoyao.service.template.eq.entity.proxy.CompanyProxy;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class CompanyService extends SimpleServiceSupport<Company, CompanyProxy> {
|
||||||
|
public CompanyService(EasyEntityQuery entityQuery) {
|
||||||
|
super(entityQuery, Company.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package com.lanyuanxiaoyao.service.template.eq.service;
|
||||||
|
|
||||||
|
import com.easy.query.api.proxy.client.EasyEntityQuery;
|
||||||
|
import com.lanyuanxiaoyao.service.template.eq.entity.Employee;
|
||||||
|
import com.lanyuanxiaoyao.service.template.eq.entity.proxy.EmployeeProxy;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class EmployeeService extends SimpleServiceSupport<Employee, EmployeeProxy> {
|
||||||
|
public EmployeeService(EasyEntityQuery entityQuery) {
|
||||||
|
super(entityQuery, Employee.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
server:
|
||||||
|
port: 2490
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: Test
|
||||||
|
datasource:
|
||||||
|
url: "jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;MODE=MySQL;DATABASE_TO_LOWER=TRUE;INIT=runscript from '/Users/lanyuanxiaoyao/Project/IdeaProjects/spring-boot-service-template/spring-boot-service-template-eq/src/test/initial.sql'"
|
||||||
|
username: test
|
||||||
|
password: test
|
||||||
|
driver-class-name: org.h2.Driver
|
||||||
|
easy-query:
|
||||||
|
database: mysql
|
||||||
|
name-conversion: underlined
|
||||||
|
print-sql: false
|
||||||
|
decorator:
|
||||||
|
datasource:
|
||||||
|
p6spy:
|
||||||
|
multiline: false
|
||||||
|
exclude-categories:
|
||||||
|
- commit
|
||||||
|
- result
|
||||||
|
- resultset
|
||||||
|
- rollback
|
||||||
|
log-format: "%(category)|%(executionTime)|%(sqlSingleLine)"
|
||||||
Reference in New Issue
Block a user