1
0

fix(eq): 完善测试用例

This commit is contained in:
2026-01-21 17:16:53 +08:00
parent af4d13d76c
commit 53d94c5f4c
18 changed files with 195 additions and 248 deletions

View File

@@ -29,8 +29,8 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.h2database</groupId> <groupId>com.lanyuanxiaoyao</groupId>
<artifactId>h2</artifactId> <artifactId>spring-boot-service-template-database-common-test</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@@ -1,4 +1,4 @@
package com.lanyuanxiaoyao.service.template.eq.controller; package com.lanyuanxiaoyao.service.template.database.eq.controller;
import com.easy.query.core.proxy.AbstractProxyEntity; import com.easy.query.core.proxy.AbstractProxyEntity;
import com.easy.query.core.proxy.ProxyEntityAvailable; import com.easy.query.core.proxy.ProxyEntityAvailable;
@@ -6,8 +6,8 @@ import com.lanyuanxiaoyao.service.template.common.helper.ObjectHelper;
import com.lanyuanxiaoyao.service.template.database.common.controller.SimpleController; import com.lanyuanxiaoyao.service.template.database.common.controller.SimpleController;
import com.lanyuanxiaoyao.service.template.database.common.entity.GlobalResponse; import com.lanyuanxiaoyao.service.template.database.common.entity.GlobalResponse;
import com.lanyuanxiaoyao.service.template.database.common.entity.Query; import com.lanyuanxiaoyao.service.template.database.common.entity.Query;
import com.lanyuanxiaoyao.service.template.eq.entity.SimpleEntity; import com.lanyuanxiaoyao.service.template.database.eq.entity.SimpleEntity;
import com.lanyuanxiaoyao.service.template.eq.service.SimpleServiceSupport; import com.lanyuanxiaoyao.service.template.database.eq.service.SimpleServiceSupport;
import java.util.function.Function; import java.util.function.Function;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;

View File

@@ -1,4 +1,4 @@
package com.lanyuanxiaoyao.service.template.eq.entity; package com.lanyuanxiaoyao.service.template.database.eq.entity;
import com.easy.query.core.annotation.Column; import com.easy.query.core.annotation.Column;
import lombok.Getter; import lombok.Getter;

View File

@@ -0,0 +1,16 @@
package com.lanyuanxiaoyao.service.template.database.eq.entity;
import com.easy.query.core.annotation.LogicDelete;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import lombok.experimental.FieldNameConstants;
@Getter
@Setter
@ToString
@FieldNameConstants
public class LogicDeleteEntity extends IdOnlyEntity {
@LogicDelete
private Boolean deleted = false;
}

View File

@@ -1,4 +1,4 @@
package com.lanyuanxiaoyao.service.template.eq.entity; package com.lanyuanxiaoyao.service.template.database.eq.entity;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import lombok.Getter; import lombok.Getter;
@@ -10,7 +10,7 @@ import lombok.experimental.FieldNameConstants;
@Setter @Setter
@ToString(callSuper = true) @ToString(callSuper = true)
@FieldNameConstants @FieldNameConstants
public class SimpleEntity extends IdOnlyEntity { public class SimpleEntity extends LogicDeleteEntity {
private LocalDateTime createdTime; private LocalDateTime createdTime;
private LocalDateTime modifiedTime; private LocalDateTime modifiedTime;
} }

View File

@@ -1,4 +1,4 @@
package com.lanyuanxiaoyao.service.template.eq.entity; package com.lanyuanxiaoyao.service.template.database.eq.entity;
import com.easy.query.core.basic.extension.generated.PrimaryKeyGenerator; import com.easy.query.core.basic.extension.generated.PrimaryKeyGenerator;
import com.lanyuanxiaoyao.service.template.database.common.helper.SnowflakeHelper; import com.lanyuanxiaoyao.service.template.database.common.helper.SnowflakeHelper;

View File

