<del id="nnjnj"></del><track id="nnjnj"></track>

<p id="nnjnj"></p>

<address id="nnjnj"></address>

    <pre id="nnjnj"><pre id="nnjnj"></pre></pre>

      <noframes id="nnjnj"><ruby id="nnjnj"><ruby id="nnjnj"></ruby></ruby>

      • 自動秒收錄
      • 軟件:1973
      • 資訊:58031|
      • 收錄網站:279908|

      IT精英團

      Spring Data JPA

      Spring Data JPA

      瀏覽次數:
      評論次數:
      編輯: 若溪
      信息來源: 51CTO博客
      更新日期: 2022-09-28 16:36:46
      摘要

      Spring Data JPA,首先了解JPA是什么?JPA(JavaPersistenceAPI)是Sun官方提出的Java持久化規范。它為Java開發人員提供了一種對象/關聯映射工具來管理Java應用中的關系數據。它的出現主要是為了簡化現有的持久化開發工作和整合ORM技術,結束現在Hibernate、TopLink、JDO等ORM框架各自為營的局面。值得注意的是,JPA是在充

      • 正文開始
      • 相關閱讀
      • 推薦作品

      首先了解 JPA 是什么?

      JPA(Java Persistence API)是 Sun 官方提出的 Java 持久化規范。
      它為 Java 開發人員提供了一種對象/關聯映射工具來管理 Java 應用中的關系數據。它的出現主要是為了簡化現有的持久化開發工作和整合 ORM 技術,
      結束現在 Hibernate、TopLink、JDO 等 ORM 框架各自為營的局面。
      值得注意的是,JPA 是在充分吸收了現有 Hibernate、TopLink、JDO 等 ORM 框架的基礎上發展而來的,具有易于使用、伸縮性強等優點。
      從目前的開發社區的反應上看,JPA 受到了極大的支持和贊揚,
      其中就包括了 Spring 與 EJB 3.0 的開發團隊。

      注意:JPA 是一套規范,不是一套產品,那么像 Hibernate、TopLink、JDO 它們是一套產品,如果說這些產品實現了這個 JPA 規范,那么就可以叫它們為 JPA 的實現產品。
      Spring Data JPA

      Spring Data JPA 是 Spring 基于 ORM 框架、JPA 規范的基礎上封裝的一套 JPA 應用框架,可使開發者用極簡的代碼即可實現對數據的訪問和操作。它提供了包括增刪改查等在內的常用功能,且易于擴展!學習并使用 Spring Data JPA 可以極大提高開發效率!

      Spring Data JPA 讓我們解脫了 DAO 層的操作,基本上所有 CRUD 都可以依賴于它來實現。

      先上例子:

      package com.itguang.weixinsell.repository;
      
      import com.itguang.weixinsell.entity.ProductInfoEntity;
      import org.springframework.data.jpa.repository.JpaRepository;
      import org.springframework.data.jpa.repository.Query;
      import org.springframework.data.repository.query.Param;
      
      import java.util.List;
      
      public interface ProductInfoRepository extends JpaRepository

      借助 Spring Data實現自動化的JPA Repostory

      查詢方法定義的規則和使用

      編寫Spring Data JPA Repository 的關鍵在于從一組接口中挑選一個進行擴展.

      如:

      public interface ProductCategoryRepository extends JpaRepository{

      添加注解能到達到不用 extends JpaRepository 的功能

      @RepositoryDefinition(domainClass = Employee.class, idClass = Integer.class)

      這里,ProductCategoryRepository擴展了 JpaRepository 接口,稍后我們會介紹其它幾個接口.

      通過這種方式,JPARepository 進行了參數化,所以它就能知道這是一個用來持久化 ProductCategoryEntity 的Repository.
      并且id類型為 Integer .

      另外,它還會集成18個執行持久化操作的通用方法.

      在spring boot 中,如果使用了 spring-boot-starter->因為 ProductCategoryRepository 擴展了 JpaRepository 接口,而 JpaRepository 接口又間接擴展了 Repository 接口,所以:
      當Spring Data 掃描到它時,就會自動創建 ProductCategoryRepository 的實現類,其中包含了 JpaRepository ,PagingAndSortingRepository ,和CrudRepository的18個方法.

      很重要的一點就是,Repository的實現類是在應用啟動的時候生成的,也就是Spring的應用上下文創建的時候.而不是通過代碼生成技術產生的,也不是接口方法調用時才產生的

      Repository 的幾個實現類

      首先看下 CrudRepository接口

      這個接口提供了通用的CRUD操作

      有保存一個或多個, 查詢一個或多個,刪除一個或多個.

      值得一提的是: JPA中的更新操作你可以通過 先查詢一個再保存來更新的.

      我們可以繼承 CrudRepository 接口或者繼承 JpaRepository接口,因為通過上面的類圖,我們可以發現 JpaRepository接口本身已經繼承了 CrudRepository

      @RunWith(SpringRunner.class)
       @SpringBootTest
       public class ProductCategoryCRUDServiceTest
           @Autowired
           private ProductCategoryCRUDService categoryCRUDService;
      
      
           //CRUD 操作
      
           //增 save(entity), save(entities)
           @Test
           public void save1(){
               ProductCategoryEntity categoryEntity = new ProductCategoryEntity();
               categoryEntity.setCategoryName("肯德基20");
               categoryEntity.setCategoryType(20);
      
               ProductCategoryEntity save = categoryCRUDService.saveOne(categoryEntity);
               System.out.println(save);
           }
      
           // save(entities)
           @Test
           public void saveManyTest(){
      
               ProductCategoryEntity categoryEntity = new ProductCategoryEntity();
               categoryEntity.setCategoryName("test21");
               categoryEntity.setCategoryType(101);
      
               ProductCategoryEntity categoryEntity2 = new ProductCategoryEntity();
               categoryEntity2.setCategoryName("test22");
               categoryEntity.setCategoryType(201);
      
               ArrayList

      只要 id一樣,就會更新,而不是添加.

      PagingAndSortingRepository 分頁排序接口

      這個接口很簡單;

      @NoRepositoryBean
      public interface PagingAndSortingRepository

      Page findAll(Pageable pageable); 中Pageable 是一個接口,他有兩個實現類,PageRequest和QPageRequest
      常使用的是 PageRequest 和QPageRequest

      PageRequest 中方法如下:

      有兩個常用的構造方法:需要注意的是,頁數是從 0 開始的,即page=0 為第一頁

           PageRequest(int page, int size)
      
           PageRequest(int page, int size, Sort sort)

      我們可以這樣構造Pageable對象,使用 PageRequest(int page, int size)

      //分頁排序查詢
      
          @Test
          public void pageAndSortingTest(){
              Pageable pageable = new PageRequest(0,5);
              Page

      返回的是一個Page對象.

      public interface Page

      舉例說明:

      //分頁排序查詢
      
          @Test
          public void pageAndSortingTest(){
              Pageable pageable = new PageRequest(0,5);
              Page

      PageRequest還有一種構造方法 PageRequest(int page, int size, Sort sort)

      我們可以傳進去一個 Sort對象,進行排序

      Sort對象的構造方法接受一個 Order對象

      Order對象是Sort 對象的一個內部類

      Order的構造方法有:

      /**
               * Creates a new {@link Order} instance. if order is {@literal null} then order defaults to
               * {@link Sort#DEFAULT_DIRECTION}
               * 
               * @param direction can be {@literal null}, will default to {@link Sort#DEFAULT_DIRECTION}
               * @param
              public Order(Direction direction, String property) {
                  this(direction, property, DEFAULT_IGNORE_CASE, null);
              }
      
              /**
               * Creates a new {@link Order} instance. if order is {@literal null} then order defaults to
               * {@link Sort#DEFAULT_DIRECTION}
               * 
               * @param direction can be {@literal null}, will default to {@link Sort#DEFAULT_DIRECTION}
               * @param property must not be {@literal null} or empty.
               * @param
              public Order(Direction direction, String property, NullHandling nullHandlingHint) {
                  this(direction, property, DEFAULT_IGNORE_CASE, nullHandlingHint);
              }
      
              /**
               * Creates a new {@link Order} instance. Takes a single property. Direction defaults to
               * {@link Sort#DEFAULT_DIRECTION}.
               * 
               * @param
              public Order(String property) {
                  this(DEFAULT_DIRECTION, property);
              }
      
              /**
               * Creates a new {@link Order} instance. if order is {@literal null} then order defaults to
               * {@link Sort#DEFAULT_DIRECTION}
               * 
               * @param direction can be {@literal null}, will default to {@link Sort#DEFAULT_DIRECTION}
               * @param property must not be {@literal null} or empty.
               * @param ignoreCase true if sorting should be case insensitive. false if sorting should be case sensitive.
               * @param nullHandling can be {@literal null}, will default to {@link NullHandling#NATIVE}.
               * @since
              private Order(Direction direction, String property, boolean ignoreCase, NullHandling nullHandling) {
      
                  if (!StringUtils.hasText(property)) {
                      throw new IllegalArgumentException("Property must not null or empty!");
                  }
      
                  this.direction = direction == null ? DEFAULT_DIRECTION : direction;
                  this.property = property;
                  this.ignoreCase = ignoreCase;
                  this.nullHandling = nullHandling == null

      Direction 是一個枚舉類型

      ASC, DESC;

      支持升序和降序,如果不傳 Direction對象,則使用默認排序規則 Direction DEFAULT_DIRECTION = Direction.ASC; ASC(升序)

      好了,經過上面的了解,相信你已經會使用 Sort 了.

      例如:

      //分頁并排序
          @Test
          public void testPageAndSort(){
      
              //按照價格降序
              Sort.Order order = new Sort.Order(Sort.Direction.DESC,"productPrice");
              Sort sort = new Sort(order);
      
              Pageable pageable = new PageRequest(0, 5,sort);
      
              Page

      如果我們想按照多個字段進行排序呢?其實也很簡單,上面我們知道,Sort有一個構造方法接收 List 類型參數,實例化多個Order對象,放在一個List 列表中即可.

      //分頁并排序
          @Test
          public void testPageAndSort(){
      
              //按照價格降序
              Sort.Order order = new Sort.Order(Sort.Direction.DESC,"productPrice");
              //按照庫存量
              Sort.Order order1 = new Sort.Order(Sort.Direction.DESC, "productStock");
      
      
              //需要注意,排序順序按照添加到 列表中的順序進行排序,如:先按庫存排序,再按價格進行排序
              ArrayList

      有一點需要注意的是:排序順序按照添加到 列表中的順序進行排序

      JpaRepository 接口使用詳解

      /**
           *  findAll(Sort sort)
           */
          @Test
          public void testJpa1(){
              //按價格降序
              Sort.Order order = new Sort.Order(Sort.Direction.DESC, "productPrice");
              Sort sort = new Sort(order);
              List

      JpaSpecificationExecutor 接口

      不屬于Repository體系,實現一組 JPA Criteria 查詢相關的方法

      Specification:封裝 JPA Criteria 查詢條件。通常使用匿名內部類的方式來創建該接口的對象

      由于JpaSpecificationExecutor 并不繼承repository 接口,所以它不能單獨使用,只能和jpa Repository 一起用。

      public interface ProductInfoRepository extends JpaRepository,JpaSpecificationExecutor

      如何創建 ? 直接new 這個接口

      /**
               * root:就是我們要查詢的類型 ProductInfoEntity
               * query: 查詢條件
               * cb: 構建Predicate(斷言)
               *
               */
      Specification

      toPredicate 方法有三個參數:


      • Root,Root繼承了From接口


      • CriteriaQuery,查詢條件

      • CriteriaBuilder,構建Predicate(斷言),這個接口方法很多



      例如:

      /**
           *  JpaSpecificationExecutor
           */
          @Test
          public void testJpaSpecificationExecutor(){
      
              //按照價格降序
              Sort.Order order = new Sort.Order(Sort.Direction.DESC,"productPrice");
              //按照庫存量
              Sort.Order order1 = new Sort.Order(Sort.Direction.DESC, "productStock");
      
      
              //需要注意,排序順序按照添加到 列表中的順序進行排序
              ArrayList

      Spring Data JPA 默認提供了 18個便利的方法進行通用的JPA操作.但是如果你的需求超過了它所提供的這18個方法,該怎么辦呢?

      幸好,Spring Data JPA提供了幾種方法來為Repository 添加自定義的方法.

      自定義查詢方法

      先看一個例子:

      “`java

      public interface ProductInfoRepository extends JpaRepository

      使用:事實上,我們并不需要實現該方法,方法簽名已經告訴 Spring Data JPA 足夠的信息來創建這個方法的實現了.
      
      ```java
      @RunWith(SpringRunner.class)
      @SpringBootTest
      public class ProductInfoRepositoryTest {
      
          @Autowired
          private ProductInfoRepository infoRepository;
      
          @Test
          public void test1(){
              List

      當創建 Repository 實現的時候,Spring Data會檢查 Repository 接口的所有方法,解析方法的名稱,并基于被持久化的對象來推測方法的目的.
      本質上,Spring Data 定義了一組小型的領域特定語言(DSL),在這里持久化的細節都是通過 Repository的方法簽名來描述的.

      findAllByProductName(String name) 方法非常簡單,但是Spring Data也能處理更加有意思的方法簽名.
      Repoditory 方法是 由一個動詞,一個可選主題,關鍵詞By以及一個斷言所組成.
      在 findAllByProductName 方法中,動詞是findAll ,斷言是 ProductName,主題并沒有指定,暗含就是 ProductInfoEntity.

      Spring Data 允許在方法中使用四種動詞: get ,read, find , count . 其中動詞 get, read,find 是同義的,這三個動詞對用的Repository方法都會查詢數據并返回對象.
      .而動詞 count 則會返回匹配對象的數量,而不是對象本身.

      Repository 方法的主題是可選的,它主要是讓你命名方法的時候有很多的靈活性,findAllByProductName和findAllProductInfoEntityByProductName方法沒有什么區別.
      要查詢的對象的類型是通過如何參數化 Repository 接口來決定的,而不是方法名稱中的主題.

      不過,Spring Data 這個小型的DSL依舊有其局限性,有時候通過方法名表達預期的查詢很繁瑣,甚至無法實現.如果與呆這種情況,Spring Data能讓我們通過#Query注解來解決問題

      聲明自定義查詢

      /**
            *使用JPA SQL語句
            * @return
           @Query("select p from ProductInfoEntity p where p.productName like '%米%' ")
           List

      當然還可以使用原生SQL語句進行查詢,只需要 nativeQuery = true 即可

      /**
           * 使用原生SQL語句 查詢
           * @return
          @Query(nativeQuery = true,value = "select count(*) from product_info")
          Integer getCount();

      Spring data JPA 更新及刪除操作整合事物的使用

      更新操作注意事項:

      • 使用Query注解寫更新JPA語句

      • 添加 @Modifying 注解

      @Modifying
          @Query("update ProductInfoEntity  o set o.productPrice =:price where o.productId=:id")
          Integer updatePrice(@Param("id") String id,@Param("price") double price);
      • 在service層添加事物 @Transactional

      package com.itguang.weixinsell.service;
      
      import com.itguang.weixinsell.repository.ProductInfoRepository;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.stereotype.Service;
      import org.springframework.transaction.annotation.Transactional;
      
      /**
       * @author itguang
       * @create
      
      @Service
      @Transactional
      public class ProductInfoService
      
          @Autowired
          private ProductInfoRepository infoRepository;
      
      
          public Integer updatePrice( String id,double price){
              Integer i = infoRepository.updatePrice(id, price);
              return


      ATMHYH C語言分享筆記
      ? 上一篇 2022-09-25
      • ATMHYH C語言分享筆記
        1閱讀 0條評論 個贊
        ATMHYH C語言分享筆記,入學C語言……
      • python爬蟲抓取國家科技報告服務系統數據 共計30多萬條
        1閱讀 0條評論 個贊
        python爬蟲爬取國家科技報告服務系統數據,共計30余萬條,爬取國家科技報告服務系統數據按學科分類【中圖分類】共計三十余萬條科技報告數據……
      • [C language _2]整數和浮點數據類型
        0閱讀 0條評論 個贊
        【C語言_2】整型和浮點型數據類型,整型數據類型整型數據類型名稱及關鍵詞類型名稱關鍵詞注釋字符型char用于表示很小的整數短整型short用于表示較小的整數整型int生活中一般的整數都可以表示長整型long用于表示較大的整數加長整型longlong用于表示非常大的整數為什么要定義不同的整型類型????因為不同的數據類型所占用的內存大小是不同的,他們可表示的數據范圍也是不同的。那么char,sho……
      • 設計的永恒法則是不會讓我思考的設計
        0閱讀 0條評論 個贊
        經久不衰的設計定律是不要讓我思考的設計,1前言什么是設計?什么是好的設計?如何思考設計背后的哲學?工作當中也有跟設計師接觸。有時候發現自己的角度(普通用戶)和設計師的初衷可能真的大相徑庭。作者主頁,可以點??此處??,以下是《不要讓我思考》(Dont'tmakemethink)讀書筆記。本書是一本很薄的書,短小精煉,適合任何想要了解設計的人:設計師、開發人員、網頁制作人員、項目經理閱讀此書不會讓人感到壓力,不需要面面俱到。任何……
      • java經典算法-第二天
        0閱讀 0條評論 個贊
        java經典算法-day2,java算法題-day2……
      發表評論 共有條評論
      用戶名: 密碼:
      驗證碼: 匿名發表
      • dotnet7 aot編譯實戰
        17閱讀 0條評論 個贊
        0起因#這段日子看到dotnet7-rc1發布,我對NativeAot功能比較感興趣,如果aot成功,這意味了我們的dotnet程序在防破解的上直接指數級提高。我隨手使用asp.netcore-7.……
      • 大促銷活動如何抵御高流量DDoS攻擊?
        0閱讀 0條評論 個贊
        大促活動如何抵御大流量DDoS攻擊?每一次活動大促帶來的迅猛流量,對技術人而言都是一次嚴峻考驗。如果在活動期間遭受黑產惡意DDoS攻擊,無疑是雪上加霜。電商的特性是業務常態下通常不會遭受大流量DD……
      • 如何找到性能最差的SQL Server查詢
        0閱讀 0條評論 個贊
        我經常會被反復問到這樣的問題:”我有一個性能很差的SQLServer。我如何找出最差性能的查詢?“。因此在今天的文章里會給你一些讓你很容易找到問題答案的信息向導。問SQLServer!SQLSe……
      • 學習Linux 就看這篇文章!
        0閱讀 0條評論 個贊
        對于測試同學來說,Linux基本屬于必學必會內容,招聘要求中基本都會出現Linux相關字眼,面試也經常被問到,原因很簡單,因為現在公司的服務器絕大多數都是Linux,如果你一無所知,很多時候聽不懂別人……
      • 如何優雅地轉換Bean對象
        0閱讀 0條評論 個贊
        背景我們的故事要從一個風和日麗的下午開始說起!這天,外包韓在位置上寫代碼~外包韓根據如下定義PO(persistantobject):持久化對象,可以看成是與數據庫中的表相映射的java對象。最……
      • [設計模式] Java設計模式-橋模式
        0閱讀 0條評論 個贊
        目錄【設計模式】Java設計模式-橋接模式簡介橋接模式實例代碼示例①、品牌接口②、汽車品牌③、抽象汽車類④、汽車類型子類⑤、橋接模式測試1|1簡介橋接(Bridge)是用于把抽象化與實現化解耦,使……
      • [設計模式] Java設計模式-工廠模式
        9閱讀 0條評論 個贊
        目錄【設計模式】Java設計模式-工廠模式簡介1、普通工廠(SimpleFactory)模式①、定義類②、定義簡單的工廠類③、實例2、抽象工廠(AbstractFactory)模式①、定義類②、……
      • Web API版本控制 網絡6
        0閱讀 0條評論 個贊
        為了了解ASP.NETCoreWebAPI的版本控制,我們必須了解API中的一些版本控制策略,然后將API版本控制與OpenAPI集成,以便我們可以在SwaggerUI中看到版本化的API。1……
      • 利用卡夫卡的賦值模式實現超大群(10萬)的消息推送
        0閱讀 0條評論 個贊
        引言IM即時通信場景下,最重要的一個能力就是推送:在線的直接通過長連接網關服務轉發,離線的通過APNS或者極光等系統進行推送。本文主要是針對在線用戶推送場景來進行總結和探討:如何利用Kafka的Ass……
      • 卡夫卡詳解(一)——卡夫卡是什么 怎么用
        0閱讀 0條評論 個贊
        kafka是什么在回答這個問題之前,我們需要先了解另一個東西--eventstreaming。什么是eventstreaming我覺得,eventstreaming是一個動態的概念,它描述了一……
      • 漫談考試成長的探索——考試策略
        6閱讀 0條評論 個贊
        在《漫談軟件系統測試——問題解決》一文中,文章借鑒控制疫情的四大策略,總結了軟件系統質量保障的四大策略。那么在日常工作中,我們應該如何理解測試策略呢?什么是測試策略?測試策略是描述軟件開發周期的測試方……
      • 【MySQL】DDL因正在等待表元數據鎖定卡住
        0閱讀 0條評論 個贊
        在數據庫空閑時間,對表做碎片整理:1altertablemy_abcengine=innodb;發現會話被阻塞,顯示狀態是:1Waitingfortablemetadatalock手動斷開alte……
      • JAVA中容器設計的進化史:從白盒到黑盒 再到作為設計模式之一的迭代器
        0閱讀 0條評論 個贊
        大家好,又見面了。在我們的項目編碼中,不可避免的會用到一些容器類,我們可以直接使用List、Map、Set、Array等類型。當然,為了體現業務層面的含義,我們也會根據實際需要自行封裝一些專門的Bea……
      • 從PG15開始WAL壓縮優化
        0閱讀 0條評論 個贊
        PG15傳聞中的超級令人激動的功能大多數跳票了,年初我也寫過一個關于PG15新功能跳票的文章。PG15BETA已經發出幾個月了,似乎PG15里令人激動人心的功能不多,不過從長長的新功能列表里,……
      • c#異步高級————通道[1]
        0閱讀 0條評論 個贊
        前言該系列為異步編程的進階篇,其實也不能這么講。世界上本沒有進階篇,只能說是高級篇(高級篇不能說多高級,是對底層的封裝的意思),只要是加深理解都是進階。本章先介紹一下channel。正文下面沒什么好說……
      • IDEA遠程部署項目到Docker
        9閱讀 0條評論 個贊
        前言最近在寫東西部署到服務器,結構是springboot工程配合docker部署。但是每次部署都3個步驟:本地構建jar復制jar到遠程服務器用DockerFile構建鏡像部署次數一多,我就懷疑人生了……
      • 這三個特點讓G1取代CMS!
        0閱讀 0條評論 個贊
        大家好,我是樹哥。之前我們聊過CMS回收器,但那時候我們說CMS回收器已經落伍了,現在應該是用G1回收器的時候了。那么G1回收器到底有什么魔力,它比CMS回收器相比強在哪里呢?今天……
      • 基于位置變化的市縣彈出引導切換
        31閱讀 0條評論 個贊
        目錄1.背景2.模型方案產出3.總結01背景58App業務中有城市和縣域兩個首頁,兩者中間有一個過渡選擇頁,用戶通過點擊該頁面下的條目內容可以切換到對應條目的首頁;比如:點擊“北京”會跳轉到北京(市)……
      • SQL Server操作系統的任務調度機制
        0閱讀 0條評論 個贊
        簡介SQLServerOS是在Windows之上,用于服務SQLServer的一個用戶級別的操作系統層次。它將操作系統部分的功能從整個SQLServer引擎中抽象出來,單獨形成一層,以便為存……
      • 自動化測試選擇Python還是Java?
        0閱讀 0條評論 個贊
        你好,我是測試蔡坨坨。今天,我們來聊一聊測試人員想要進階,想要做自動化測試,甚至測試開發,如何選擇編程語言。前言自動化測試,這幾年行業內的熱詞,也是測試人員進階的必備技能,更是軟件測試未來發展的趨勢?!?/div>
      最近發布資訊
      更多
      警花高潮嗷嗷叫
      <del id="nnjnj"></del><track id="nnjnj"></track>

      <p id="nnjnj"></p>

      <address id="nnjnj"></address>

        <pre id="nnjnj"><pre id="nnjnj"></pre></pre>

          <noframes id="nnjnj"><ruby id="nnjnj"><ruby id="nnjnj"></ruby></ruby>