分享知识 传递快乐
使用JPA自定义声明式查询方法
凡是继承了JpaRepository的或继承其子接口的,都可以使用自定义的声明式查询方法。
声明式查询方法可以分3大类:
- 计数类:以count开头,返回数值类型。
- 查询类:以get/find/stream/query/read开头,返回实体类或其集合。
- 删除类:以delete/remove开始,返回int类型。
示例:
public interface WebTaskRepository extends JpaRepository<WebTask, Integer> {
// declare query method
// 声明式查询方法
// 1. count 计数
long countByName(String name);
// 2. get/find/stream/query/read 查询
public List<WebTask> findByTaskName(String name);
// 3. delete/remove 删除
int deleteById(long id);
}
在以上方法之后还有可以加入下面的关键词。
JPA声明式查询方法名称关键词
查询方法可以由我们声明的命名查询生成,也可以像前面那样由方法名解析。
- 方法名以find…By, read…By, query…By, count…By和 get…By做开头。在By之前可以添加Distinct表示查找不重复数据。By之后是真正的查询条件。
- 可以查询某个属性,也可以使用条件进行比较复杂的查询,例如Between, LessThan, GreaterThan, Like,And,Or等。
- 字符串属性后面可以跟IgnoreCase表示不区分大小写,也可以后跟AllIgnoreCase表示所有属性都不区分大小写。
- 可以使用OrderBy对结果进行升序或降序排序。
- 可以查询属性的属性,直接将几个属性连着写即可,如果可能出现歧义属性,可以使用下划线分隔多个属性。
Keyword | Sample | JPQL snippet |
| | |
| | |
| , , | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | (parameter bound with appended ) |
| | (parameter bound with prepended ) |
| | (parameter bound wrapped in ) |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
具体语法规则和对应的sql都在代码中给出来了,这边需要和大家说的是UserRepository接口的特点。我们通过继承JpaRepository《对应的实体类,主键属性值》来编写findBy等相关的函数来查询数据库。继承JpaRepository的接口在使用的时候,通过@Autowired会自动创建接口的实现类,不需要怎么去实现这个接口,这也是jpa最方便的地方。如果需要详细说明的话可以查看官方文档Appendix C: Repository query keywords一节。
实例说明:
实体类
@Entity
@Table(name="user")
public class User {
@Id
@GenericGenerator(name = "PKUUID", strategy = "uuid2")
@GeneratedValue(generator = "PKUUID")
@Column(length = 36)
protected String id;
@Column(name = "name", nullable = true, length = 30)
private String name;
@Column(name = "height", nullable = true, length = 10)
private Integer height;
public User() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getHeight() {
return height;
}
public void setHeight(Integer height) {
this.height = height;
}
}
JPA
public interface UserRepository extends JpaRepository<User,String>{
/**
* 相当于 select *from user where name=?
* @param name
* @return
*/
public List<User> findByName(String name);
/**
* 相当于select *from user where name like ?
* 但是有一点需要注意的是,%需要我们自己来写
* @param name
* @return
*/
public List<User> findByNameLike(String name);
/**
* 相当于select *from user where name not like ?
* 但是有一点需要注意的是,%需要我们自己来写
* @param name
* @return
*/
public List<User> findByNameNotLike(String name);
/**
* 相当于 select *from user where name <> ?
* @param name
* @return
*/
public List<User> findByNameNot(String name);
/**
* 相当于 select *from user where id in (?)
* @param ids
* @return
*/
public List<User> findByIdIn(List<String> ids);
/**
* 相当于 select *from user where id not in ()
* @param ids
* @return
*/
public List<User> findByIdNotIn(List<String> ids);
/**
* 相当于 select *from user where name=? order by height desc
* @param name
* @return
*/
public List<User> findByNameOrderByHeightDesc(String name);
/**
* 相当于 select *from user where name=? order by height asc
* @param name
* @return
*/
public List<User> findByNameOrderByHeightAsc(String name);
/**
* 相当于 select *from user where name is null
* @return
*/
public List<User> findByNameIsNull();
/**
* 相当于 select *from user where name is not null
* @return
*/
public List<User> findByNameIsNotNull();
/**
* 相当于 select *from user where name =? and height=?
* @param name
* @param height
* @return
*/
public List<User> findByNameAndHeight(String name,int height);
/**
* 相当于 select *from user where name =? or height=?
* @param name
* @param height
* @return
*/
public List<User> findByNameOrHeight(String name,int height);
/**
* 相当于 select *from user where height between ? and ?
* 需要注意的是mysql是有包含两个端点值的
* @param start
* @param end
* @return
*/
public List<User> findByHeightBetween(int start,int end);
/**
* 相当于 select *from user where height < ?
* 需要注意的是mysql是没有包含端点值的
* @param less
* @return
*/
public List<User> findByHeightLessThan(int less);
/**
* 相当于 select *from user where height > ?
* 需要注意的是mysql是没有包含端点值的
* @param greater
* @return
*/
public List<User> findByHeightGreaterThan(int greater);
//计数
public Long countByName(String name);
// 唯一查询,findDistinctByTaskName == findDistinctUserByTaskName
List<User> findDistinctTaskNameByTaskName(String name);
// 启用静态排序
List<User> findByNameOrderByIdDesc(String name);
// 查询符合查询条件的前1条数据
User findFirst1ByName(String name);
// 获得符合查询条件的前2条数据
List<User> findTop2ByName(String name);
}
扩展:
JPA写操作时需要注意,无论是更新,还是删除都需要加上@Transactional 和 @Modifying两个注解。
@Modifying
@Transactional
@Query(value="DELETE FROM DS_IPAY_PAY T WHERE T.BILL_ID = ?1",nativeQuery=true)
public void delete(Long billId);