1. 简介

在很多以数据为核心的系统中,我们常常需要判断某个实体是否已经存在于数据库中。

本文将介绍几种在 Spring Data 和 JPA 中实现 exists 查询的方法,帮助你快速判断数据是否存在。

2. 示例实体

为了演示方便,我们先定义一个简单的实体类 Car,包含两个字段:modelpower

@Entity
public class Car {

    @Id
    @GeneratedValue
    private int id;

    private Integer power;
    private String model;
    
    // getters, setters, ...
}

3. 通过 ID 查询

JpaRepository 接口提供了一个 existsById 方法,可以快速判断某个 ID 是否存在于数据库中:

int searchId = 2; // 示例 Car 的 ID
boolean exists = repository.existsById(searchId);

⚠️ 注意: 除非是测试环境,否则不要硬编码 ID 值(如 2),因为 ID 通常由数据库自动生成,可能会变化。
existsById 是最简单直接的 exists 判断方式,但灵活性最差,仅适用于基于主键的查询。

4. 使用派生查询方法(Derived Query Method)

Spring Data 支持通过方法名自动推导出查询逻辑。例如,我们想判断是否存在某个 model 的 Car,可以定义如下方法:

boolean existsCarByModel(String model);

⚠️ 注意: 方法名必须符合 Spring Data 的命名规范,不能随意命名。IDE 如 IntelliJ 会提供自动补全支持。

当查询逻辑变得复杂时(比如多条件、排序、分页),这种命名方式可能会变得冗长甚至难以维护。
✅ 优点是代码简洁,适合逻辑简单的存在性判断。

5. 使用 Example 查询

Example 是一种动态查询方式,通过构建 ExampleMatcher 来灵活定义查询条件。适用于需要动态组合查询条件的场景。

5.1. 构建 Matcher

比如我们要进行忽略大小写的 model 匹配:

ExampleMatcher modelMatcher = ExampleMatcher.matching()
  .withIgnorePaths("id") 
  .withMatcher("model", ignoreCase());

⚠️ 注意: 要显式忽略 id 字段,否则默认会包含主键。

5.2. 构建 Probe 并执行查询

接下来构建一个“探针”对象,并执行查询:

Car probe = new Car();
probe.setModel("bmw");
Example<Car> example = Example.of(probe, modelMatcher);
boolean exists = repository.exists(example);

✅ Example 查询非常灵活,适合构建动态查询条件。
❌ 缺点是代码略显繁琐,适合在其他方式不适用时使用。

6. 使用自定义 JPQL 查询

如果你熟悉 JPQL 或 SQL,可以使用 @Query 注解编写自定义查询,实现 exists 语义:

@Query("select case when count(c) > 0 then true else false end from Car c where lower(c.model) like lower(:model)")
boolean existsCarLikeCustomQuery(@Param("model") String model);

这段 JPQL 的意思是:根据 model 字段进行模糊匹配(忽略大小写),如果存在记录则返回 true

✅ 自定义 JPQL 查询适合复杂查询逻辑,控制更精细。
❌ 缺点是需要维护 JPQL 语句,对不熟悉的人可能不够直观。

7. 总结

在 Spring Data 中判断某个实体是否存在,有多种方式可供选择:

方法 优点 缺点 适用场景
existsById 简单直接 灵活性差 判断主键是否存在
派生查询方法 无需写 SQL,IDE 支持 方法名易冗长 查询条件固定、简单
Example 查询 动态构建查询条件 代码略复杂 动态查询
自定义 JPQL 灵活、控制精细 需要维护 JPQL 复杂查询或模糊匹配

建议: 在实际开发中,优先选择简单、直观的方式。比如优先使用 existsById 或派生查询方法;当查询逻辑复杂时再考虑 Example 或自定义 JPQL。

统一风格,有助于团队协作和后期维护。


原始标题:The Exists Query in Spring Data | Baeldung