spring data jpa 的簡單使用

先說簡單一下JPAspring

概念:JPA(Java Persistence API)是Sun官方提出的Java持久化規範。它爲Java開發人員提供了一種對象/關聯映射工具來管理Java應用中的關係數據。數據庫

影響他的出現主要是爲了簡化現有的持久化開發工做和整合ORM技術,結束如今Hibernate,TopLink,JDO等ORM框架各自爲營的局面數組

好處:spring data jpa讓咱們解脫了DAO層的操做,基本上全部CRUD均可以依賴於它來實現緩存

進入正題框架

Spring DATA JPAmaven

  一、引入spring-boot

 maven引入:工具

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

 gradle引入:gradle

compile('org.springframework.boot:spring-boot-starter-data-jpa')

  實現:建立一個接口繼承下面的任何一個接口均可以ui

  3.1:Repository

  概述:僅僅是一個標識,代表任何繼承它的均爲倉庫接口類,方便Spring自動掃描識別 。這個接口是最基礎的接口,只是一個標誌性的接口,沒有定義任何的方法。

  它是最頂層的接口,是一個空接口,目的是爲了統一全部的Repository的類型,且能讓組件掃描的時候自動識別。

  好處:例如,咱們有一部分方法是不想對外提供的,好比咱們只想提供增長和修改方法,不提供刪除方法,那麼下面介紹的幾個接口都是作不到的,這個時候,咱們就能夠繼承這個接口,而後將CrudRepository接口裏面相應的方法拷貝到Repository接口就能夠了。

 

 3.2:CrudRepository

   概述:Repository的子接口,提供CRUD相關的方法 

 主要方法:

保存
    <S extends T> S save(S entity);
批量保存
    <S extends T> Iterable<S> save(Iterable<S> entities);
根據id查詢一個對象
    T findOne(ID id)
判斷對象是否存在
    boolean exists(ID id)
查詢全部的對象
    Iterable<T> findAll()
根據id列表查詢全部的對象
    Iterable<T> findAll(Iterable<ID> ids)
計算對象的總個數
    long count()
根據id刪除
    void delete(ID id)
刪除對象
    void delete(T entity);
批量刪除
    void delete(Iterable<? extends T> entities);
刪除全部
    void deleteAll()

 3.3:PagingAndSortingRepository

  概述:CrudRepository的子接口,添加一組分頁排序相關的方法 

主要方法:

不帶分頁的排序
    Iterable<T> findAll(Sort sort)
帶分頁的排序
    Page<T> findAll(Pageable pageable)

 3.4:JpaRepository

  概述:PagingAndSortingRepository的子接口,增長一組JPA規範相關的方法 

 主要方法:

查詢全部對象,不排序
    List<T> findAll()
查詢全部對象,並排序
    List<T> findAll(Sort sort)
批量保存
    <S extends T> List<S> save(Iterable<S> entities);
強制緩存與數據庫同步
    void flush()
保存並強制同步
    T saveAndFlush(T entity)
批量刪除
    void deleteInBatch(Iterable<T> entities)
刪除全部
    void deleteAllInBatch();

 

    3.5:JpaSpecificationExecutor

      概述:這個比較特殊,不屬於Repository體系,它實現一組JPA Criteria查詢相關的方法,主要是用來作複雜的查詢的接口(輔助接口)。

      注意事項:這個接口很特殊,不屬於Repository體系,而Spring data JPA不會自動掃描識別,因此會報找不到對應的Bean,咱們只須要繼承任意一個繼承了Repository的子接口或直接繼承Repository接口,Spring data JPA就會自動掃描識別,進行統一的管理

 

  四、自定義方法:

  前提:實現上面的任何一個接口

  4.1:使用 @Query 建立查詢

   4.1.1:用法

   @Query 註解的使用很是簡單,只需在聲明的方法上面標註該註解,同時提供一個 JP QL 查詢語句便可

 例如:

@Query("select u from User u where u.name = :name")
User findUserByName(@Param("name") String name);

 4.1.2:參數

 4.1.2.1:命名參數

