<noframes id="bhrfl"><address id="bhrfl"></address>

    <address id="bhrfl"></address>

    <noframes id="bhrfl"><address id="bhrfl"><th id="bhrfl"></th></address>

    <form id="bhrfl"><th id="bhrfl"><progress id="bhrfl"></progress></th></form>

    <em id="bhrfl"><span id="bhrfl"></span></em>

    全部
    常見問題
    產品動態
    精選推薦

    使用Spring Data JPA訪問MySQL

    管理 管理 編輯 刪除

    在實際開發過程中,對數據庫的操作大多可以歸結為:“增刪改查”。就最為普遍的單表操作而言,除了表和字段不同外,語句幾乎都是類似的,開發人員需要寫大量類似而枯燥的語句來完成業務邏輯。

    為了解決這些大量枯燥的數據操作語句,誕生了非常多的優秀框架,比如:Hibernate。通過整合Hibernate,我們能夠以操作Java實體的方式來完成對數據的操作,通過框架的幫助,對Java實體的變更最終將自動地映射到數據庫表中。

    在Hibernate的幫助下,Java實體映射到數據庫表數據完成之后,再進一步解決抽象各個Java實體基本的“增刪改查”操作,我們通常會以泛型的方式封裝一個模板Dao來進行抽象簡化,但是這樣依然不是很方便,我們需要針對每個實體編寫一個繼承自泛型模板Dao的接口,再編寫該接口的實現。雖然一些基礎的數據訪問已經可以得到很好的復用,但是在代碼結構上針對每個實體都會有一堆Dao的接口和實現。

    由于模板Dao的實現,使得這些具體實體的Dao層已經變的非?!氨 ?,有一些具體實體的Dao實現可能完全就是對模板Dao的簡單代理,并且往往這樣的實現類可能會出現在很多實體上。Spring Data JPA的出現正可以讓這樣一個已經很“薄”的數據訪問層變成只是一層接口的編寫方式。比如,下面的例子:

    public interface UserRepository extends JpaRepository {
    
        User findByName(String name);
    
        @Query("from User u where u.name=:name")
        User findUser(@Param("name") String name);
    
    }
    

    我們只需要通過編寫一個繼承自JpaRepository的接口就能完成數據訪問,下面以一個具體實例來體驗Spring Data JPA給我們帶來的強大功能。

    使用步驟

    由于Spring Data JPA依賴于Hibernate。如果您對Hibernate有一定了解,下面內容可以毫不費力的看懂并上手使用它。如果您還是Hibernate新手,可以先按如下方式來試試看。

    工程配置

    pom.xml中添加相關依賴,加入以下內容:

    
        org.springframework.boot
        spring-boot-starter-data-jpa
    
    

    application.xml中配置:數據庫連接信息(如使用嵌入式數據庫則不需要)、自動創建表結構的設置,例如使用mysql的情況如下:

    spring.datasource.url=jdbc:mysql://localhost:3306/test
    spring.datasource.username=root
    spring.datasource.password=
    spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
    
    spring.jpa.properties.hibernate.hbm2ddl.auto=create-drop
    

    spring.jpa.properties.hibernate.hbm2ddl.auto是hibernate的配置屬性,其主要作用是:自動創建、更新、驗證數據庫表結構。該參數的幾種配置如下:

    • create:每次加載hibernate時都會刪除上一次的生成的表,然后根據你的model類再重新來生成新表,哪怕兩次沒有任何改變也要這樣執行,這就是導致數據庫表數據丟失的一個重要原因。
    • create-drop:每次加載hibernate時根據model類生成表,但是sessionFactory一關閉,表就自動刪除。
    • update:最常用的屬性,第一次加載hibernate時根據model類會自動建立起表的結構(前提是先建立好數據庫),以后加載hibernate時根據model類自動更新表結構,即使表結構改變了但表中的行仍然存在不會刪除以前的行。要注意的是當部署到服務器后,表結構是不會被馬上建立起來的,是要等應用第一次運行起來后才會。
    • validate:每次加載hibernate時,驗證創建數據庫表結構,只會和數據庫中的表進行比較,不會創建新表,但是會插入新值。

    至此已經完成基礎配置,如果您有在Spring下整合使用過它的話,相信你已經感受到Spring Boot的便利之處:JPA的傳統配置在persistence.xml文件中,但是這里我們不需要。

    創建實體

    創建一個User實體,包含id(主鍵)、name(姓名)、age(年齡)屬性,通過ORM框架其會被映射到數據庫表中,由于配置了hibernate.hbm2ddl.auto,在應用啟動的時候框架會自動去數據庫中創建對應的表。

    @Entity
    @Data
    @NoArgsConstructor
    public class User {
    
        @Id
        @GeneratedValue
        private Long id;
    
        private String name;
        private Integer age;
    
        public User(String name, Integer age) {
            this.name = name;
            this.age = age;
        }
    }
    
    • @Entity注解標識了User類是一個持久化的實體
    • @Data@NoArgsConstructor是Lombok中的注解。用來自動生成各參數的Set、Get函數以及不帶參數的構造函數。
    • @Id@GeneratedValue用來標識User對應對應數據庫表中的主鍵

    注意:除了這些注解之外,還有很多用來精細化配置映射關系的注解,這里不做具體介紹,大家可自行閱讀Hibernate的文檔來學習這些注解的詳細使用方法。

    創建數據訪問接口

    下面針對User實體創建對應的Repository接口實現對該實體的數據訪問,如下代碼:

    public interface UserRepository extends JpaRepository {
    
        User findByName(String name);
    
        User findByNameAndAge(String name, Integer age);
    
        @Query("from User u where u.name=:name")
        User findUser(@Param("name") String name);
    
    }
    

    在Spring Data JPA中,只需要編寫類似上面這樣的接口就可實現數據訪問。不再像我們以往編寫了接口時候還需要自己編寫接口實現類,直接減少了我們的文件清單。

    下面對上面的UserRepository做一些解釋,該接口繼承自JpaRepository,通過查看JpaRepository接口的API文檔,可以看到該接口本身已經實現了創建(save)、更新(save)、刪除(delete)、查詢(findAll、findOne)等基本操作的函數,因此對于這些基礎操作的數據訪問就不需要開發者再自己定義。

    在上例中,我們可以看到下面兩個函數:

    • User findByName(String name)
    • User findByNameAndAge(String name, Integer age)

    它們分別實現了按name查詢User實體和按name和age查詢User實體,可以看到我們這里沒有任何類SQL語句就完成了兩個條件查詢方法。這就是Spring-data-jpa的一大特性:通過解析方法名創建查詢。

    除了通過解析方法名來創建查詢外,它也提供通過使用@Query 注解來創建查詢,您只需要編寫JPQL語句,并通過類似“:name”來映射@Param指定的參數,就像例子中的第三個findUser函數一樣。

    單元測試

    在完成了上面的數據訪問接口之后,按照慣例就是編寫對應的單元測試來驗證編寫的內容是否正確。這里就不多做介紹,主要通過數據操作和查詢來反復驗證操作的正確性。

    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class ApplicationTests {
    
        @Autowired
        private UserRepository userRepository;
    
        @Test
        public void test() throws Exception {
    
            // 創建10條記錄
            userRepository.save(new User("AAA", 10));
            userRepository.save(new User("BBB", 20));
            userRepository.save(new User("CCC", 30));
            userRepository.save(new User("DDD", 40));
            userRepository.save(new User("EEE", 50));
            userRepository.save(new User("FFF", 60));
            userRepository.save(new User("GGG", 70));
            userRepository.save(new User("HHH", 80));
            userRepository.save(new User("III", 90));
            userRepository.save(new User("JJJ", 100));
    
            // 測試findAll, 查詢所有記錄
            Assert.assertEquals(10, userRepository.findAll().size());
    
            // 測試findByName, 查詢姓名為FFF的User
            Assert.assertEquals(60, userRepository.findByName("FFF").getAge().longValue());
    
            // 測試findUser, 查詢姓名為FFF的User
            Assert.assertEquals(60, userRepository.findUser("FFF").getAge().longValue());
    
            // 測試findByNameAndAge, 查詢姓名為FFF并且年齡為60的User
            Assert.assertEquals("FFF", userRepository.findByNameAndAge("FFF", 60).getName());
    
            // 測試刪除姓名為AAA的User
            userRepository.delete(userRepository.findByName("AAA"));
    
            // 測試findAll, 查詢所有記錄, 驗證上面的刪除是否成功
            Assert.assertEquals(9, userRepository.findAll().size());
    
        }
    }
    

    關于Spring Data

    Spring Data JPA在Spring家族中實際上是一個二級項目,它隸屬于Spring Data這個頂級項目。我們們可以看一下關于這個項目的介紹,它除了涵蓋對關系型數據庫的抽象之外,其實還有很多對其他數據存儲中間件的實現,比如我們常用的Redis、MongoDB、Elasticsearch等。

    如果再找幾個項目看一下它們的簡單示例,你會發現:不論你是要訪問什么數據存儲產品,它們的編碼方式幾乎都是一樣的!這就是Spring Data這個項目充滿魅力的地方!通過對數據訪問操作的抽象來屏蔽細節,用不同子項目的方式去實現細節。讓開發者只需要學會使用Spring Data,就能方便快捷的學會對各種數據存儲的操作。所以,對于Spring Data,強烈推薦Java開發者們可以學、甚至讀一下源碼的重要框架。雖然,目前來說很多大型互聯網公司并不會選擇它(性能考量居多,能真正用好它的人不多)作為主要的開發框架,但是其背后的抽象思想是非常值得我們學習的。并且,在做一些非高并發項目的時候,這簡直就是一個快捷開發神器,它可以幫助我們少寫非常多的代碼!


    請登錄后查看

    哈哈哈醬 最后編輯于2024-12-20 16:08:27

    快捷回復
    回復
    回復
    回復({{post_count}}) {{!is_user ? '我的回復' :'全部回復'}}
    排序 默認正序 回復倒序 點贊倒序

    {{item.user_info.nickname ? item.user_info.nickname : item.user_name}} LV.{{ item.user_info.bbs_level }}

    作者 管理員 企業

    {{item.floor}}# 同步到gitee 已同步到gitee {{item.is_suggest == 1? '取消推薦': '推薦'}}
    {{item.is_suggest == 1? '取消推薦': '推薦'}}
    沙發 板凳 地板 {{item.floor}}#
    {{item.user_info.title || '暫無簡介'}}
    附件

    {{itemf.name}}

    {{item.created_at}}  {{item.ip_address}}
    打賞
    已打賞¥{{item.reward_price}}
    {{item.like_count}}
    {{item.showReply ? '取消回復' : '回復'}}
    刪除
    回復
    回復

    {{itemc.user_info.nickname}}

    {{itemc.user_name}}

    回復 {{itemc.comment_user_info.nickname}}

    附件

    {{itemf.name}}

    {{itemc.created_at}}
    打賞
    已打賞¥{{itemc.reward_price}}
    {{itemc.like_count}}
    {{itemc.showReply ? '取消回復' : '回復'}}
    刪除
    回復
    回復
    查看更多
    打賞
    已打賞¥{{reward_price}}
    1201
    {{like_count}}
    {{collect_count}}
    添加回復 ({{post_count}})

    相關推薦

    快速安全登錄

    使用微信掃碼登錄
    {{item.label}} 加精
    {{item.label}} {{item.label}} 板塊推薦 常見問題 產品動態 精選推薦 首頁頭條 首頁動態 首頁推薦
    取 消 確 定
    回復
    回復
    問題:
    問題自動獲取的帖子內容,不準確時需要手動修改. [獲取答案]
    答案:
    提交
    bug 需求 取 消 確 定
    打賞金額
    當前余額:¥{{rewardUserInfo.reward_price}}
    {{item.price}}元
    請輸入 0.1-{{reward_max_price}} 范圍內的數值
    打賞成功
    ¥{{price}}
    完成 確認打賞

    微信登錄/注冊

    切換手機號登錄

    {{ bind_phone ? '綁定手機' : '手機登錄'}}

    {{codeText}}
    切換微信登錄/注冊
    暫不綁定
    亚洲欧美字幕
    CRMEB客服

    CRMEB咨詢熱線 咨詢熱線

    400-8888-794

    微信掃碼咨詢

    CRMEB開源商城下載 源碼下載 CRMEB幫助文檔 幫助文檔
    返回頂部 返回頂部
    CRMEB客服