1
0

feat(jpa): 增加HQL查询实现对比

This commit is contained in:
2026-01-22 18:24:23 +08:00
parent 611988d7ab
commit f81217f14a

View File

@@ -191,6 +191,21 @@ public class TestApplication extends AbstractTestApplication {
);
Assert.isTrue(result1_querydsl.size() == 1, "基本比较操作符查询失败 %d".formatted(result1_querydsl.size()));
formatLog("1. 基本比较操作符查询 HQL");
var result1_hql = session.createQuery(
"""
from Employee employee
where employee.name = 'Bob'
and employee.role != com.lanyuanxiaoyao.service.template.database.jpa.entity.Employee.Role.ADMIN
and employee.age > 20
and employee.age < 30
and employee.salary >= 40000.00
and employee.salary <= 45000.00
""",
Employee.class
).list();
Assert.isTrue(result1_hql.size() == 1, "基本比较操作符查询失败 %d".formatted(result1_hql.size()));
formatLog("2. 区间和集合操作符查询 JPA");
// 查找年龄在25-30之间、年龄不在40-50之间、年龄在25/30/35中、角色是USER或ADMIN、姓名不在Charlie/David中的员工
var result2_jpa = employeeRepository.findAll((root, query, cb) -> cb.and(
@@ -225,6 +240,20 @@ public class TestApplication extends AbstractTestApplication {
);
Assert.isTrue(result2_querydsl.size() == 2, "区间和集合操作符查询失败 %d".formatted(result2_querydsl.size()));
formatLog("2. 区间和集合操作符查询 HQL");
var result2_hql = session.createQuery(
"""
from Employee employee
where employee.age between 25 and 30
and not (employee.age between 40 and 50)
and employee.age in (25, 30, 35)
and employee.role in (com.lanyuanxiaoyao.service.template.database.jpa.entity.Employee.Role.USER, com.lanyuanxiaoyao.service.template.database.jpa.entity.Employee.Role.ADMIN)
and employee.name not in ('Charlie', 'David')
""",
Employee.class
).list();
Assert.isTrue(result2_hql.size() == 2, "区间和集合操作符查询失败 %d".formatted(result2_hql.size()));
formatLog("3. 字符串操作符查询 JPA");
// 查找以A开头、不以C开头、包含"ali"忽略大小写、名称长度在4-10之间、前3个字符为"Ali"的员工
var result3_jpa = employeeRepository.findAll((root, query, cb) -> cb.and(
@@ -263,6 +292,22 @@ public class TestApplication extends AbstractTestApplication {
);
Assert.isTrue(result3_querydsl.size() == 1, "字符串操作符查询失败 %d".formatted(result3_querydsl.size()));
formatLog("3. 字符串操作符查询 HQL");
var result3_hql = session.createQuery(
"""
from Employee employee
where employee.name like 'A%'
and employee.name not like 'C%'
and lower(employee.name) like '%ali%'
and upper(employee.name) like '%ALI%'
and length(employee.name) > 4
and length(employee.name) <= 10
and substring(employee.name, 1, 3) = 'Ali'
""",
Employee.class
).list();
Assert.isTrue(result3_hql.size() == 1, "字符串操作符查询失败 %d".formatted(result3_hql.size()));
formatLog("4. NULL 和布尔操作符查询 JPA");
// 查找激活状态为true、bonus不为null、code不在E999中的员工
var result4_jpa = employeeRepository.findAll((root, query, cb) -> cb.and(
@@ -292,6 +337,18 @@ public class TestApplication extends AbstractTestApplication {
);
Assert.isTrue(!result4_querydsl.isEmpty(), "NULL 和布尔操作符查询失败 %d".formatted(result4_querydsl.size()));
formatLog("4. NULL 和布尔操作符查询 HQL");
var result4_hql = session.createQuery(
"""
from Employee employee
where employee.active is true
and employee.bonus is not null
and employee.code not in ('E999')
""",
Employee.class
).list();
Assert.isTrue(!result4_hql.isEmpty(), "NULL 和布尔操作符查询失败 %d".formatted(result4_hql.size()));
formatLog("5. 集合操作符查询 JPA");
// 查找技能集合非空、爱好集合非空、包含"Reading"爱好、不包含"Riding"爱好、爱好数量大于1、技能数量小于4的员工
var result5_jpa = employeeRepository.findAll((root, query, cb) -> cb.and(
@@ -322,6 +379,21 @@ public class TestApplication extends AbstractTestApplication {
);
Assert.isTrue(result5_querydsl.size() == 2, "集合操作符查询失败 %d".formatted(result5_querydsl.size()));
formatLog("5. 集合操作符查询 HQL");
var result5_hql = session.createQuery(
"""
from Employee employee
where employee.skills is not empty
and employee.hobbies is not empty
and 'Reading' member of employee.hobbies
and 'Riding' not member of employee.hobbies
and size(employee.hobbies) > 1
and size(employee.skills) < 4
""",
Employee.class
).list();
Assert.isTrue(result5_hql.size() == 2, "集合操作符查询失败 %d".formatted(result5_hql.size()));
formatLog("6. 逻辑操作符查询 JPA");
// 查找姓名为Alice或Bob、且姓名不为Charlie或David的员工
var result6_jpa = employeeRepository.findAll((root, query, cb) -> cb.and(
@@ -356,6 +428,17 @@ public class TestApplication extends AbstractTestApplication {
);
Assert.isTrue(result6_querydsl.size() == 2, "逻辑操作符查询失败 %d".formatted(result6_querydsl.size()));
formatLog("6. 逻辑操作符查询 HQL");
var result6_hql = session.createQuery(
"""
from Employee employee
where (employee.name = 'Alice' or employee.name = 'Bob')
and not (employee.name = 'Charlie' or employee.name = 'David')
""",
Employee.class
).list();
Assert.isTrue(result6_hql.size() == 2, "逻辑操作符查询失败 %d".formatted(result6_hql.size()));
formatLog("7. Specification 链式调用查询 JPA");
// 链式组合激活状态为true、年龄大于25、角色不是ADMIN、或姓名为Charlie、且姓名不为Alice Smith
var result7_jpa = employeeRepository.findAll(
@@ -388,6 +471,20 @@ public class TestApplication extends AbstractTestApplication {
);
Assert.isTrue(result7_querydsl.size() == 2, "Specification 链式调用失败 %d".formatted(result7_querydsl.size()));
formatLog("7. Specification 链式调用查询 HQL");
var result7_hql = session.createQuery(
"""
from Employee employee
where employee.active is true
and employee.age > 25
and employee.role != com.lanyuanxiaoyao.service.template.database.jpa.entity.Employee.Role.ADMIN
and employee.name != 'Alice Smith'
or employee.name = 'Charlie'
""",
Employee.class
).list();
Assert.isTrue(result7_hql.size() == 2, "Specification 链式调用失败 %d".formatted(result7_hql.size()));
formatLog("8. Join 操作查询 JPA");
// 查找公司名为TechCorp、技能包含Java、属性值为Senior的员工使用join、fetch、集合join、map join
var result8_jpa = employeeRepository.findAll((root, query, cb) -> {
@@ -426,6 +523,24 @@ public class TestApplication extends AbstractTestApplication {
);
Assert.isTrue(result8_querydsl.size() == 1, "Join 操作查询失败 %d".formatted(result8_querydsl.size()));
formatLog("8. Join 操作查询 HQL");
var result8_hql = session.createQuery(
"""
from Employee employee
join employee.company as company
join employee.skills as skill
join employee.properties as prop
where company.name = 'TechCorp'
and company.name != 'DataInc'
and skill.name = 'Java'
and skill.name != 'MySQL'
and value(prop) = 'Senior'
and value(prop) != 'Junior'
""",
Employee.class
).list();
Assert.isTrue(result8_hql.size() == 1, "Join 操作查询失败 %d".formatted(result8_hql.size()));
formatLog("9. 子查询和聚合函数查询 JPA");
// 查找薪资高于平均薪资、总记录数不为5、总薪酬在55000-70000之间、激活状态为true、姓名不为David、年龄大于28、角色不是USER的员工
var result9_jpa = employeeRepository.findAll((root, query, cb) -> {
@@ -478,6 +593,23 @@ public class TestApplication extends AbstractTestApplication {
);
Assert.isTrue(result9_querydsl.isEmpty(), "子查询(聚合函数)+ 数学运算失败 %d".formatted(result9_querydsl.size()));
formatLog("9. 子查询和聚合函数查询 HQL");
var result9_hql = session.createQuery(
"""
from Employee employee
where employee.salary > (select avg(e.salary) from Employee e)
and 5 <> (select count(e.id) from Employee e)
and employee.salary + coalesce(employee.bonus, 0.00) > 55000.00
and employee.salary + coalesce(employee.bonus, 0.00) < 70000.00
and employee.active is true
and employee.name != 'David'
and employee.age > 28
and employee.role != com.lanyuanxiaoyao.service.template.database.jpa.entity.Employee.Role.USER
""",
Employee.class
).list();
Assert.isTrue(result9_hql.isEmpty(), "子查询(聚合函数)+ 数学运算失败 %d".formatted(result9_hql.size()));
formatLog("10. 排序查询 JPA");
// 查找激活状态为true、角色不是ADMIN、年龄大于20、薪资小于60000的员工按年龄降序、姓名升序排序
var result10_jpa = employeeRepository.findAll(
@@ -521,6 +653,20 @@ public class TestApplication extends AbstractTestApplication {
);
Assert.isTrue(result10_querydsl.size() == 3, "排序查询失败 %d".formatted(result10_querydsl.size()));
formatLog("10. 排序查询 HQL");
var result10_hql = session.createQuery(
"""
from Employee employee
where employee.active is true
and employee.role != com.lanyuanxiaoyao.service.template.database.jpa.entity.Employee.Role.ADMIN
and employee.age > 20
and employee.salary < 60000.00
order by employee.age desc, employee.name asc
""",
Employee.class
).list();
Assert.isTrue(result10_hql.size() == 3, "排序查询失败 %d".formatted(result10_hql.size()));
formatLog("11. 分页查询 JPA");
// 分页查找激活状态为true、角色不是ADMIN、年龄大于20、薪资小于60000的员工每页2条按年龄排序
var page11_jpa = employeeRepository.findAll(
@@ -564,6 +710,31 @@ public class TestApplication extends AbstractTestApplication {
Assert.isTrue(page11_querydsl.getContent().size() == 2, "分页大小不正确 %d".formatted(page11_querydsl.getContent().size()));
Assert.isTrue(page11_querydsl.getTotalElements() == 3, "总元素数不正确 %d".formatted(page11_querydsl.getTotalElements()));
formatLog("11. 分页查询 HQL");
var page11_hql = session.createQuery(
"""
from Employee employee
where employee.active is true
and employee.role != com.lanyuanxiaoyao.service.template.database.jpa.entity.Employee.Role.ADMIN
and employee.age > 20
and employee.salary < 60000.00
order by employee.age
""",
Employee.class
).setFirstResult(0).setMaxResults(2).list();
var total11_hql = session.createQuery(
"""
from Employee employee
where employee.active is true
and employee.role != com.lanyuanxiaoyao.service.template.database.jpa.entity.Employee.Role.ADMIN
and employee.age > 20
and employee.salary < 60000.00
""",
Employee.class
).list().size();
Assert.isTrue(page11_hql.size() == 2, "分页大小不正确 %d".formatted(page11_hql.size()));
Assert.isTrue(total11_hql == 3, "总元素数不正确 %d".formatted(total11_hql));
formatLog("12. CASE WHEN 条件表达式查询 JPA");
// 查找年龄大于30Senior或年龄在25-30之间Middle的员工排除Junior级别的员工
var result12_jpa = employeeRepository.findAll((root, query, cb) -> cb.and(
@@ -618,6 +789,23 @@ public class TestApplication extends AbstractTestApplication {
);
Assert.isTrue(result12_querydsl.size() == 2, "CASE WHEN 查询失败 %d".formatted(result12_querydsl.size()));
formatLog("12. CASE WHEN 条件表达式查询 HQL");
var result12_hql = session.createQuery(
"""
from Employee employee
where (case when employee.age > 30 then 'Senior'
when employee.age between 25 and 30 then 'Middle'
else 'Junior'
end) = 'Senior'
and (case when employee.age > 30 then 'Senior'
when employee.age between 25 and 30 then 'Middle'
else 'Junior'
end) != 'Junior'
""",
Employee.class
).list();
Assert.isTrue(result12_hql.size() == 2, "CASE WHEN 查询失败 %d".formatted(result12_hql.size()));
formatLog("13. 综合多条件查询 JPA");
// 综合查询公司名为TechCorp、技能包含Java、城市为Beijing、技能和爱好非空、属性非空、创建和修改时间不为null、激活状态为true、姓名不为Alice Smith、年龄大于25、角色不是USER
var result13_jpa = employeeRepository.findAll((root, query, cb) -> {
@@ -685,6 +873,33 @@ public class TestApplication extends AbstractTestApplication {
);
Assert.isTrue(result13_querydsl.size() == 1 && result13_querydsl.get(0).getName().equals("Alice"), "综合多条件查询失败 %d".formatted(result13_querydsl.size()));
formatLog("13. 综合多条件查询 HQL");
var result13_hql = session.createQuery(
"""
select distinct employee
from Employee employee
join employee.company as company
join employee.skills as skill
where company.name = 'TechCorp'
and company.name != 'DataInc'
and skill.name = 'Java'
and skill.name != 'MySQL'
and employee.address.city = 'Beijing'
and employee.address.city != 'Shanghai'
and employee.skills is not empty
and employee.hobbies is not empty
and employee.properties is not empty
and employee.createdTime is not null
and employee.modifiedTime is not null
and employee.active is true
and employee.name != 'Alice Smith'
and employee.age > 25
and employee.role != com.lanyuanxiaoyao.service.template.database.jpa.entity.Employee.Role.USER
""",
Employee.class
).list();
Assert.isTrue(result13_hql.size() == 1 && result13_hql.get(0).getName().equals("Alice"), "综合多条件查询失败 %d".formatted(result13_hql.size()));
formatLog("清理测试数据");
employeeRepository.deleteAllInBatch();
companyRepository.deleteAllInBatch();