JPA,QueryDSL、MyBatisPlus.lambdaQuery 之间的关系以及区分度
为了更好的分辨代码DAO层具体用的什么框架,增加辨识度的笔记。(大部门来源GPT 自己只是做笔记)
MyBatis-Plus的lambdaQuery查询方式
lambdaQuery 是 MyBatis-Plus 框架中的一种查询方式,主要用于构建动态条件查询。它通过 Lambda 表达式 提供了更友好的 API,可以避免传统 MyBatis 中字符串拼接 SQL 的繁琐,同时提供类型安全的查询方式。
所属框架
框架: MyBatis-Plus
功能模块: 条件构造器(Wrapper)
优点
- 类型安全
使用 Lambda 表达式,字段名称通过方法引用来确定,避免手动拼接字符串引入的错误。 - 链式调用
支持流式 API,代码简洁易读。 - 动态查询
可根据条件动态添加查询逻辑,比如:
LambdaQueryWrapper<School> query = Wrappers.lambdaQuery();
if (someCondition) {
query.eq(School::getPhone, "123456");
}
List<School> result = schoolMapper.selectList(query);
总结
.lambdaQuery().eq() 是 MyBatis-Plus 的条件构造器 API,用于构建高效、简洁、类型安全的 SQL 查询。它在动态条件查询中尤其实用,是替代传统 XML 或注解拼接 SQL 的一种现代化方案。
JPA的链式调用查询
JPA 也支持类似于链式调用的查询方式,但它的实现和 MyBatis-Plus 有些不同。以下是 JPA 中实现链式调用查询的主要方式:
JPA 中链式调用的实现方式
通过 Specification 接口实现动态查询
使用 Spring Data JPA 时,可以通过 Specification 提供的动态条件查询来实现链式查询。
示例代码:
@Autowired
private SchoolRepository schoolRepository;
public List<School> queryWithSpecification(String name, String address) {
Specification<School> spec = (root, query, criteriaBuilder) -> {
List<Predicate> predicates = new ArrayList<>();
if (name != null) {
predicates.add(criteriaBuilder.equal(root.get("name"), name));
}
if (address != null) {
predicates.add(criteriaBuilder.like(root.get("address"), "%" + address + "%"));
}
return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
};
return schoolRepository.findAll(spec);
}
解释:
-
root.get(“fieldName”): 获取实体类对应字段。
-
criteriaBuilder: 构造查询条件(如 equal、like、greaterThan 等)。
-
predicates: 使用 List 动态添加条件,支持链式查询。
QueryDSL
QueryDSL(一种 JPA 的扩展库),则可以用链式 API 更优雅地构造查询条件。
示例代码:
@Autowired
private JPAQueryFactory queryFactory;
public List<School> queryWithQueryDSL(String name, String address) {
QSchool school = QSchool.school;
return queryFactory.selectFrom(school)
.where(
name != null ? school.name.eq(name) : null,
address != null ? school.address.like("%" + address + "%") : null
)
.fetch();
}
解释:
- QSchool 是由 QueryDSL 自动生成的实体类对应的查询对象。
- where 方法支持动态条件,条件为 null 时自动跳过。
- fetch() 获取结果列表。
JPA Stream 查询
通过 JPA Stream 查询(Spring Data JPA 的 Fluent API) 使用 Spring Data JPA 提供的 findBy...
方法,可以通过接口方法的链式调用实现简单查询。
示例代码: 定义 Repository 接口:
public interface SchoolRepository extends JpaRepository<School, Long> {
List<School> findByName(String name);
List<School> findByAddressContaining(String address);
List<School> findByNameAndAddressContaining(String name, String address);
}
@Autowired
private SchoolRepository schoolRepository;
public List<School> queryWithDerivedMethods(String name, String address) {
return schoolRepository.findByNameAndAddressContaining(name, address);
}
支持链式组合查询,如 findByNameAndAddressContaining
。
JPA 和 MyBatis-Plus 链式调用的对比
特性 | JPA (Spring Data + QueryDSL) | MyBatis-Plus |
---|---|---|
动态查询 | 使用 Specification 或 QueryDSL 实现 | 使用 Lambda 条件构造器 |
语法简洁性 | QueryDSL 更接近 MyBatis-Plus 的风格,但需要配置 | 简洁易用,开箱即用 |
代码生成支持 | QueryDSL 需要生成 Q 类 | 不需要额外生成类 |
类型安全 | 支持,通过 Criteria API 或 QueryDSL 实现 | Lambda 表达式支持类型安全 |
适用场景 | 面向复杂查询,适合用作标准化数据访问 | 更灵活的动态 SQL 生成 |
总结
JPA 的链式查询主要通过 Specification
和 QueryDSL 实现,功能类似于 MyBatis-Plus 的 lambdaQuery()
。虽然 JPA 的链式调用方式略显复杂,但它可以通过增强库(如 QueryDSL)实现更流畅的开发体验。