@@ -1,4 +1,4 @@
package com.lanyuanxiaoyao.service.template.eq.service; package com.lanyuanxiaoyao.service.template.database.eq.service;
import com.easy.query.api.proxy.client.EasyEntityQuery; import com.easy.query.api.proxy.client.EasyEntityQuery;
import com.easy.query.core.enums.SQLExecuteStrategyEnum; import com.easy.query.core.enums.SQLExecuteStrategyEnum;
@@ -10,7 +10,7 @@ import com.lanyuanxiaoyao.service.template.database.common.entity.Query;
import com.lanyuanxiaoyao.service.template.database.common.exception.IdNotFoundException; import com.lanyuanxiaoyao.service.template.database.common.exception.IdNotFoundException;
import com.lanyuanxiaoyao.service.template.database.common.service.QueryParser; import com.lanyuanxiaoyao.service.template.database.common.service.QueryParser;
import com.lanyuanxiaoyao.service.template.database.common.service.SimpleService; import com.lanyuanxiaoyao.service.template.database.common.service.SimpleService;
import com.lanyuanxiaoyao.service.template.eq.entity.SimpleEntity; import com.lanyuanxiaoyao.service.template.database.eq.entity.SimpleEntity;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
@@ -263,12 +263,18 @@ public abstract class SimpleServiceSupport<ENTITY extends SimpleEntity & ProxyEn
@Override @Override
protected void between(Query.Queryable queryable, PROXY proxy) { protected void between(Query.Queryable queryable, PROXY proxy) {
throw new UnsupportedOperationException(); queryable.between().forEach((column, value) -> {
proxy.anyColumn(column).gt(value.start());
proxy.anyColumn(column).le(value.end());
});
} }
@Override @Override
protected void notBetween(Query.Queryable queryable, PROXY proxy) { protected void notBetween(Query.Queryable queryable, PROXY proxy) {
throw new UnsupportedOperationException(); queryable.between().forEach((column, value) -> {
proxy.anyColumn(column).le(value.start());
proxy.anyColumn(column).gt(value.end());
});
} }
} }
} }

View File

@@ -4,7 +4,8 @@ create table if not exists Company
name varchar(255) not null, name varchar(255) not null,
members int not null, members int not null,
created_time timestamp not null default current_timestamp(), created_time timestamp not null default current_timestamp(),
modified_time timestamp not null default current_timestamp() on update current_timestamp() modified_time timestamp not null default current_timestamp() on update current_timestamp(),
deleted tinyint not null default false
); );
create table if not exists Employee create table if not exists Employee
@@ -12,6 +13,8 @@ create table if not exists Employee
id bigint primary key, id bigint primary key,
name varchar(255) not null, name varchar(255) not null,
age int not null, age int not null,
company_id bigint not null,
created_time timestamp not null default current_timestamp(), created_time timestamp not null default current_timestamp(),
modified_time timestamp not null default current_timestamp() on update current_timestamp() modified_time timestamp not null default current_timestamp() on update current_timestamp(),
deleted tinyint not null default false
); );

View File

@@ -0,0 +1,76 @@
package com.lanyuanxiaoyao.service.template.database.eq;
import com.easy.query.api.proxy.client.EasyEntityQuery;
import com.lanyuanxiaoyao.service.template.database.common.test.AbstractTestApplication;
import com.lanyuanxiaoyao.service.template.database.eq.entity.Company;
import com.lanyuanxiaoyao.service.template.database.eq.entity.Employee;
import com.lanyuanxiaoyao.service.template.database.eq.entity.proxy.EmployeeProxy;
import java.util.List;
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.util.Assert;
@Slf4j
@RequiredArgsConstructor
@SpringBootApplication
public class TestApplication extends AbstractTestApplication {
private final EasyEntityQuery entityQuery;
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
@EventListener(ApplicationReadyEvent.class)
public void runTests() {
testCrud();
testDelete();
testQuery();
System.exit(0);
}
private void testDelete() {
formatLog("Delete");
saveItem("company", randomCompany());
saveItem("company", randomCompany());
entityQuery.deletable(Company.class)
.where(proxy -> proxy.id().isNotNull())
.allowDeleteStatement(true)
.executeRows();
}
private void testQuery() {
formatLog("Added");
var company1 = Company.builder().name(randomString(5)).members(randomInt(100)).build();
entityQuery.insertable(company1).executeRows();
var company2 = Company.builder().name(randomString(5)).members(randomInt(100)).build();
entityQuery.insertable(company2).executeRows();
var employee1 = Employee.builder().name("Tom").age(randomInt(100)).companyId(company1.getId()).build();
entityQuery.insertable(employee1).executeRows();
var employee2 = Employee.builder().name(randomString(10)).age(randomInt(100)).companyId(company2.getId()).build();
entityQuery.insertable(employee2).executeRows();
formatLog("Query");
var employees1 = entityQuery.queryable(Employee.class)
.include(EmployeeProxy::company)
.where(proxy -> {
proxy.name().isNotNull();
proxy.name().eq("Tom");
proxy.name().startsWith("To");
proxy.name().endsWith("om");
proxy.age().lt(200);
proxy.age().gt(0);
proxy.name().in(List.of("Tom", "Mike"));
})
.toList();
Assert.isTrue(employees1.size() == 1, "查询数量错误");
formatLog("Clean");
entityQuery.deletable(Company.class).where(proxy -> proxy.id().isNotNull()).executeRows();
entityQuery.deletable(Employee.class).where(proxy -> proxy.id().isNotNull()).executeRows();
}
}

View File

