今天在寫JPA查詢的時候,遇到了添加自定義方法,項目啓動報錯原因,現總結如下:
首先定義實體類
@Entity
@Table(name =“user”)
類用戶{
@Id
@GeneratedValue
int id;
@柱
字符串年齡;
@柱
絃樂學校;
@柱
String userName;
set,get方法(省略)
}
公共接口UserRepository擴展了JpaRepository <User,Long> {
List <User> findByUsernameLike(String username);
List <User> aaa();
}
啓動項目時,項目報錯提示信息爲:org.springframework.data.mapping.PropertyReferenceException:找不到類型爲com.fpi.safety.common.entity.po.User的屬性aaa
再將List <User> aaa();方法去掉後,項目又可以正常啓動運行
是什麼原因呢?
經查找,原來是繼承JPA,必須滿足一些規則,規則如下
Spring Data JPA框架在進行方法名解析時,會先把方法名多餘的前綴截取掉,比如find,findBy,read,readBy,get,getBy,然後對剩下的部分進行解析。
假如創建如下的查詢:findByUserName(),框架在解析該方法時,首先剔除findBy,然後對剩下的屬性進行解析,假設查詢實體爲用戶
1:先判斷用戶名(根據POJO規範,首字母變爲小寫)是否爲查詢實體的一個屬性,如果是,則表示根據該屬性進行查詢;如果沒有該屬性,繼續第二步;
2:從右往左截取第一個大寫字母開頭的字符串此處是名稱),然後檢查剩下的字符串是否爲查詢實體的一個屬性,如果是,則表示根據該屬性進行查詢;如果沒有該屬性,則重複第二步,繼續從右往左截取;最後假設用戶爲查詢實體的一個屬性;
3:接着處理剩下部分(用戶名),先判斷用戶所對應的類型是否有userName的屬性,如果有,則表示該方法最終是根據“User.userName”的取值進行查詢;否則繼續按照步驟2的規則從右往左截取,最終表示根據“User.userName”的值進行查詢。
4:可能會存在一種特殊情況,比如用戶包含一個的屬性,也有一個userNameChange屬性,此時會存在混合。可以明確在屬性之間加上“_”以顯式表達意思,比如“findByUser_NameChange”或者” findByUserName_Change()“
從上面,我們可以得知,jap在解析是,aaa在用戶類中是沒有屬性的,所以報錯找不到屬性aaa。
如果我們想要使用JAP框架,又不想再多增加一個自定義類,則必須符合其命名規則
如果,你記不住JPA的規則也沒關係,你可以自己再多寫一個類來實現自定義查詢方法
如下:
。自定義一個接口,該接口用來聲明自己額外定義的查詢。
public interface UseerRepositoryTwo {
public List <User> searchUser(String name,int id);
}
2.創建一個接口,該接口擴展JpaRepository或者CurdRepository,以及上面自己定義的接口UseerRepositoryTwo
public interface UserRepositoryTwoService擴展CrudRepository <LogDTO,Integer>,CustomizedLogRepository {
}
3.實現UserRepositoryTwoService
注意此處的類名,必須以2中創建的接口的名字UserRepositoryTwoService,後面加上Impl來聲明,而不是寫成UseerRepositoryTwoImpl
public class UserRepositoryTwoServiceImpl實現UserRepositoryTwoService {
@Autowired
@PersistenceContext
私有EntityManager entityManager;
@Override
public List <User> searchLogs(int Id,String name){
......
}
}
自己在寫自定義實現即可