feat(database): 调整模块依赖创建test公共包
This commit is contained in:
29
pom.xml
29
pom.xml
@@ -12,6 +12,7 @@
|
||||
<modules>
|
||||
<module>spring-boot-service-template-common</module>
|
||||
<module>spring-boot-service-template-database/spring-boot-service-template-database-common</module>
|
||||
<module>spring-boot-service-template-database/spring-boot-service-template-database-common-test</module>
|
||||
<module>spring-boot-service-template-database/spring-boot-service-template-database-eq</module>
|
||||
<module>spring-boot-service-template-database/spring-boot-service-template-database-jpa</module>
|
||||
<module>spring-boot-service-template-database/spring-boot-service-template-database-xbatis</module>
|
||||
@@ -31,6 +32,8 @@
|
||||
<mapstruct-plus.version>1.5.0</mapstruct-plus.version>
|
||||
<datasource-decorator.version>2.0.0</datasource-decorator.version>
|
||||
<easy-query.version>3.1.68</easy-query.version>
|
||||
|
||||
<hutool.version>5.8.43</hutool.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
@@ -56,6 +59,11 @@
|
||||
<artifactId>spring-boot-service-template-database-common</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.lanyuanxiaoyao</groupId>
|
||||
<artifactId>spring-boot-service-template-database-common-test</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- spring boot 相关依赖 -->
|
||||
<dependency>
|
||||
@@ -129,6 +137,27 @@
|
||||
<artifactId>jspecify</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
<version>${hutool.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-core</artifactId>
|
||||
<version>${hutool.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-http</artifactId>
|
||||
<version>${hutool.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-json</artifactId>
|
||||
<version>${hutool.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
<?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-database-common-test</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-jdbc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mapstruct</groupId>
|
||||
<artifactId>mapstruct</artifactId>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.gavlyukovskiy</groupId>
|
||||
<artifactId>p6spy-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,228 @@
|
||||
package com.lanyuanxiaoyao.service.template.database.common.test;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import tools.jackson.databind.JsonNode;
|
||||
import tools.jackson.databind.ObjectMapper;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class AbstractTestApplication {
|
||||
private static final String BASE_URL = "http://localhost:2490";
|
||||
private static final RestTemplate REST_CLIENT = new RestTemplate();
|
||||
private static final ObjectMapper MAPPER = new ObjectMapper();
|
||||
private static final Random random = new Random();
|
||||
private static final String randomChars = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM";
|
||||
|
||||
private final JdbcTemplate template;
|
||||
|
||||
protected void testCrud() {
|
||||
var cid1 = saveItem("company", randomCompany("Apple")).get("data").asLong();
|
||||
var cid2 = saveItem("company", randomCompany()).get("data").asLong();
|
||||
var cid3 = saveItem("company", randomCompany()).get("data").asLong();
|
||||
|
||||
var companies1 = listItems("company");
|
||||
Assert.isTrue(companies1.at("/data/items").size() == 3, "数量错误");
|
||||
Assert.isTrue(companies1.at("/data/total").asLong() == 3, "返回数量错误");
|
||||
|
||||
var company1 = detailItem("company", cid1);
|
||||
Assert.isTrue(cid1 == company1.at("/data/id").asLong(), "id错误");
|
||||
Assert.isTrue(company1.at("/data/name").asString("").startsWith("Apple"), "name错误");
|
||||
|
||||
var company2 = detailItem("company", cid2);
|
||||
Assert.isTrue(cid2 == company2.at("/data/id").asLong(), "id错误");
|
||||
|
||||
var company3 = detailItem("company", cid3);
|
||||
Assert.isTrue(cid3 == company3.at("/data/id").asLong(), "id错误");
|
||||
|
||||
// language=JSON
|
||||
var pageRequest = """
|
||||
{
|
||||
"page": {
|
||||
"index": 1,
|
||||
"size": 2
|
||||
}
|
||||
}
|
||||
""";
|
||||
var companies2 = listItems("company", pageRequest);
|
||||
Assert.isTrue(companies2.at("/data/items").size() == 2, "数量错误");
|
||||
Assert.isTrue(companies2.at("/data/total").asLong() == 3, "返回数量错误");
|
||||
|
||||
// language=JSON
|
||||
var queryRequest = """
|
||||
{
|
||||
"query": {
|
||||
"notNullEqual": [
|
||||
"name"
|
||||
],
|
||||
"equal": {
|
||||
"name": "Apple"
|
||||
},
|
||||
"like": {
|
||||
"name": "Appl%"
|
||||
},
|
||||
"contain": {
|
||||
"name": "ple"
|
||||
},
|
||||
"startWith": {
|
||||
"name": "Appl"
|
||||
},
|
||||
"endWith": {
|
||||
"name": "le"
|
||||
},
|
||||
"less": {
|
||||
"members": 100
|
||||
},
|
||||
"greatEqual": {
|
||||
"members": 0,
|
||||
"createdTime": "2025-01-01 00:00:00"
|
||||
},
|
||||
"inside": {
|
||||
"name": [
|
||||
"Apple",
|
||||
"Banana"
|
||||
]
|
||||
},
|
||||
"between": {
|
||||
"members": {
|
||||
"start": 0,
|
||||
"end": 100
|
||||
}
|
||||
}
|
||||
},
|
||||
"page": {
|
||||
"index": 1,
|
||||
"size": 2
|
||||
}
|
||||
}
|
||||
""";
|
||||
var companies3 = listItems("company", queryRequest);
|
||||
Assert.isTrue(companies3.at("/data/items").size() == 1, "数量错误");
|
||||
Assert.isTrue(companies3.at("/data/total").asLong() == 1, "返回数量错误");
|
||||
|
||||
removeItem("company", cid1);
|
||||
Assert.isTrue(listItems("company").at("/data/items").size() == 2, "数量错误");
|
||||
Assert.isTrue(listItems("company").at("/data/total").asLong() == 2, "返回数量错误");
|
||||
removeItem("company", cid2);
|
||||
removeItem("company", cid3);
|
||||
Assert.isTrue(listItems("company").at("/data/items").isEmpty(), "数量错误");
|
||||
Assert.isTrue(listItems("company").at("/data/total").asLong() == 0, "返回数量错误");
|
||||
}
|
||||
|
||||
protected Map<String, Object> randomCompany() {
|
||||
return randomCompany(randomString(10));
|
||||
}
|
||||
|
||||
protected Map<String, Object> randomCompany(String name) {
|
||||
return Map.of(
|
||||
"name", name,
|
||||
"members", randomInt(100)
|
||||
);
|
||||
}
|
||||
|
||||
protected Map<String, Object> randomEmployee(Long companyId) {
|
||||
return randomEmployee(companyId, randomString(10));
|
||||
}
|
||||
|
||||
protected Map<String, Object> randomEmployee(Long companyId, String name) {
|
||||
return Map.of(
|
||||
"name", name,
|
||||
"age", randomInt(100),
|
||||
"companyId", companyId
|
||||
);
|
||||
}
|
||||
|
||||
protected Map<String, Object> randomReport(Long employeeId) {
|
||||
return Map.of(
|
||||
"score", randomDouble(200),
|
||||
"level", randomChar("ABCDE"),
|
||||
"employeeId", employeeId
|
||||
);
|
||||
}
|
||||
|
||||
private String randomString(String prefix, int length) {
|
||||
return prefix + randomString(length);
|
||||
}
|
||||
|
||||
private String randomString(int length) {
|
||||
var builder = new StringBuilder();
|
||||
for (int i = 0; i < length; i++) {
|
||||
builder.append(randomChars.charAt(random.nextInt(randomChars.length())));
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private String randomChar(String base) {
|
||||
return base.charAt(randomInt(base.length())) + "";
|
||||
}
|
||||
|
||||
private int randomInt(int bound) {
|
||||
return random.nextInt(1, bound);
|
||||
}
|
||||
|
||||
private double randomDouble(int bound) {
|
||||
return random.nextDouble(1, bound);
|
||||
}
|
||||
|
||||
protected HttpHeaders headers() {
|
||||
var headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||
return headers;
|
||||
}
|
||||
|
||||
protected JsonNode saveItem(String path, Object 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());
|
||||
}
|
||||
|
||||
protected 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());
|
||||
}
|
||||
|
||||
protected 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());
|
||||
}
|
||||
|
||||
protected 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());
|
||||
}
|
||||
|
||||
protected 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,14 @@
|
||||
package com.lanyuanxiaoyao.service.template.database.common.test.entity;
|
||||
|
||||
public enum Industry {
|
||||
TECHNOLOGY,
|
||||
FINANCE,
|
||||
MEDIA,
|
||||
SERVICE,
|
||||
GOVERNMENT,
|
||||
EDUCATION,
|
||||
HEALTHCARE,
|
||||
CONSTRUCTION,
|
||||
RETAIL,
|
||||
OTHER,
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.lanyuanxiaoyao.service.template.database.common.test.entity;
|
||||
|
||||
public enum Level {
|
||||
A, B, C, D, E
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
server:
|
||||
port: 2490
|
||||
decorator:
|
||||
datasource:
|
||||
p6spy:
|
||||
multiline: false
|
||||
exclude-categories:
|
||||
- commit
|
||||
- result
|
||||
- resultset
|
||||
- rollback
|
||||
log-format: "%(category)|%(executionTime)|%(sqlSingleLine)"
|
||||
@@ -16,16 +16,5 @@
|
||||
<groupId>com.lanyuanxiaoyao</groupId>
|
||||
<artifactId>spring-boot-service-template-common</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mapstruct</groupId>
|
||||
<artifactId>mapstruct</artifactId>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.gavlyukovskiy</groupId>
|
||||
<artifactId>p6spy-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -42,8 +42,8 @@
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<groupId>com.lanyuanxiaoyao</groupId>
|
||||
<artifactId>spring-boot-service-template-database-common-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package com.lanyuanxiaoyao.service.template.jpa.controller;
|
||||
package com.lanyuanxiaoyao.service.template.database.jpa.controller;
|
||||
|
||||
import com.lanyuanxiaoyao.service.template.common.helper.ObjectHelper;
|
||||
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.Query;
|
||||
import com.lanyuanxiaoyao.service.template.jpa.entity.SimpleEntity;
|
||||
import com.lanyuanxiaoyao.service.template.jpa.service.SimpleServiceSupport;
|
||||
import com.lanyuanxiaoyao.service.template.database.jpa.entity.SimpleEntity;
|
||||
import com.lanyuanxiaoyao.service.template.database.jpa.service.SimpleServiceSupport;
|
||||
import java.util.function.Function;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.lanyuanxiaoyao.service.template.jpa.entity;
|
||||
package com.lanyuanxiaoyao.service.template.database.jpa.entity;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.EntityListeners;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.lanyuanxiaoyao.service.template.jpa.entity;
|
||||
package com.lanyuanxiaoyao.service.template.database.jpa.entity;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.EntityListeners;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.lanyuanxiaoyao.service.template.jpa.entity;
|
||||
package com.lanyuanxiaoyao.service.template.database.jpa.entity;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.lanyuanxiaoyao.service.template.jpa.entity;
|
||||
package com.lanyuanxiaoyao.service.template.database.jpa.entity;
|
||||
|
||||
import com.lanyuanxiaoyao.service.template.database.common.helper.SnowflakeHelper;
|
||||
import java.io.Serializable;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.lanyuanxiaoyao.service.template.jpa.helper;
|
||||
package com.lanyuanxiaoyao.service.template.database.jpa.helper;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import java.io.IOException;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.lanyuanxiaoyao.service.template.jpa.repository;
|
||||
package com.lanyuanxiaoyao.service.template.database.jpa.repository;
|
||||
|
||||
import com.blinkfox.fenix.jpa.FenixJpaRepository;
|
||||
import com.blinkfox.fenix.specification.FenixJpaSpecificationExecutor;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.lanyuanxiaoyao.service.template.jpa.service;
|
||||
package com.lanyuanxiaoyao.service.template.database.jpa.service;
|
||||
|
||||
import com.lanyuanxiaoyao.service.template.common.helper.ObjectHelper;
|
||||
import com.lanyuanxiaoyao.service.template.database.common.entity.Page;
|
||||
@@ -9,9 +9,9 @@ import com.lanyuanxiaoyao.service.template.database.common.exception.NotComparab
|
||||
import com.lanyuanxiaoyao.service.template.database.common.exception.NotStringException;
|
||||
import com.lanyuanxiaoyao.service.template.database.common.service.QueryParser;
|
||||
import com.lanyuanxiaoyao.service.template.database.common.service.SimpleService;
|
||||
import com.lanyuanxiaoyao.service.template.jpa.entity.IdOnlyEntity;
|
||||
import com.lanyuanxiaoyao.service.template.jpa.entity.SimpleEntity;
|
||||
import com.lanyuanxiaoyao.service.template.jpa.repository.SimpleRepository;
|
||||
import com.lanyuanxiaoyao.service.template.database.jpa.entity.IdOnlyEntity;
|
||||
import com.lanyuanxiaoyao.service.template.database.jpa.entity.SimpleEntity;
|
||||
import com.lanyuanxiaoyao.service.template.database.jpa.repository.SimpleRepository;
|
||||
import jakarta.persistence.criteria.CriteriaBuilder;
|
||||
import jakarta.persistence.criteria.CriteriaQuery;
|
||||
import jakarta.persistence.criteria.Path;
|
||||
@@ -0,0 +1,121 @@
|
||||
package com.lanyuanxiaoyao.service.template.database.jpa;
|
||||
|
||||
import com.blinkfox.fenix.EnableFenix;
|
||||
import com.lanyuanxiaoyao.service.template.database.common.test.AbstractTestApplication;
|
||||
import com.lanyuanxiaoyao.service.template.database.common.test.entity.Industry;
|
||||
import com.lanyuanxiaoyao.service.template.database.jpa.entity.Company_;
|
||||
import com.lanyuanxiaoyao.service.template.database.jpa.entity.Employee;
|
||||
import com.lanyuanxiaoyao.service.template.database.jpa.entity.Employee_;
|
||||
import com.lanyuanxiaoyao.service.template.database.jpa.entity.QEmployee;
|
||||
import com.lanyuanxiaoyao.service.template.database.jpa.repository.EmployeeRepository;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
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.data.jpa.repository.config.EnableJpaAuditing;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@Slf4j
|
||||
@SpringBootApplication
|
||||
@EnableFenix
|
||||
@EnableJpaAuditing
|
||||
public class TestApplication extends AbstractTestApplication {
|
||||
private final EmployeeRepository employeeRepository;
|
||||
|
||||
public TestApplication(JdbcTemplate jdbcTemplate, EmployeeRepository employeeRepository) {
|
||||
super(jdbcTemplate);
|
||||
this.employeeRepository = employeeRepository;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(TestApplication.class, args);
|
||||
}
|
||||
|
||||
@EventListener(ApplicationReadyEvent.class)
|
||||
public void runTests() throws SQLException {
|
||||
testCrud();
|
||||
testSpecification();
|
||||
testNative();
|
||||
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
private void testSpecification() {
|
||||
// 增
|
||||
var cid1 = saveItem("company", randomCompany()).get("data").asLong();
|
||||
var cid2 = saveItem("company", randomCompany()).get("data").asLong();
|
||||
var cid3 = saveItem("company", randomCompany()).get("data").asLong();
|
||||
var eid1 = saveItem("employee", randomEmployee(cid1, "Tom")).get("data").asLong();
|
||||
var eid2 = saveItem("employee", randomEmployee(cid2)).get("data").asLong();
|
||||
var rid1 = saveItem("report", randomReport(eid1)).get("data").asLong();
|
||||
var rid2 = saveItem("report", randomReport(eid2)).get("data").asLong();
|
||||
|
||||
var employees1 = employeeRepository.findAll(
|
||||
builder -> builder
|
||||
.andIsNotNull(Employee.Fields.name)
|
||||
.andEquals(Employee.Fields.name, "Tom")
|
||||
.andLike(Employee.Fields.name, "To")
|
||||
.andStartsWith(Employee.Fields.name, "To")
|
||||
.andEndsWith(Employee.Fields.name, "om")
|
||||
.andLessThan(Employee.Fields.age, 200)
|
||||
.andGreaterThanEqual(Employee.Fields.age, 0)
|
||||
.andIn(Employee.Fields.name, List.of("Tom", "Mike"))
|
||||
.andBetween(Employee.Fields.age, 0, 200)
|
||||
.build()
|
||||
);
|
||||
Assert.isTrue(employees1.size() == 1, "查询数量错误");
|
||||
|
||||
var employees2 = employeeRepository.findAll(
|
||||
(root, query, builder) ->
|
||||
builder.and(
|
||||
builder.isNotNull(root.get(Employee_.name)),
|
||||
builder.equal(root.get(Employee_.name), "Tom"),
|
||||
builder.like(root.get(Employee_.name), "To%"),
|
||||
builder.lessThan(root.get(Employee_.age), 200),
|
||||
builder.greaterThanOrEqualTo(root.get(Employee_.age), 0),
|
||||
builder.in(root.get(Employee_.NAME)).value(List.of("Tom", "Mike")),
|
||||
builder.between(root.get(Employee_.age), 0, 200),
|
||||
builder.isNotEmpty(root.get(Employee_.company).get(Company_.employees)),
|
||||
builder.isNotMember(Industry.MEDIA, root.get(Employee_.company).get(Company_.industries))
|
||||
)
|
||||
);
|
||||
Assert.isTrue(employees2.size() == 1, "查询数量错误");
|
||||
|
||||
var employees3 = employeeRepository.findAll(
|
||||
QEmployee.employee.name.isNotNull()
|
||||
.and(QEmployee.employee.name.eq("Tom"))
|
||||
.and(QEmployee.employee.name.like("To%"))
|
||||
.and(QEmployee.employee.name.startsWith("To"))
|
||||
.and(QEmployee.employee.name.endsWith("om"))
|
||||
.and(QEmployee.employee.age.lt(200))
|
||||
.and(QEmployee.employee.age.goe(0))
|
||||
.and(QEmployee.employee.name.in("Tom", "Mike"))
|
||||
.and(QEmployee.employee.age.between(0, 200))
|
||||
.and(QEmployee.employee.company().employees.isNotEmpty())
|
||||
.and(QEmployee.employee.company().industries.contains(Industry.MEDIA).not())
|
||||
.and(QEmployee.employee.connections.containsKey(Employee.ConnectionType.EMAIL).not())
|
||||
);
|
||||
Assert.isTrue(employees3.size() == 1, "查询数量错误");
|
||||
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
private void testNative() {
|
||||
var cid1 = saveItem("company", randomCompany()).get("data").asLong();
|
||||
var cid2 = saveItem("company", randomCompany()).get("data").asLong();
|
||||
var cid3 = saveItem("company", randomCompany()).get("data").asLong();
|
||||
var eid1 = saveItem("employee", randomEmployee(cid1)).get("data").asLong();
|
||||
var eid2 = saveItem("employee", randomEmployee(cid2)).get("data").asLong();
|
||||
var eid3 = saveItem("employee", randomEmployee(cid3)).get("data").asLong();
|
||||
|
||||
var list = employeeRepository.findAllEmployeeWithCompanyName();
|
||||
Assert.isTrue(list.size() == 3, "数量错误");
|
||||
|
||||
var list_native = employeeRepository.findAllEmployeeWithCompanyNameNative();
|
||||
Assert.isTrue(list_native.size() == 3, "数量错误");
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.lanyuanxiaoyao.service.template.jpa.controller;
|
||||
package com.lanyuanxiaoyao.service.template.database.jpa.controller;
|
||||
|
||||
import com.lanyuanxiaoyao.service.template.jpa.entity.Company;
|
||||
import com.lanyuanxiaoyao.service.template.jpa.service.CompanyService;
|
||||
import com.lanyuanxiaoyao.service.template.database.jpa.entity.Company;
|
||||
import com.lanyuanxiaoyao.service.template.database.jpa.service.CompanyService;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.function.Function;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.lanyuanxiaoyao.service.template.jpa.controller;
|
||||
package com.lanyuanxiaoyao.service.template.database.jpa.controller;
|
||||
|
||||
import com.lanyuanxiaoyao.service.template.jpa.entity.Employee;
|
||||
import com.lanyuanxiaoyao.service.template.jpa.service.CompanyService;
|
||||
import com.lanyuanxiaoyao.service.template.jpa.service.EmployeeService;
|
||||
import com.lanyuanxiaoyao.service.template.database.jpa.entity.Employee;
|
||||
import com.lanyuanxiaoyao.service.template.database.jpa.service.CompanyService;
|
||||
import com.lanyuanxiaoyao.service.template.database.jpa.service.EmployeeService;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.function.Function;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
@@ -1,8 +1,9 @@
|
||||
package com.lanyuanxiaoyao.service.template.jpa.controller;
|
||||
package com.lanyuanxiaoyao.service.template.database.jpa.controller;
|
||||
|
||||
import com.lanyuanxiaoyao.service.template.jpa.entity.Report;
|
||||
import com.lanyuanxiaoyao.service.template.jpa.service.EmployeeService;
|
||||
import com.lanyuanxiaoyao.service.template.jpa.service.ReportService;
|
||||
import com.lanyuanxiaoyao.service.template.database.common.test.entity.Level;
|
||||
import com.lanyuanxiaoyao.service.template.database.jpa.entity.Report;
|
||||
import com.lanyuanxiaoyao.service.template.database.jpa.service.EmployeeService;
|
||||
import com.lanyuanxiaoyao.service.template.database.jpa.service.ReportService;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.function.Function;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
@@ -63,7 +64,7 @@ public class ReportController extends SimpleControllerSupport<Report, ReportCont
|
||||
public record SaveItem(
|
||||
Long id,
|
||||
Double score,
|
||||
Report.Level level,
|
||||
Level level,
|
||||
Long employeeId
|
||||
) {
|
||||
}
|
||||
@@ -73,7 +74,7 @@ public class ReportController extends SimpleControllerSupport<Report, ReportCont
|
||||
Long employeeId,
|
||||
String employeeName,
|
||||
Double score,
|
||||
Report.Level level
|
||||
Level level
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -82,7 +83,7 @@ public class ReportController extends SimpleControllerSupport<Report, ReportCont
|
||||
Long employeeId,
|
||||
String employeeName,
|
||||
Double score,
|
||||
Report.Level level,
|
||||
Level level,
|
||||
LocalDateTime createdTime,
|
||||
LocalDateTime modifiedTime
|
||||
) {
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.lanyuanxiaoyao.service.template.jpa.entity;
|
||||
package com.lanyuanxiaoyao.service.template.database.jpa.entity;
|
||||
|
||||
import com.lanyuanxiaoyao.service.template.database.common.test.entity.Industry;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.ConstraintMode;
|
||||
import jakarta.persistence.ElementCollection;
|
||||
@@ -47,17 +48,4 @@ public class Company extends SimpleEntity {
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(nullable = false)
|
||||
private Set<Industry> industries = new HashSet<>();
|
||||
|
||||
public enum Industry {
|
||||
TECHNOLOGY,
|
||||
FINANCE,
|
||||
MEDIA,
|
||||
SERVICE,
|
||||
GOVERNMENT,
|
||||
EDUCATION,
|
||||
HEALTHCARE,
|
||||
CONSTRUCTION,
|
||||
RETAIL,
|
||||
OTHER,
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.lanyuanxiaoyao.service.template.jpa.entity;
|
||||
package com.lanyuanxiaoyao.service.template.database.jpa.entity;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.ConstraintMode;
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.lanyuanxiaoyao.service.template.jpa.entity;
|
||||
package com.lanyuanxiaoyao.service.template.database.jpa.entity;
|
||||
|
||||
import com.lanyuanxiaoyao.service.template.database.common.test.entity.Level;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.EntityListeners;
|
||||
@@ -34,8 +35,4 @@ public class Report extends SimpleEntity {
|
||||
|
||||
@Column(nullable = false, comment = "员工 ID")
|
||||
private Long employeeId;
|
||||
|
||||
public enum Level {
|
||||
A, B, C, D, E
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.lanyuanxiaoyao.service.template.jpa.entity.vo;
|
||||
package com.lanyuanxiaoyao.service.template.database.jpa.entity.vo;
|
||||
|
||||
public record EmployeeWithCompanyName(
|
||||
String name,
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.lanyuanxiaoyao.service.template.database.jpa.repository;
|
||||
|
||||
import com.lanyuanxiaoyao.service.template.database.jpa.entity.Company;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface CompanyRepository extends SimpleRepository<Company> {
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.lanyuanxiaoyao.service.template.jpa.repository;
|
||||
package com.lanyuanxiaoyao.service.template.database.jpa.repository;
|
||||
|
||||
import com.lanyuanxiaoyao.service.template.jpa.entity.Employee;
|
||||
import com.lanyuanxiaoyao.service.template.jpa.entity.vo.EmployeeWithCompanyName;
|
||||
import com.lanyuanxiaoyao.service.template.database.jpa.entity.Employee;
|
||||
import com.lanyuanxiaoyao.service.template.database.jpa.entity.vo.EmployeeWithCompanyName;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
@@ -19,6 +19,6 @@ public interface EmployeeRepository extends SimpleRepository<Employee> {
|
||||
@Query(value = "select e.name, c.name, e.age, e.role from employee e, company c where e.company_id = c.id", nativeQuery = true)
|
||||
List<EmployeeWithCompanyName> findAllEmployeeWithCompanyNameNative();
|
||||
|
||||
@Query("select new com.lanyuanxiaoyao.service.template.jpa.entity.vo.EmployeeWithCompanyName(employee.name, employee.company.name, employee.age, cast(employee.role as string)) from Employee employee")
|
||||
@Query("select new com.lanyuanxiaoyao.service.template.database.jpa.entity.vo.EmployeeWithCompanyName(employee.name, employee.company.name, employee.age, cast(employee.role as string)) from Employee employee")
|
||||
List<EmployeeWithCompanyName> findAllEmployeeWithCompanyName();
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.lanyuanxiaoyao.service.template.database.jpa.repository;
|
||||
|
||||
import com.lanyuanxiaoyao.service.template.database.jpa.entity.Report;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface ReportRepository extends SimpleRepository<Report> {
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.lanyuanxiaoyao.service.template.database.jpa.service;
|
||||
|
||||
import com.lanyuanxiaoyao.service.template.database.jpa.entity.Company;
|
||||
import com.lanyuanxiaoyao.service.template.database.jpa.repository.CompanyRepository;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class CompanyService extends SimpleServiceSupport<Company> {
|
||||
public CompanyService(CompanyRepository repository) {
|
||||
super(repository);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.lanyuanxiaoyao.service.template.database.jpa.service;
|
||||
|
||||
import com.lanyuanxiaoyao.service.template.database.jpa.entity.Employee;
|
||||
import com.lanyuanxiaoyao.service.template.database.jpa.repository.EmployeeRepository;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class EmployeeService extends SimpleServiceSupport<Employee> {
|
||||
public EmployeeService(EmployeeRepository repository) {
|
||||
super(repository);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.lanyuanxiaoyao.service.template.database.jpa.service;
|
||||
|
||||
import com.lanyuanxiaoyao.service.template.database.jpa.entity.Report;
|
||||
import com.lanyuanxiaoyao.service.template.database.jpa.repository.ReportRepository;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class ReportService extends SimpleServiceSupport<Report> {
|
||||
public ReportService(ReportRepository repository) {
|
||||
super(repository);
|
||||
}
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
package com.lanyuanxiaoyao.service.template.jpa;
|
||||
|
||||
import com.lanyuanxiaoyao.service.template.jpa.helper.DatabaseHelper;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Helper测试类
|
||||
* 用于测试驼峰命名法转下划线命名法的功能
|
||||
*/
|
||||
@Slf4j
|
||||
public class HelperTest {
|
||||
|
||||
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
|
||||
// 通过反射调用Helper类中的private静态方法camelConvert
|
||||
var camelConvert = DatabaseHelper.class.getDeclaredMethod("camelConvert", String.class);
|
||||
camelConvert.setAccessible(true);
|
||||
|
||||
// 测试用例集合
|
||||
Map<String, String> testCases = new HashMap<>();
|
||||
|
||||
// 基本转换测试
|
||||
testCases.put("helloWorld", "hello_world");
|
||||
testCases.put("firstName", "first_name");
|
||||
testCases.put("lastName", "last_name");
|
||||
testCases.put("URL", "url");
|
||||
testCases.put("HTTPResponse", "http_response");
|
||||
testCases.put("XMLParser", "xml_parser");
|
||||
|
||||
// 边界情况测试
|
||||
testCases.put(null, null); // null输入
|
||||
testCases.put("", ""); // 空字符串
|
||||
testCases.put("a", "a"); // 单个小写字母
|
||||
testCases.put("A", "a"); // 单个大写字母
|
||||
testCases.put("aB", "a_b"); // 两个字符
|
||||
testCases.put("Ab", "ab"); // 首字母大写
|
||||
|
||||
// 数字相关测试
|
||||
testCases.put("field1Name", "field1_name");
|
||||
testCases.put("field12Name", "field12_name");
|
||||
testCases.put("2FARequired", "2_fa_required");
|
||||
testCases.put("ID", "id");
|
||||
testCases.put("userID", "user_id");
|
||||
testCases.put("HTML5Parser", "html5_parser");
|
||||
|
||||
// 连续大写字母测试
|
||||
testCases.put("HTTPSConnection", "https_connection");
|
||||
testCases.put("XMLHttpRequest", "xml_http_request");
|
||||
testCases.put("URLPath", "url_path");
|
||||
testCases.put("APIKey", "api_key");
|
||||
testCases.put("JWTToken", "jwt_token");
|
||||
|
||||
// 特殊场景测试
|
||||
testCases.put("iPhone", "i_phone"); // 以小写字母开头,后面有大写
|
||||
testCases.put("iOSVersion", "i_os_version"); // 连续小写字母后跟大写
|
||||
testCases.put("CAPTCHA", "captcha"); // 全大写字母缩写
|
||||
|
||||
log.info("开始执行驼峰命名转下划线命名测试...");
|
||||
|
||||
int passedTests = 0;
|
||||
int totalTests = testCases.size();
|
||||
|
||||
for (Map.Entry<String, String> testCase : testCases.entrySet()) {
|
||||
String input = testCase.getKey();
|
||||
String expected = testCase.getValue();
|
||||
String actual = (String) camelConvert.invoke(null, input);
|
||||
|
||||
try {
|
||||
Assert.isTrue(Objects.equals(expected, actual), "测试失败: 输入='%s', 期望='%s', 实际='%s'".formatted(input, expected, actual));
|
||||
passedTests++;
|
||||
log.info("✓ 测试通过: '{}' -> '{}'", input, actual);
|
||||
} catch (Exception e) {
|
||||
log.error("✗ {}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
log.info("测试结果: {}/{} 通过", passedTests, totalTests);
|
||||
if (passedTests == totalTests) {
|
||||
log.info("所有测试通过!✓");
|
||||
} else {
|
||||
log.error("有测试失败!✗");
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,302 +0,0 @@
|
||||
package com.lanyuanxiaoyao.service.template.jpa;
|
||||
|
||||
import com.blinkfox.fenix.EnableFenix;
|
||||
import com.lanyuanxiaoyao.service.template.jpa.entity.Company;
|
||||
import com.lanyuanxiaoyao.service.template.jpa.entity.Company_;
|
||||
import com.lanyuanxiaoyao.service.template.jpa.entity.Employee;
|
||||
import com.lanyuanxiaoyao.service.template.jpa.entity.Employee_;
|
||||
import com.lanyuanxiaoyao.service.template.jpa.entity.QEmployee;
|
||||
import com.lanyuanxiaoyao.service.template.jpa.entity.Report;
|
||||
import com.lanyuanxiaoyao.service.template.jpa.entity.Report_;
|
||||
import com.lanyuanxiaoyao.service.template.jpa.repository.EmployeeRepository;
|
||||
import jakarta.annotation.Resource;
|
||||
import java.util.List;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
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.data.jpa.repository.config.EnableJpaAuditing;
|
||||
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;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableFenix
|
||||
@EnableJpaAuditing
|
||||
public class TestApplication {
|
||||
private static final Logger log = LoggerFactory.getLogger(TestApplication.class);
|
||||
private static final String BASE_URL = "http://localhost:2490";
|
||||
private static final RestTemplate REST_CLIENT = new RestTemplate();
|
||||
private static final ObjectMapper MAPPER = new ObjectMapper();
|
||||
@Resource
|
||||
private EmployeeRepository employeeRepository;
|
||||
|
||||
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" +
|
||||
" \"between\": {\n" +
|
||||
" \"members\": {\n" +
|
||||
" \"start\": 0,\n" +
|
||||
" \"end\": 50\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").asText()), "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").asText()), "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());
|
||||
|
||||
var eid1 = saveItem("employee", "{\"name\": \"Tom\",\"age\": 18, \"companyId\": %d}".formatted(cid1)).get("data").asLong();
|
||||
var eid2 = saveItem("employee", "{\"name\": \"Jerry\",\"age\": 18, \"companyId\": %d}".formatted(cid1)).get("data").asLong();
|
||||
var eid3 = saveItem("employee", "{\"name\": \"Mike\",\"age\": 18, \"companyId\": %d}".formatted(cid2)).get("data").asLong();
|
||||
|
||||
var employees = listItems("employee");
|
||||
Assert.isTrue(employees.at("/data/items").size() == 3, "数量错误");
|
||||
Assert.isTrue(employees.at("/data/total").asLong() == 3, "返回数量错误");
|
||||
|
||||
var employee1 = detailItem("employee", eid1);
|
||||
Assert.isTrue(eid1 == employee1.at("/data/id").asLong(), "id错误");
|
||||
Assert.isTrue("Tom".equals(employee1.at("/data/name").asText()), "name错误");
|
||||
Assert.isTrue(18 == employee1.at("/data/age").asInt(), "age错误");
|
||||
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
@EventListener(ApplicationReadyEvent.class)
|
||||
public void runSpecificationTests() {
|
||||
// 增
|
||||
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 eid1 = saveItem("employee", "{\"name\": \"Tom\",\"age\": 18, \"companyId\": %d}".formatted(cid1)).get("data").asLong();
|
||||
var eid2 = saveItem("employee", "{\"name\": \"Jerry\",\"age\": 18, \"companyId\": %d}".formatted(cid1)).get("data").asLong();
|
||||
var eid3 = saveItem("employee", "{\"name\": \"Mike\",\"age\": 18, \"companyId\": %d}".formatted(cid2)).get("data").asLong();
|
||||
var rid = saveItem("report", "{\"employeeId\": %d, \"score\": 56.38, \"level\": \"A\"}".formatted(eid1)).get("data").asLong();
|
||||
var rid2 = saveItem("report", "{\"employeeId\": %d, \"score\": 78.98, \"level\": \"B\"}".formatted(eid2)).get("data").asLong();
|
||||
|
||||
log.debug(
|
||||
"Results: {}",
|
||||
employeeRepository.findAll(
|
||||
builder -> builder
|
||||
.andIsNotNull(Employee.Fields.name)
|
||||
.andEquals(Employee.Fields.name, "Tom")
|
||||
.andLike(Employee.Fields.name, "To%")
|
||||
.andStartsWith(Employee.Fields.name, "To")
|
||||
.andEndsWith(Employee.Fields.name, "om")
|
||||
.andLessThan(Employee.Fields.age, 50)
|
||||
.andGreaterThanEqual(Employee.Fields.age, 0)
|
||||
.andIn(Employee.Fields.name, List.of("Tom", "Mike"))
|
||||
.andBetween(Employee.Fields.age, 0, 50)
|
||||
.build()
|
||||
)
|
||||
);
|
||||
|
||||
log.debug(
|
||||
"Results: {}",
|
||||
employeeRepository.findAll(
|
||||
(root, query, builder) ->
|
||||
builder.and(
|
||||
builder.isNotNull(root.get(Employee_.name)),
|
||||
builder.equal(root.get(Employee_.name), "Tom"),
|
||||
builder.like(root.get(Employee_.name), "To%"),
|
||||
builder.lessThan(root.get(Employee_.age), 50),
|
||||
builder.greaterThanOrEqualTo(root.get(Employee_.age), 0),
|
||||
builder.in(root.get(Employee_.NAME)).value(List.of("Tom", "Mike")),
|
||||
builder.between(root.get(Employee_.age), 0, 50),
|
||||
builder.isNotEmpty(root.get(Employee_.company).get(Company_.employees)),
|
||||
builder.isMember(Company.Industry.MEDIA, root.get(Employee_.company).get(Company_.industries))
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
log.debug(
|
||||
"Results: {}",
|
||||
employeeRepository.findAll(
|
||||
QEmployee.employee.name.isNotNull()
|
||||
.and(QEmployee.employee.name.eq("Tom"))
|
||||
.and(QEmployee.employee.name.like("To%"))
|
||||
.and(QEmployee.employee.name.startsWith("To"))
|
||||
.and(QEmployee.employee.name.endsWith("om"))
|
||||
.and(QEmployee.employee.age.lt(50))
|
||||
.and(QEmployee.employee.age.goe(0))
|
||||
.and(QEmployee.employee.name.in("Tom", "Mike"))
|
||||
.and(QEmployee.employee.age.between(0, 50))
|
||||
.and(QEmployee.employee.company().employees.isNotEmpty())
|
||||
.and(QEmployee.employee.company().employees.any().name.ne("Tom"))
|
||||
.and(QEmployee.employee.company().industries.contains(Company.Industry.MEDIA))
|
||||
.and(QEmployee.employee.connections.containsKey(Employee.ConnectionType.EMAIL))
|
||||
)
|
||||
);
|
||||
|
||||
log.debug(
|
||||
"Results: {}",
|
||||
employeeRepository.findAll(
|
||||
(root, query, builder) -> {
|
||||
var reportRoot = query.from(Report.class);
|
||||
return builder.and(
|
||||
builder.equal(root.get(Employee_.id), reportRoot.get(Report_.employeeId)),
|
||||
builder.equal(reportRoot.get(Report_.level), Report.Level.A)
|
||||
);
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
@EventListener(ApplicationReadyEvent.class)
|
||||
public void runNativeQueryTests() {
|
||||
// 增
|
||||
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 eid1 = saveItem("employee", "{\"name\": \"Tom\",\"age\": 18, \"companyId\": %d}".formatted(cid1)).get("data").asLong();
|
||||
var eid2 = saveItem("employee", "{\"name\": \"Jerry\",\"age\": 18, \"companyId\": %d}".formatted(cid1)).get("data").asLong();
|
||||
var eid3 = saveItem("employee", "{\"name\": \"Mike\",\"age\": 18, \"companyId\": %d}".formatted(cid2)).get("data").asLong();
|
||||
|
||||
var list = employeeRepository.findAllEmployeeWithCompanyName();
|
||||
Assert.isTrue(list.size() == 3, "数量错误");
|
||||
log.debug("Results: {}", list);
|
||||
var list_native = employeeRepository.findAllEmployeeWithCompanyNameNative();
|
||||
Assert.isTrue(list_native.size() == 3, "数量错误");
|
||||
log.debug("Results: {}", list_native);
|
||||
}
|
||||
|
||||
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(), "请求失败");
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
package com.lanyuanxiaoyao.service.template.jpa.repository;
|
||||
|
||||
import com.lanyuanxiaoyao.service.template.jpa.entity.Company;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface CompanyRepository extends SimpleRepository<Company> {
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
package com.lanyuanxiaoyao.service.template.jpa.repository;
|
||||
|
||||
import com.lanyuanxiaoyao.service.template.jpa.entity.Report;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface ReportRepository extends SimpleRepository<Report> {
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
package com.lanyuanxiaoyao.service.template.jpa.service;
|
||||
|
||||
import com.lanyuanxiaoyao.service.template.jpa.entity.Company;
|
||||
import com.lanyuanxiaoyao.service.template.jpa.repository.CompanyRepository;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class CompanyService extends SimpleServiceSupport<Company> {
|
||||
public CompanyService(CompanyRepository repository) {
|
||||
super(repository);
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
package com.lanyuanxiaoyao.service.template.jpa.service;
|
||||
|
||||
import com.lanyuanxiaoyao.service.template.jpa.entity.Employee;
|
||||
import com.lanyuanxiaoyao.service.template.jpa.repository.EmployeeRepository;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class EmployeeService extends SimpleServiceSupport<Employee> {
|
||||
public EmployeeService(EmployeeRepository repository) {
|
||||
super(repository);
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
package com.lanyuanxiaoyao.service.template.jpa.service;
|
||||
|
||||
import com.lanyuanxiaoyao.service.template.jpa.entity.Report;
|
||||
import com.lanyuanxiaoyao.service.template.jpa.repository.ReportRepository;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class ReportService extends SimpleServiceSupport<Report> {
|
||||
public ReportService(ReportRepository repository) {
|
||||
super(repository);
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,6 @@
|
||||
server:
|
||||
port: 2490
|
||||
spring:
|
||||
application:
|
||||
name: Test
|
||||
profiles:
|
||||
include: test
|
||||
datasource:
|
||||
url: jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1
|
||||
username: test
|
||||
@@ -12,12 +10,3 @@ spring:
|
||||
generate-ddl: true
|
||||
fenix:
|
||||
print-banner: false
|
||||
decorator:
|
||||
datasource:
|
||||
p6spy:
|
||||
multiline: false
|
||||
exclude-categories:
|
||||
- commit
|
||||
- result
|
||||
- resultset
|
||||
log-format: "%(category)|%(executionTime)|%(sqlSingleLine)"
|
||||
|
||||
Reference in New Issue
Block a user