@@ -1,8 +1,8 @@
package com.lanyuanxiaoyao.service.template.eq.controller; package com.lanyuanxiaoyao.service.template.database.eq.controller;
import com.lanyuanxiaoyao.service.template.eq.entity.Company; import com.lanyuanxiaoyao.service.template.database.eq.entity.Company;
import com.lanyuanxiaoyao.service.template.eq.entity.proxy.CompanyProxy; import com.lanyuanxiaoyao.service.template.database.eq.entity.proxy.CompanyProxy;
import com.lanyuanxiaoyao.service.template.eq.service.CompanyService; import com.lanyuanxiaoyao.service.template.database.eq.service.CompanyService;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.function.Function; import java.util.function.Function;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;

View File

@@ -0,0 +1,33 @@
package com.lanyuanxiaoyao.service.template.database.eq.entity;
import com.easy.query.core.annotation.EntityProxy;
import com.easy.query.core.annotation.Navigate;
import com.easy.query.core.annotation.Table;
import com.easy.query.core.enums.RelationTypeEnum;
import com.easy.query.core.proxy.ProxyEntityAvailable;
import com.lanyuanxiaoyao.service.template.database.eq.entity.proxy.CompanyProxy;
import java.util.List;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import lombok.experimental.FieldNameConstants;
@Getter
@Setter
@ToString(callSuper = true)
@FieldNameConstants
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Table
@EntityProxy
public class Company extends SimpleEntity implements ProxyEntityAvailable<Company, CompanyProxy> {
private String name;
private Integer members;
@Navigate(value = RelationTypeEnum.OneToMany, selfProperty = {"id"}, targetProperty = {"companyId"})
private List<Employee> employees;
}

View File

@@ -0,0 +1,33 @@
package com.lanyuanxiaoyao.service.template.database.eq.entity;
import com.easy.query.core.annotation.EntityProxy;
import com.easy.query.core.annotation.Navigate;
import com.easy.query.core.annotation.Table;
import com.easy.query.core.enums.RelationTypeEnum;
import com.easy.query.core.proxy.ProxyEntityAvailable;
import com.lanyuanxiaoyao.service.template.database.eq.entity.proxy.EmployeeProxy;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import lombok.experimental.FieldNameConstants;
@Getter
@Setter
@ToString(callSuper = true)
@FieldNameConstants
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Table
@EntityProxy
public class Employee extends SimpleEntity implements ProxyEntityAvailable<Employee, EmployeeProxy> {
private String name;
private Integer age;
private Long companyId;
@Navigate(value = RelationTypeEnum.OneToOne, selfProperty = {"companyId"}, targetProperty = {"id"})
private Company company;
}

View File

@@ -1,8 +1,8 @@
package com.lanyuanxiaoyao.service.template.eq.service; package com.lanyuanxiaoyao.service.template.database.eq.service;
import com.easy.query.api.proxy.client.EasyEntityQuery; import com.easy.query.api.proxy.client.EasyEntityQuery;
import com.lanyuanxiaoyao.service.template.eq.entity.Company; import com.lanyuanxiaoyao.service.template.database.eq.entity.Company;
import com.lanyuanxiaoyao.service.template.eq.entity.proxy.CompanyProxy; import com.lanyuanxiaoyao.service.template.database.eq.entity.proxy.CompanyProxy;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@Service @Service

View File

@@ -1,8 +1,8 @@
package com.lanyuanxiaoyao.service.template.eq.service; package com.lanyuanxiaoyao.service.template.database.eq.service;
import com.easy.query.api.proxy.client.EasyEntityQuery; import com.easy.query.api.proxy.client.EasyEntityQuery;
import com.lanyuanxiaoyao.service.template.eq.entity.Employee; import com.lanyuanxiaoyao.service.template.database.eq.entity.Employee;
import com.lanyuanxiaoyao.service.template.eq.entity.proxy.EmployeeProxy; import com.lanyuanxiaoyao.service.template.database.eq.entity.proxy.EmployeeProxy;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@Service @Service

View File

@@ -1,167 +0,0 @@
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(), "请求失败");
}
}

View File

@@ -1,21 +0,0 @@
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;
}

View File

@@ -1,21 +0,0 @@
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;
}

View File

@@ -1,8 +1,6 @@
server:
port: 2490
spring: spring:
application: profiles:
name: Test include: test
datasource: 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-database/spring-boot-service-template-database-eq/src/test/initial.sql'" 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-database/spring-boot-service-template-database-eq/src/test/initial.sql'"
username: test username: test
@@ -12,13 +10,4 @@ easy-query:
database: mysql database: mysql
name-conversion: underlined name-conversion: underlined
print-sql: false print-sql: false
decorator: print-nav-sql: false
datasource:
p6spy:
multiline: false
exclude-categories:
- commit
- result
- resultset
- rollback
log-format: "%(category)|%(executionTime)|%(sqlSingleLine)"