描述:推薦使用這種方法,能夠不用管參數的位置

@Query("select u from User u where u.name = :name")
User findUserByName(@Param("name") String name);

 

 4.1.2.2:索引參數

 描述:使用?佔位符

@Query("select u from User u where u.email = ?1")// 1表示第一個參數
User findUserByEmail(String email);

 4.1.2.3: SPEL表達式(這裏只是簡單的寫了一下,有興趣能夠去文檔看一下)

   描述:從Spring Data JPA版本1.4開始,咱們支持經過手動定義的查詢來使用受限制的SpEL模板表達式@Query 

@Query("select u from User u where u.name = :name")
User findUserByName(@Param("name") String name);

  基於SpEL的查詢模板中支持的變量

變量
    entityName
用法
    select x from #{#entityName} x
描述
    插入entityName與給定存儲庫關聯的域類型。該entityName解決以下:若是域類型已設置的name屬性@Entity註解那麼它將被使用。不然,將使用域類型的簡單類名稱。
注意
    該entityName能夠經過自定義@Entity的註釋。orm.xmlSpEL表達式不支持自定義。
    引用#entityName將會把用戶類的潛在的將來重映射轉換成一個不一樣的實體名稱(例如經過使用@Entity(name = "MyUser")

 

 4.1.3:分類 

   4.1.3.1:QUERY

 例如:

@Query("select u from User u where u.name = :name")
User findUserByName(@Param("name") String name);

 注意:

  一、使用@Query來指定本地查詢,只要設置nativeQuery爲true,好比:

好比:
@Query(value="select * from tbl_user where name like %?1" ,nativeQuery=true)
public List<UserModel> findByUuidOrAge(String name);

  二、當前版本的本地查詢不支持翻頁和動態的排序

 

 分類(在Query中也分不少中查詢)

  一、使用@Query在查詢方法中聲明查詢

 @Query("select u from User u where u.emailAddress = ?1")
  User findByEmailAddress(String emailAddress);

 

  二、使用高級LIKE表達式

@Query("select u from User u where u.firstname like %?1")
  List<User> findByFirstnameEndsWith(String firstname);

 

  三、使用@Query在查詢方法中聲明本地計數查詢以進行分頁

 @Query(value = "SELECT * FROM USERS WHERE LASTNAME = ?1",
    countQuery = "SELECT count(*) FROM USERS WHERE LASTNAME = ?1",
    nativeQuery = true)
  Page<User> findByLastname(String lastname, Pageable pageable);

 

 4.1.3.1:修改查詢

  好比:

@Modifying
@Query(value="update UserModel o set o.name=:newName where o.name like %:nn")
public int findByUuidOrAge(@Param("nn") String name,@Param("newName") String newName);

  注意:能夠經過使用 @Query 來執行一個更新操做,爲此,咱們須要在使用 @Query 的同時,* 用 @Modifying 來將該操做標識爲修改查詢,這樣框架最終會生成一個更新的操做,而非查詢操做。

  

  4.2:@NamedQueries建立查詢

  概念:命名查詢是 JPA 提供的一種將查詢語句從方法體中獨立出來,以供多個方法共用的功能

  用法:用戶只須要按照 JPA 規範在 orm.xml 文件或者在代碼中使用 @NamedQuery(或 @NamedNativeQuery)定義好查詢語句,惟一要作的就是爲該語句命名時,須要知足」DomainClass.methodName()」的 命名規則

  好比:

編寫接口:
public interface FindUserByNamedQueryRepository extends JpaRepository<User, Integer> {
User findUserWithName(@Param("name") String name);
}
編寫類:
@Entity
@NamedQueries(value={
@NamedQuery(name="User.findUserWithName",query="select u from User u where u.name = :name")
})
如下是實體類
......

  注意:

  一、@NamedQuery中的name屬性的值要和接口中的方法名稱同樣。

  二、此處若是是多個方法,那麼須要使用@NamedQueries,若是隻有一個方法,則可使用@NamedQuery,寫法以下:

