分享知識 傳遞快樂
使用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);