Spring Data JPA基本方法调用规律
一、命名规则核心逻辑
派生方法名由三部分组成:findBy + 属性名 + 条件
,其中:
- 前缀(固定关键词):
findBy
、deleteBy
、countBy
、existsBy
等。 - 属性名:实体类的字段名(需严格匹配驼峰命名)。
- 条件:可选,如
GreaterThan
、LessThan
、Like
等。
示例:
// 方法名 = 前缀 + 属性名 + 条件
List<User> findByAgeGreaterThan(int age); // 查询年龄大于 age 的用户
二、常见前缀与用途
前缀 | 用途 | 返回值类型 |
---|---|---|
findBy | 查询符合条件的记录 | List<T> 、Optional<T> |
deleteBy | 删除符合条件的记录 | long (删除数量) |
countBy | 统计符合条件的记录数 | long |
existsBy | 判断是否存在符合条件的记录 | boolean |
findFirstBy | 查询符合条件的第一条记录 | Optional<T> |
findTop5By | 查询符合条件的前 5 条记录 | List<T> |
三、常用条件关键字
条件关键字 | 含义 | 示例方法名 | 生成 SQL 片段 |
---|---|---|---|
And | 逻辑与 | findByNameAndAge | WHERE name = ? AND age = ? |
Or | 逻辑或 | findByNameOrAge | WHERE name = ? OR age = ? |
GreaterThan | 大于 | findByAgeGreaterThan | WHERE age > ? |
LessThan | 小于 | findByAgeLessThan | WHERE age < ? |
Between | 在区间内 | findByAgeBetween | WHERE age BETWEEN ? AND ? |
Like | 模糊匹配 | findByNameLike | WHERE name LIKE ? |
IgnoreCase | 忽略大小写 | findByNameIgnoreCase | WHERE UPPER(name) = UPPER(?) |
OrderBy | 排序 | findByNameOrderByAgeDesc | WHERE name = ? ORDER BY age DESC |
IsNull / NotNull | 空值判断 | findByEmailIsNull | WHERE email IS NULL |
In / NotIn | 包含 / 不包含 | findByAgeIn | WHERE age IN (?, ?, ?) |
四、处理复杂属性与嵌套查询
1. 关联实体属性
通过 _
或直接拼接关联实体的属性名:
// 假设 User 有一个 Address 类型的关联字段 address
List<User> findByAddress_City(String city); // 等价于 findByAddressCity
2. 集合属性查询
若实体包含集合字段(如 List<Role>
):
// 查询拥有特定角色的用户
List<User> findByRolesName(String roleName);
五、实战技巧:如何快速编写派生方法
-
使用 IDE 自动补全
在接口中输入findBy
,IDE 会根据实体类字段自动提示可用的方法名。 -
遵循步骤推导
- 确定前缀:根据操作类型选择
findBy
、deleteBy
等。 - 列出条件属性:按顺序拼接实体字段名(如
name
、age
)。 - 添加条件关键字:在属性后添加
GreaterThan
、Like
等(可选)。 - 排序与分页:添加
OrderByXxxAsc
或使用Pageable
参数。
- 确定前缀:根据操作类型选择
-
复杂查询用
@Query
当派生方法名过长(超过 3 个条件)或逻辑复杂时,推荐使用@Query
注解直接写 SQL。
六、示例对照表
需求描述 | 派生方法名 |
---|---|
查询年龄大于 18 且名字包含 "张" 的用户 | findByAgeGreaterThanAndNameLike(int age, String name) |
删除状态为 "INACTIVE" 的用户 | deleteByStatus(String status) |
统计邮箱不为空的用户数 | countByEmailNotNull() |
查询用户名是 "admin" 或 "root" 的用户 | findByUsernameIn(List<String> usernames) |
查询最近注册的 10 个用户(按注册时间降序) | findTop10ByOrderByRegisterTimeDesc() |
七、注意事项
- 字段名严格匹配:属性名必须与实体类字段完全一致(包括大小写)。
- 避免深层嵌套:关联查询建议不超过 2 层(如
user.address.city
),否则用@Query
。 - 性能问题:复杂查询(如多表关联)使用派生方法可能生成低效 SQL,需通过
@Query
优化。