@NamedQuery(name="User.findUserWithName",query="select u from User u where u.name = :name")

  4.3:經過解析方法名建立查詢

  概念:顧名思義,就是根據方法的名字,就能建立查詢

  定義規則:

   說明:按照Spring data 定義的規則,查詢方法以find|read|get開頭涉及條件查詢時,條件的屬性用條件關鍵字鏈接,要注意的是:條件屬性首字母需大寫(參數名大寫,條件名首字母大寫,而且接口名中參數出現的順序必須和參數列表中的參數順序一致)

   例如:

 
 
//參數名大寫,條件名首字母大寫,而且接口名中參數出現的順序必須和參數列表中的參數順序一致
User findByNameAndEmail(String name, String email);  //至關於發送了一條SQL:select u from User u where u.name = :name and u.email = :email
  
List<User> findByNameOrPassword(String name, String password);  //至關於發送了一條SQL:select u from User u where u.name = ?1 or u.password = ?2
List<User> findByNameOrPassword(String name, String password);  //至關於發送了一條SQL:select u from User u where u.name = ?1 or u.password = ?2
List<User> findByIdBetween(Integer start, Integer end);  //至關於發送了一條SQL:select u from User u where u.id between ?1 and ?2
List<User> findByIdLessThan(Integer end);  //至關於發送了一條SQL:select u from User u where u.id < ?1 ...

  解析:框架在進行方法名解析時,會先把方法名多餘的前綴截取掉,好比 find、findBy、read、readBy、get、getBy,而後對剩下部分進行解析。而且若是方法的最後一個參數是 Sort 或者 Pageable 類型,也會提取相關的信息,以便按規則進行排序或者分頁查詢。在建立查詢時,咱們經過在方法名中使用屬性名稱來表達,好比 findByIdIn()。框架在解析該方法時,首先剔除 findBy,而後對剩下的屬性進行解析

 

   一些條件查詢的關鍵字:

   

框架在進行方法名解析時,會先把方法名多餘的前綴截取掉,好比 find、findBy、read、readBy、get、getBy,而後對剩下部分進行解析。
而且若是方法的最後一個參數是 Sort 或者 Pageable 類型,也會提取相關的信息,以便按規則進行排序或者分頁查詢。在建立查詢時,咱們經過在方法名中使用屬性名稱來表達
,好比 findByIdIn()。框架在解析該方法時,首先剔除 findBy,而後對剩下的屬性進行解析
And
--- 等價於 SQL 中的 and 關鍵字,好比 findByUsernameAndPassword(String user, Striang pwd)
Or
--- 等價於 SQL 中的 or 關鍵字,好比 findByUsernameOrAddress(String user, String addr)
Between
--- 等價於 SQL 中的 between 關鍵字,好比 findBySalaryBetween(int max, int min)
LessThan
--- 等價於 SQL 中的 "<",好比 findBySalaryLessThan(int max)
GreaterThan
--- 等價於 SQL 中的">",好比 findBySalaryGreaterThan(int min)
IsNull
--- 等價於 SQL 中的 "is null",好比 findByUsernameIsNull()
IsNotNull
--- 等價於 SQL 中的 "is not null",好比 findByUsernameIsNotNull()
NotNull
--- 與 IsNotNull 等價
Like
--- 等價於 SQL 中的 "like",好比 findByUsernameLike(String user)
NotLike
--- 等價於 SQL 中的 "not like",好比 findByUsernameNotLike(String user)
OrderBy
---等價於 SQL 中的 "order by",好比 findByUsernameOrderBySalaryAsc(String user)
Not
--- 等價於 SQL 中的 "! =",好比 findByUsernameNot(String user)
In
--- 等價於 SQL 中的 "in",好比 findByUsernameIn(Collection<String> userList) ,方法的參數能夠是 Collection 類型,也能夠是數組或者不定長參數
NotIn
--- 等價於 SQL 中的 "not in",好比 findByUsernameNotIn(Collection<String> userList) ,方法的參數能夠是 Collection 類型,也能夠是數組或者不定長參數
相關文章
相關標籤/搜索