feat(jpa): 增加Fenix查询实现对比
This commit is contained in:
@@ -152,7 +152,7 @@ public class TestApplication extends AbstractTestApplication {
|
||||
|
||||
formatLog("1. 基本比较操作符查询 JPA");
|
||||
// 查找姓名为"Bob"、角色不是ADMIN、年龄在20-30之间、薪资在40000-45000之间的员工
|
||||
var result1 = employeeRepository.findAll((root, query, cb) -> cb.and(
|
||||
var result1_jpa = employeeRepository.findAll((root, query, cb) -> cb.and(
|
||||
cb.equal(root.get(Employee_.name), "Bob"),
|
||||
cb.notEqual(root.get(Employee_.role), Employee.Role.ADMIN),
|
||||
cb.greaterThan(root.get(Employee_.age), 20),
|
||||
@@ -160,7 +160,7 @@ public class TestApplication extends AbstractTestApplication {
|
||||
cb.greaterThanOrEqualTo(root.get(Employee_.salary), new BigDecimal("40000.00")),
|
||||
cb.lessThanOrEqualTo(root.get(Employee_.salary), new BigDecimal("45000.00"))
|
||||
));
|
||||
Assert.isTrue(result1.size() == 1, "基本比较操作符查询失败 (%d)".formatted(result1.size()));
|
||||
Assert.isTrue(result1_jpa.size() == 1, "基本比较操作符查询失败 (%d)".formatted(result1_jpa.size()));
|
||||
|
||||
formatLog("1. 基本比较操作符查询 Fenix");
|
||||
var result1_fenix = employeeRepository.findAll(
|
||||
@@ -172,11 +172,11 @@ public class TestApplication extends AbstractTestApplication {
|
||||
.andLessThanEqual(Employee.Fields.salary, new BigDecimal("45000.00"))
|
||||
.build()
|
||||
);
|
||||
Assert.isTrue(result1_fenix.size() == 1, "基本比较操作符查询失败 (%d)".formatted(result1.size()));
|
||||
Assert.isTrue(result1_fenix.size() == 1, "基本比较操作符查询失败 (%d)".formatted(result1_fenix.size()));
|
||||
|
||||
formatLog("2. 区间和集合操作符查询");
|
||||
formatLog("2. 区间和集合操作符查询 JPA");
|
||||
// 查找年龄在25-30之间、年龄不在40-50之间、年龄在25/30/35中、角色是USER或ADMIN、姓名不在Charlie/David中的员工
|
||||
var result2 = employeeRepository.findAll((root, query, cb) -> cb.and(
|
||||
var result2_jpa = employeeRepository.findAll((root, query, cb) -> cb.and(
|
||||
cb.between(root.get(Employee_.age), 25, 30),
|
||||
cb.between(root.get(Employee_.age), 40, 50).not(),
|
||||
root.get(Employee_.age).in(25, 30, 35),
|
||||
@@ -184,11 +184,22 @@ public class TestApplication extends AbstractTestApplication {
|
||||
cb.not(root.get(Employee_.name).in("Charlie", "David")),
|
||||
root.get(Employee_.name).in("Charlie", "David").not()
|
||||
));
|
||||
Assert.isTrue(result2.size() == 2, "区间和集合操作符查询失败 (%d)".formatted(result2.size()));
|
||||
Assert.isTrue(result2_jpa.size() == 2, "区间和集合操作符查询失败 (%d)".formatted(result2_jpa.size()));
|
||||
|
||||
formatLog("3. 字符串操作符查询");
|
||||
formatLog("2. 区间和集合操作符查询 Fenix");
|
||||
var result2_fenix = employeeRepository.findAll(
|
||||
builder -> builder.andBetween(Employee.Fields.age, 25, 30)
|
||||
.andNotBetween(Employee.Fields.age, 40, 50)
|
||||
.andIn(Employee.Fields.age, List.of(25, 30, 35))
|
||||
.andIn(Employee.Fields.role, List.of(Employee.Role.USER, Employee.Role.ADMIN))
|
||||
.andNotIn(Employee.Fields.name, List.of("Charlie", "David"))
|
||||
.build()
|
||||
);
|
||||
Assert.isTrue(result2_fenix.size() == 2, "区间和集合操作符查询失败 (%d)".formatted(result2_fenix.size()));
|
||||
|
||||
formatLog("3. 字符串操作符查询 JPA");
|
||||
// 查找以A开头、不以C开头、包含"ali"(忽略大小写)、名称长度在4-10之间、前3个字符为"Ali"的员工
|
||||
var result3 = employeeRepository.findAll((root, query, cb) -> cb.and(
|
||||
var result3_jpa = employeeRepository.findAll((root, query, cb) -> cb.and(
|
||||
cb.like(root.get(Employee_.name), "A%"),
|
||||
cb.notLike(root.get(Employee_.name), "C%"),
|
||||
cb.like(cb.lower(root.get(Employee_.name)), "%ali%"),
|
||||
@@ -197,21 +208,45 @@ public class TestApplication extends AbstractTestApplication {
|
||||
cb.lessThanOrEqualTo(cb.length(root.get(Employee_.name)), 10),
|
||||
cb.equal(cb.substring(root.get(Employee_.name), 0, 3), "Ali")
|
||||
));
|
||||
Assert.isTrue(result3.size() == 1, "字符串操作符查询失败 (%d)".formatted(result3.size()));
|
||||
Assert.isTrue(result3_jpa.size() == 1, "字符串操作符查询失败 (%d)".formatted(result3_jpa.size()));
|
||||
|
||||
formatLog("4. NULL 和布尔操作符查询");
|
||||
formatLog("3. 字符串操作符查询 Fenix");
|
||||
log.info("Fenix框架当前版本不支持以下字符串操作符:");
|
||||
log.info(" - cb.length() - 字符串长度函数");
|
||||
log.info(" - cb.substring() - 子字符串提取函数");
|
||||
log.info(" - cb.lower() / cb.upper() - 大小写转换函数 (不支持直接在条件中使用)");
|
||||
log.info("Fenix支持的部分实现:");
|
||||
var result3_fenix = employeeRepository.findAll(
|
||||
builder -> builder.andStartsWith(Employee.Fields.name, "A")
|
||||
.andNotStartsWith(Employee.Fields.name, "C")
|
||||
.build()
|
||||
);
|
||||
log.info("Fenix查询结果: {} 条记录(仅支持部分条件)", result3_fenix.size());
|
||||
|
||||
formatLog("4. NULL 和布尔操作符查询 JPA");
|
||||
// 查找激活状态为true、bonus不为null、code不在E999中的员工
|
||||
var result4 = employeeRepository.findAll((root, query, cb) -> cb.and(
|
||||
var result4_jpa = employeeRepository.findAll((root, query, cb) -> cb.and(
|
||||
cb.isTrue(root.get(Employee_.active)),
|
||||
cb.isFalse(cb.literal(false)),
|
||||
cb.isNotNull(root.get(Employee_.bonus)),
|
||||
cb.isNull(root.get(Employee_.code).in("E999"))
|
||||
cb.not(root.get(Employee_.code).in("E999"))
|
||||
));
|
||||
Assert.isTrue(result4.isEmpty(), "NULL 和布尔操作符查询失败 (%d)".formatted(result4.size()));
|
||||
Assert.isTrue(!result4_jpa.isEmpty(), "NULL 和布尔操作符查询失败 (%d)".formatted(result4_jpa.size()));
|
||||
|
||||
formatLog("5. 集合操作符查询");
|
||||
formatLog("4. NULL 和布尔操作符查询 Fenix");
|
||||
log.info("Fenix框架当前版本不支持以下布尔操作符:");
|
||||
log.info(" - cb.isTrue() / cb.isFalse() - 专用布尔判断函数");
|
||||
log.info("Fenix通过equals/notEquals处理布尔字段");
|
||||
var result4_fenix = employeeRepository.findAll(
|
||||
builder -> builder.andEquals(Employee.Fields.active, true)
|
||||
.andIsNotNull(Employee.Fields.bonus)
|
||||
.andNotIn(Employee.Fields.code, List.of("E999"))
|
||||
.build()
|
||||
);
|
||||
Assert.isTrue(!result4_fenix.isEmpty(), "NULL 和布尔操作符查询失败 (%d)".formatted(result4_fenix.size()));
|
||||
|
||||
formatLog("5. 集合操作符查询 JPA");
|
||||
// 查找技能集合非空、爱好集合非空、包含"Reading"爱好、不包含"Riding"爱好、爱好数量大于1、技能数量小于4的员工
|
||||
var result5 = employeeRepository.findAll((root, query, cb) -> cb.and(
|
||||
var result5_jpa = employeeRepository.findAll((root, query, cb) -> cb.and(
|
||||
cb.isNotEmpty(root.get(Employee_.skills)),
|
||||
cb.isEmpty(root.get(Employee_.hobbies)).not(),
|
||||
cb.isMember("Reading", root.get(Employee_.hobbies)),
|
||||
@@ -219,11 +254,18 @@ public class TestApplication extends AbstractTestApplication {
|
||||
cb.greaterThan(cb.size(root.get(Employee_.hobbies)), 1),
|
||||
cb.lessThan(cb.size(root.get(Employee_.skills)), 4)
|
||||
));
|
||||
Assert.isTrue(result5.size() == 2, "集合操作符查询失败 (%d)".formatted(result5.size()));
|
||||
Assert.isTrue(result5_jpa.size() == 2, "集合操作符查询失败 (%d)".formatted(result5_jpa.size()));
|
||||
|
||||
formatLog("6. 逻辑操作符查询");
|
||||
formatLog("5. 集合操作符查询 Fenix");
|
||||
log.info("Fenix框架当前版本不支持以下集合操作符:");
|
||||
log.info(" - cb.isNotEmpty() / cb.isEmpty() - 集合非空/空判断");
|
||||
log.info(" - cb.isMember() / cb.isNotMember() - 集合成员判断");
|
||||
log.info(" - cb.size() - 集合大小函数");
|
||||
log.info("这些集合操作在JPA Criteria中需要复杂的join处理,Fenix当前不支持");
|
||||
|
||||
formatLog("6. 逻辑操作符查询 JPA");
|
||||
// 查找姓名为Alice或Bob、且姓名不为Charlie或David的员工
|
||||
var result6 = employeeRepository.findAll((root, query, cb) -> cb.and(
|
||||
var result6_jpa = employeeRepository.findAll((root, query, cb) -> cb.and(
|
||||
cb.or(
|
||||
cb.equal(root.get(Employee_.name), "Alice"),
|
||||
cb.equal(root.get(Employee_.name), "Bob")
|
||||
@@ -235,22 +277,46 @@ public class TestApplication extends AbstractTestApplication {
|
||||
)
|
||||
)
|
||||
));
|
||||
Assert.isTrue(result6.size() == 2, "逻辑操作符查询失败 (%d)".formatted(result6.size()));
|
||||
Assert.isTrue(result6_jpa.size() == 2, "逻辑操作符查询失败 (%d)".formatted(result6_jpa.size()));
|
||||
|
||||
formatLog("7. Specification 链式调用查询");
|
||||
formatLog("6. 逻辑操作符查询 Fenix");
|
||||
log.info("Fenix框架当前版本不支持复杂的嵌套OR和NOT组合逻辑");
|
||||
log.info("Fenix支持简单的orEquals,但不支持嵌套的or + not组合");
|
||||
var result6_fenix = employeeRepository.findAll(
|
||||
builder -> builder.orEquals(Employee.Fields.name, "Alice")
|
||||
.orEquals(Employee.Fields.name, "Bob")
|
||||
.andNotIn(Employee.Fields.name, List.of("Charlie", "David"))
|
||||
.build()
|
||||
);
|
||||
Assert.isTrue(result6_fenix.size() == 3, "逻辑操作符查询失败 (%d)".formatted(result6_fenix.size()));
|
||||
|
||||
formatLog("7. Specification 链式调用查询 JPA");
|
||||
// 链式组合:激活状态为true、年龄大于25、角色不是ADMIN、或姓名为Charlie、且姓名不为Alice Smith
|
||||
var result7 = employeeRepository.findAll(
|
||||
var result7_jpa = employeeRepository.findAll(
|
||||
Specification.<Employee>where((root, query, cb) -> cb.isTrue(root.get(Employee_.active)))
|
||||
.and((root, query, cb) -> cb.greaterThan(root.get(Employee_.age), 25))
|
||||
.and((root, query, cb) -> cb.notEqual(root.get(Employee_.role), Employee.Role.ADMIN))
|
||||
.or((root, query, cb) -> cb.equal(root.get(Employee_.name), "Charlie"))
|
||||
.and((root, query, cb) -> cb.notEqual(root.get(Employee_.name), "Alice Smith"))
|
||||
);
|
||||
Assert.isTrue(result7.size() == 2, "Specification 链式调用失败 (%d)".formatted(result7.size()));
|
||||
Assert.isTrue(result7_jpa.size() == 2, "Specification 链式调用失败 (%d)".formatted(result7_jpa.size()));
|
||||
|
||||
formatLog("8. Join 操作查询");
|
||||
formatLog("7. Specification 链式调用查询 Fenix");
|
||||
log.info("Fenix框架使用builder链式调用,类似JPA Specification链式调用");
|
||||
log.info("Fenix builder天然支持链式调用,每个方法返回builder本身");
|
||||
var result7_fenix = employeeRepository.findAll(
|
||||
builder -> builder.andEquals(Employee.Fields.active, true)
|
||||
.andGreaterThan(Employee.Fields.age, 25)
|
||||
.andNotEquals(Employee.Fields.role, Employee.Role.ADMIN)
|
||||
.orEquals(Employee.Fields.name, "Charlie")
|
||||
.andNotEquals(Employee.Fields.name, "Alice Smith")
|
||||
.build()
|
||||
);
|
||||
Assert.isTrue(result7_fenix.size() == 2, "Specification 链式调用失败 (%d)".formatted(result7_fenix.size()));
|
||||
|
||||
formatLog("8. Join 操作查询 JPA");
|
||||
// 查找公司名为TechCorp、技能包含Java、属性值为Senior的员工(使用join、fetch、集合join、map join)
|
||||
var result8 = employeeRepository.findAll((root, query, cb) -> {
|
||||
var result8_jpa = employeeRepository.findAll((root, query, cb) -> {
|
||||
root.fetch(Employee_.company);
|
||||
query.distinct(true);
|
||||
return cb.and(
|
||||
@@ -265,11 +331,21 @@ public class TestApplication extends AbstractTestApplication {
|
||||
cb.notEqual(root.join(Employee_.properties).value(), "Junior")
|
||||
);
|
||||
});
|
||||
Assert.isTrue(result8.size() == 1, "Join 操作查询失败 (%d)".formatted(result8.size()));
|
||||
Assert.isTrue(result8_jpa.size() == 1, "Join 操作查询失败 (%d)".formatted(result8_jpa.size()));
|
||||
|
||||
formatLog("9. 子查询和聚合函数查询");
|
||||
formatLog("8. Join 操作查询 Fenix");
|
||||
log.info("Fenix框架当前版本不支持显式的join操作:");
|
||||
log.info(" - root.join() - 显式关联查询");
|
||||
log.info(" - root.fetch() - 显式抓取查询");
|
||||
log.info(" - Map join (cb.equal(root.join().value(), ...))");
|
||||
log.info("Fenix主要用于单表条件查询,复杂join操作建议使用JPA Specification原生方式或QueryDSL");
|
||||
log.info("可以通过doAny使用原生CriteriaBuilder实现join操作");
|
||||
log.info("注意:由于类型系统的限制,doAny中使用join可能会有类型推断问题");
|
||||
log.info("建议:对于join等复杂查询,直接使用JPA Specification原生方式");
|
||||
|
||||
formatLog("9. 子查询和聚合函数查询 JPA");
|
||||
// 查找薪资高于平均薪资、总记录数不为5、总薪酬在55000-70000之间、激活状态为true、姓名不为David、年龄大于28、角色不是USER的员工
|
||||
var result9 = employeeRepository.findAll((root, query, cb) -> {
|
||||
var result9_jpa = employeeRepository.findAll((root, query, cb) -> {
|
||||
var avgSalarySubquery = query.subquery(Double.class);
|
||||
var avgSubRoot = avgSalarySubquery.from(Employee.class);
|
||||
avgSalarySubquery.select(cb.avg(avgSubRoot.get(Employee_.salary)));
|
||||
@@ -293,11 +369,20 @@ public class TestApplication extends AbstractTestApplication {
|
||||
cb.notEqual(root.get(Employee_.role), Employee.Role.USER)
|
||||
);
|
||||
});
|
||||
Assert.isTrue(result9.isEmpty(), "子查询(聚合函数)+ 数学运算失败 (%d)".formatted(result9.size()));
|
||||
Assert.isTrue(result9_jpa.isEmpty(), "子查询(聚合函数)+ 数学运算失败 (%d)".formatted(result9_jpa.size()));
|
||||
|
||||
formatLog("10. 排序查询");
|
||||
formatLog("9. 子查询和聚合函数查询 Fenix");
|
||||
log.info("Fenix框架当前版本不支持以下高级查询特性:");
|
||||
log.info(" - query.subquery() - 子查询");
|
||||
log.info(" - cb.avg(), cb.count(), cb.sum() - 聚合函数");
|
||||
log.info(" - cb.coalesce() - 空值替换函数");
|
||||
log.info(" - cb.sum() - 数值加法运算");
|
||||
log.info("这些是SQL级别的复杂查询,Fenix主要用于动态条件构建");
|
||||
log.info("可以通过doAny使用原生CriteriaBuilder实现部分聚合操作");
|
||||
|
||||
formatLog("10. 排序查询 JPA");
|
||||
// 查找激活状态为true、角色不是ADMIN、年龄大于20、薪资小于60000的员工,按年龄降序、姓名升序排序
|
||||
var result10 = employeeRepository.findAll(
|
||||
var result10_jpa = employeeRepository.findAll(
|
||||
(root, query, cb) -> cb.and(
|
||||
cb.isTrue(root.get(Employee_.active)),
|
||||
cb.notEqual(root.get(Employee_.role), Employee.Role.ADMIN),
|
||||
@@ -309,11 +394,27 @@ public class TestApplication extends AbstractTestApplication {
|
||||
Sort.Order.asc(Employee_.NAME)
|
||||
)
|
||||
);
|
||||
Assert.isTrue(result10.size() == 3 && result10.get(0).getAge() >= result10.get(1).getAge(), "排序查询失败 (%d)".formatted(result10.size()));
|
||||
Assert.isTrue(result10_jpa.size() == 3 && result10_jpa.get(0).getAge() >= result10_jpa.get(1).getAge(), "排序查询失败 (%d)".formatted(result10_jpa.size()));
|
||||
|
||||
formatLog("11. 分页查询");
|
||||
formatLog("10. 排序查询 Fenix");
|
||||
log.info("Fenix框架使用Spring Data JPA原生的Sort对象进行排序");
|
||||
log.info("Fenix构建查询条件,Sort对象通过repository.findAll()的第二个参数传入");
|
||||
var result10_fenix = employeeRepository.findAll(
|
||||
builder -> builder.andEquals(Employee.Fields.active, true)
|
||||
.andNotEquals(Employee.Fields.role, Employee.Role.ADMIN)
|
||||
.andGreaterThan(Employee.Fields.age, 20)
|
||||
.andLessThan(Employee.Fields.salary, new BigDecimal("60000.00"))
|
||||
.build(),
|
||||
Sort.by(
|
||||
Sort.Order.desc(Employee.Fields.age),
|
||||
Sort.Order.asc(Employee.Fields.name)
|
||||
)
|
||||
);
|
||||
Assert.isTrue(result10_fenix.size() == 3 && result10_fenix.get(0).getAge() >= result10_fenix.get(1).getAge(), "排序查询失败 (%d)".formatted(result10_fenix.size()));
|
||||
|
||||
formatLog("11. 分页查询 JPA");
|
||||
// 分页查找激活状态为true、角色不是ADMIN、年龄大于20、薪资小于60000的员工,每页2条,按年龄排序
|
||||
var page11 = employeeRepository.findAll(
|
||||
var page11_jpa = employeeRepository.findAll(
|
||||
(root, query, cb) -> cb.and(
|
||||
cb.isTrue(root.get(Employee_.active)),
|
||||
cb.notEqual(root.get(Employee_.role), Employee.Role.ADMIN),
|
||||
@@ -322,12 +423,26 @@ public class TestApplication extends AbstractTestApplication {
|
||||
),
|
||||
org.springframework.data.domain.PageRequest.of(0, 2, Sort.by(Employee_.AGE))
|
||||
);
|
||||
Assert.isTrue(page11.getContent().size() == 2, "分页大小不正确 (%d)".formatted(page11.getContent().size()));
|
||||
Assert.isTrue(page11.getTotalElements() == 3, "总元素数不正确 (%d)".formatted(page11.getTotalElements()));
|
||||
Assert.isTrue(page11_jpa.getContent().size() == 2, "分页大小不正确 (%d)".formatted(page11_jpa.getContent().size()));
|
||||
Assert.isTrue(page11_jpa.getTotalElements() == 3, "总元素数不正确 (%d)".formatted(page11_jpa.getTotalElements()));
|
||||
|
||||
formatLog("12. CASE WHEN 条件表达式查询");
|
||||
formatLog("11. 分页查询 Fenix");
|
||||
log.info("Fenix框架使用Spring Data JPA原生的Pageable对象进行分页");
|
||||
log.info("Fenix构建查询条件,Pageable对象通过repository.findAll()的第二个参数传入");
|
||||
var page11_fenix = employeeRepository.findAll(
|
||||
builder -> builder.andEquals(Employee.Fields.active, true)
|
||||
.andNotEquals(Employee.Fields.role, Employee.Role.ADMIN)
|
||||
.andGreaterThan(Employee.Fields.age, 20)
|
||||
.andLessThan(Employee.Fields.salary, new BigDecimal("60000.00"))
|
||||
.build(),
|
||||
org.springframework.data.domain.PageRequest.of(0, 2, Sort.by(Employee.Fields.age))
|
||||
);
|
||||
Assert.isTrue(page11_fenix.getContent().size() == 2, "分页大小不正确 (%d)".formatted(page11_fenix.getContent().size()));
|
||||
Assert.isTrue(page11_fenix.getTotalElements() == 3, "总元素数不正确 (%d)".formatted(page11_fenix.getTotalElements()));
|
||||
|
||||
formatLog("12. CASE WHEN 条件表达式查询 JPA");
|
||||
// 查找年龄大于30(Senior)或年龄在25-30之间(Middle)的员工,排除Junior级别的员工
|
||||
var result12 = employeeRepository.findAll((root, query, cb) -> cb.and(
|
||||
var result12_jpa = employeeRepository.findAll((root, query, cb) -> cb.and(
|
||||
cb.equal(
|
||||
cb.selectCase()
|
||||
.when(cb.greaterThan(root.get(Employee_.age), 30), "Senior")
|
||||
@@ -343,11 +458,35 @@ public class TestApplication extends AbstractTestApplication {
|
||||
"Junior"
|
||||
)
|
||||
));
|
||||
Assert.isTrue(result12.size() == 2, "CASE WHEN 查询失败 (%d)".formatted(result12.size()));
|
||||
Assert.isTrue(result12_jpa.size() == 2, "CASE WHEN 查询失败 (%d)".formatted(result12_jpa.size()));
|
||||
|
||||
formatLog("13. 综合多条件查询");
|
||||
formatLog("12. CASE WHEN 条件表达式查询 Fenix");
|
||||
log.info("Fenix框架当前版本不支持CASE WHEN条件表达式:");
|
||||
log.info(" - cb.selectCase() - SQL CASE WHEN表达式");
|
||||
log.info(" - .when() - CASE WHEN条件分支");
|
||||
log.info(" - .otherwise() - CASE ELSE分支");
|
||||
log.info("CASE WHEN是SQL级别的条件表达式,Fenix主要用于动态条件构建");
|
||||
log.info("可以通过doAny使用原生CriteriaBuilder实现CASE WHEN操作");
|
||||
log.info("注意:由于类型系统的限制,doAny中使用CriteriaBuilder的复杂表达式可能会有类型推断问题");
|
||||
log.info("建议:对于CASE WHEN等复杂查询,直接使用JPA Specification原生方式");
|
||||
var result12_fenix = employeeRepository.findAll(builder -> {
|
||||
return builder.doAny(null, null, (cb, root, fieldName, value) -> {
|
||||
// 使用原生JPA Criteria实现CASE WHEN(简化版本)
|
||||
var caseExpr = cb.selectCase()
|
||||
.when(cb.greaterThan(root.get("age"), 30), "Senior")
|
||||
.when(cb.between(root.get("age"), 25, 30), "Middle")
|
||||
.otherwise("Junior");
|
||||
return cb.and(
|
||||
cb.equal(caseExpr, "Senior"),
|
||||
cb.notEqual(caseExpr, "Junior")
|
||||
);
|
||||
}).build();
|
||||
});
|
||||
Assert.isTrue(result12_fenix.size() == 2, "CASE WHEN 查询失败 (%d)".formatted(result12_fenix.size()));
|
||||
|
||||
formatLog("13. 综合多条件查询 JPA");
|
||||
// 综合查询:公司名为TechCorp、技能包含Java、城市为Beijing、技能和爱好非空、属性非空、创建和修改时间不为null、激活状态为true、姓名不为Alice Smith、年龄大于25、角色不是USER
|
||||
var result13 = employeeRepository.findAll((root, query, cb) -> {
|
||||
var result13_jpa = employeeRepository.findAll((root, query, cb) -> {
|
||||
query.distinct(true);
|
||||
return cb.and(
|
||||
// Company Join 条件
|
||||
@@ -374,7 +513,16 @@ public class TestApplication extends AbstractTestApplication {
|
||||
cb.notEqual(root.get(Employee_.role), Employee.Role.USER)
|
||||
);
|
||||
});
|
||||
Assert.isTrue(result13.size() == 1 && result13.get(0).getName().equals("Alice"), "综合多条件查询失败 (%d)".formatted(result13.size()));
|
||||
Assert.isTrue(result13_jpa.size() == 1 && result13_jpa.get(0).getName().equals("Alice"), "综合多条件查询失败 (%d)".formatted(result13_jpa.size()));
|
||||
|
||||
formatLog("13. 综合多条件查询 Fenix");
|
||||
log.info("Fenix框架不支持综合多条件查询中的复杂join和集合操作:");
|
||||
log.info(" - 显式join操作(company, skills, properties)");
|
||||
log.info(" - 集合isEmpty/isNotEmpty/isMember操作");
|
||||
log.info(" - Map join操作");
|
||||
log.info(" - 嵌入式对象查询(address.city)");
|
||||
log.info("Fenix主要支持简单的单表字段查询");
|
||||
log.info("可以通过doAny使用原生CriteriaBuilder实现复杂综合查询");
|
||||
|
||||
formatLog("清理测试数据");
|
||||
employeeRepository.deleteAllInBatch();
|
||||
|
||||
Reference in New Issue
Block a user