在數(shù)據(jù)訪(fǎng)問(wèn)這章的第一篇文章《Spring中運(yùn)用JdbcTemplate訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)》中,我們現(xiàn)已介紹了怎么運(yùn)用SpringBoot中最根本的jdbc模塊來(lái)完結(jié)聯(lián)絡(luò)型數(shù)據(jù)庫(kù)的數(shù)據(jù)讀寫(xiě)操作。那么結(jié)合Web開(kāi)發(fā)一章的內(nèi)容,我們就能夠利用JDBC模塊與Web模塊的功用,綜合著運(yùn)用來(lái)完結(jié)一個(gè)適用于許多簡(jiǎn)略運(yùn)用場(chǎng)景的后端運(yùn)用了。
然而當(dāng)我們有必定的開(kāi)發(fā)經(jīng)驗(yàn)之后,不難發(fā)現(xiàn),在實(shí)踐開(kāi)發(fā)過(guò)程中,對(duì)數(shù)據(jù)庫(kù)的操作大多能夠歸結(jié)為:“增修改查”。就最為普遍的單表操作而言,除了表和字段不同外,句子簡(jiǎn)直都是相似的,開(kāi)發(fā)人員需求寫(xiě)許多相似而單調(diào)的句子來(lái)完結(jié)業(yè)務(wù)邏輯。
為了處理這些許多單調(diào)的數(shù)據(jù)操作句子,誕生了非常多的優(yōu)異結(jié)構(gòu),比方:Hibernate。經(jīng)過(guò)整合Hibernate,我們能夠以操作Java實(shí)體的方法來(lái)完結(jié)對(duì)數(shù)據(jù)的操作,經(jīng)過(guò)結(jié)構(gòu)的協(xié)助,對(duì)Java實(shí)體的改動(dòng)最終將自動(dòng)地映射到數(shù)據(jù)庫(kù)表中。
在Hibernate的協(xié)助下,Java實(shí)體映射到數(shù)據(jù)庫(kù)表數(shù)據(jù)完結(jié)之后,再進(jìn)一步處理籠統(tǒng)各個(gè)Java實(shí)體根本的“增修改查”操作,我們通常會(huì)以泛型的方法封裝一個(gè)模板Dao來(lái)進(jìn)行籠統(tǒng)簡(jiǎn)化,但是這樣依然不是很便利,我們需求針對(duì)每個(gè)實(shí)體編寫(xiě)一個(gè)承繼自泛型模板Dao的接口,再編寫(xiě)該接口的完結(jié)。盡管一些基礎(chǔ)的數(shù)據(jù)訪(fǎng)問(wèn)現(xiàn)已能夠得到很好的復(fù)用,但是在代碼結(jié)構(gòu)上針對(duì)每個(gè)實(shí)體都會(huì)有一堆Dao的接口和完結(jié)。
因?yàn)槟0錎ao的完結(jié),使得這些具體實(shí)體的Dao層現(xiàn)已變的非?!氨 ?,有一些具體實(shí)體的Dao完結(jié)或許徹底便是對(duì)模板Dao的簡(jiǎn)略代理,而且往往這樣的完結(jié)類(lèi)或許會(huì)呈現(xiàn)在許多實(shí)體上。SpringDataJPA的呈現(xiàn)正能夠讓這樣一個(gè)現(xiàn)已很“薄”的數(shù)據(jù)訪(fǎng)問(wèn)層變成僅僅一層接口的編寫(xiě)方法。比方,下面的比方:
publicinterfaceUserRepositoryextendsJpaRepository<User,Long>{UserfindByName(Stringname);@Query(“fromUseruwhereu.name=:name”)UserfindUser(@Param(“name”)Stringname);
}
我們只需求經(jīng)過(guò)編寫(xiě)一個(gè)承繼自JpaRepository的接口就能完結(jié)數(shù)據(jù)訪(fǎng)問(wèn),下面以一個(gè)具體實(shí)例來(lái)體驗(yàn)SpringDataJPA給我們帶來(lái)的強(qiáng)壯功用。
運(yùn)用過(guò)程
因?yàn)镾pringDataJPA依賴(lài)于Hibernate。假如您對(duì)Hibernate有必定了解,下面內(nèi)容能夠毫不費(fèi)力的看懂并上手運(yùn)用它。假如您還是Hibernate新手,您能夠先按如下方法入門(mén),再建議回頭學(xué)習(xí)一下Hibernate以協(xié)助這部分的理解和進(jìn)一步運(yùn)用。
工程配備
在pom.xml中增加相關(guān)依賴(lài),加入以下內(nèi)容:
<dependency<groupId>org.springframework.bootgroupId><artifactId>spring-boot-starter-data-jpaartifactId>dependency>
在application.xml中配備:數(shù)據(jù)庫(kù)銜接信息(如運(yùn)用嵌入式數(shù)據(jù)庫(kù)則不需求)、自動(dòng)創(chuàng)建表結(jié)構(gòu)的設(shè)置,例如運(yùn)用mysql的狀況如下:
spring.datasource.url=jdbc:mysql://localhost:3306/testspring.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的配備特色,其首要作用是:自動(dòng)創(chuàng)建、更新、驗(yàn)證數(shù)據(jù)庫(kù)表結(jié)構(gòu)。該參數(shù)的幾種配備如下:
create:每次加載hibernate時(shí)都會(huì)刪去上一次的生成的表,然后根據(jù)你的model類(lèi)再?gòu)念^來(lái)生成新表,哪怕兩次沒(méi)有任何改動(dòng)也要這樣履行,這便是導(dǎo)致數(shù)據(jù)庫(kù)表數(shù)據(jù)丟失的一個(gè)重要原因。
create-drop:每次加載hibernate時(shí)根據(jù)model類(lèi)生成表,但是sessionFactory一關(guān)閉,表就自動(dòng)刪去。
update:最常用的特色,第一次加載hibernate時(shí)根據(jù)model類(lèi)會(huì)自動(dòng)樹(shù)立起表的結(jié)構(gòu)(條件是先樹(shù)立好數(shù)據(jù)庫(kù)),今后加載hibernate時(shí)根據(jù)model類(lèi)自動(dòng)更新表結(jié)構(gòu),即便表結(jié)構(gòu)改動(dòng)了但表中的行仍然存在不會(huì)刪去曾經(jīng)的行。要注意的是當(dāng)布置到服務(wù)器后,表結(jié)構(gòu)是不會(huì)被馬上樹(shù)立起來(lái)的,是要等運(yùn)用第一次運(yùn)轉(zhuǎn)起來(lái)后才會(huì)。
validate:每次加載hibernate時(shí),驗(yàn)證創(chuàng)建數(shù)據(jù)庫(kù)表結(jié)構(gòu),只會(huì)和數(shù)據(jù)庫(kù)中的表進(jìn)行比較,不會(huì)創(chuàng)建新表,但是會(huì)刺進(jìn)新值。
至此現(xiàn)已完結(jié)基礎(chǔ)配備,假如您有在Spring下整合運(yùn)用過(guò)它的話(huà),相信你現(xiàn)已感受到SpringBoot的便利之處:JPA的傳統(tǒng)配備在persistence.xml文件中,但是這兒我們不需求。當(dāng)然,最好在構(gòu)建項(xiàng)目時(shí)分按照之條件過(guò)的最佳實(shí)踐的工程結(jié)構(gòu)來(lái)安排,這樣以確保各種配備都能被結(jié)構(gòu)掃描到。
創(chuàng)建實(shí)體
創(chuàng)建一個(gè)User實(shí)體,包含id(主鍵)、name(名字)、age(年紀(jì))特色,經(jīng)過(guò)ORM結(jié)構(gòu)其會(huì)被映射到數(shù)據(jù)庫(kù)表中,因?yàn)榕鋫淞薶ibernate.hbm2ddl.auto,在運(yùn)用發(fā)動(dòng)的時(shí)分結(jié)構(gòu)會(huì)自動(dòng)去數(shù)據(jù)庫(kù)中創(chuàng)建對(duì)應(yīng)的表。
@Entity@Data@NoArgsConstructorpublicclassUser{@Id@GeneratedValueprivateLongid;privateStringname;privateIntegerage;publicUser(Stringname,Integerage){this.name=name;this.age=age;
}
}
@Entity注解標(biāo)識(shí)了User類(lèi)是一個(gè)耐久化的實(shí)體
@Data和@NoArgsConstructor是Lombok中的注解。用來(lái)自動(dòng)生成各參數(shù)的Set、Get函數(shù)以及不帶參數(shù)的結(jié)構(gòu)函數(shù)。假如您對(duì)Lombok還不了解,能夠看看這篇文章:Java開(kāi)發(fā)神器Lombok的運(yùn)用與原理
@Id和@GeneratedValue用來(lái)標(biāo)識(shí)User對(duì)應(yīng)對(duì)應(yīng)數(shù)據(jù)庫(kù)表中的主鍵
注意:除了這些注解之外,還有許多用來(lái)精細(xì)化配備映射聯(lián)絡(luò)的注解,這兒不做具體介紹。后續(xù)會(huì)出專(zhuān)門(mén)一篇來(lái)介紹常用注解。讀者也能夠自行閱覽Hibernate的文檔來(lái)學(xué)習(xí)這些注解的具體運(yùn)用方法。
創(chuàng)建數(shù)據(jù)訪(fǎng)問(wèn)接口
下面針對(duì)User實(shí)體創(chuàng)建對(duì)應(yīng)的Repository接口完結(jié)對(duì)該實(shí)體的數(shù)據(jù)訪(fǎng)問(wèn),如下代碼:
publicinterfaceUserRepositoryextendsJpaRepository<User,Long>{UserfindByName(Stringname);UserfindByNameAndAge(Stringname,Integerage);@Query(“fromUseruwhereu.name=:name”)UserfindUser(@Param(“name”)Stringname);
}
在SpringDataJPA中,只需求編寫(xiě)相似上面這樣的接口就可完結(jié)數(shù)據(jù)訪(fǎng)問(wèn)。不再像我們以往編寫(xiě)了接口時(shí)分還需求自己編寫(xiě)接口完結(jié)類(lèi),直接減少了我們的文件清單。
下面對(duì)上面的UserRepository做一些解釋?zhuān)摻涌诔欣^自JpaRepository,經(jīng)過(guò)查看JpaRepository接口的API文檔,能夠看到該接口本身現(xiàn)已完結(jié)了創(chuàng)建(save)、更新(save)、刪去(delete)、查詢(xún)(findAll、findOne)等根本操作的函數(shù),因此關(guān)于這些基礎(chǔ)操作的數(shù)據(jù)訪(fǎng)問(wèn)就不需求開(kāi)發(fā)者再自己定義。
在我們實(shí)踐開(kāi)發(fā)中,JpaRepository接口定義的接口往往還不行或許功能不行優(yōu)化,我們需求進(jìn)一步完結(jié)更雜亂一些的查詢(xún)或操作。因?yàn)楸疚闹攸c(diǎn)在SpringBoot中整合spring-data-jpa,在這兒先拋磚引玉簡(jiǎn)略介紹一下spring-data-jpa中讓我們興奮的功用,后續(xù)再單獨(dú)開(kāi)篇講一下spring-data-jpa中的常見(jiàn)運(yùn)用。
在上例中,我們能夠看到下面兩個(gè)函數(shù):
UserfindByName(Stringname)
UserfindByNameAndAge(Stringname,Integerage)
它們分別完結(jié)了按name查詢(xún)User實(shí)體和按name和age查詢(xún)User實(shí)體,能夠看到我們這兒沒(méi)有任何類(lèi)SQL句子就完結(jié)了兩個(gè)條件查詢(xún)方法。這便是Spring-data-jpa的一大特性:經(jīng)過(guò)解析方法名創(chuàng)建查詢(xún)。
除了經(jīng)過(guò)解析方法名來(lái)創(chuàng)建查詢(xún)外,它也提供經(jīng)過(guò)運(yùn)用@Query注解來(lái)創(chuàng)建查詢(xún),您只需求編寫(xiě)JPQL句子,并經(jīng)過(guò)相似“:name”來(lái)映射@Param指定的參數(shù),就像比方中的第三個(gè)findUser函數(shù)相同。
SpringDataJPA的能力遠(yuǎn)不止本文說(shuō)到的這些,因?yàn)楸疚氖滓哉辖榻B為主,關(guān)于SpringDataJPA的運(yùn)用僅僅介紹了常見(jiàn)的運(yùn)用方法。比方@Modifying操作、分頁(yè)排序、原生SQL支持以及與SpringMVC的結(jié)合運(yùn)用等等內(nèi)容就不在本文中具體打開(kāi),這兒先挖個(gè)坑,后續(xù)再補(bǔ)文章填坑,如您對(duì)這些感興趣能夠重視我博客或簡(jiǎn)書(shū),同樣歡迎大家留言溝通想法。
單元測(cè)驗(yàn)
在完結(jié)了上面的數(shù)據(jù)訪(fǎng)問(wèn)接口之后,按照常規(guī)便是編寫(xiě)對(duì)應(yīng)的單元測(cè)驗(yàn)來(lái)驗(yàn)證編寫(xiě)的內(nèi)容是否正確。這兒就不多做介紹,首要經(jīng)過(guò)數(shù)據(jù)操作和查詢(xún)來(lái)反復(fù)驗(yàn)證操作的正確性。
@RunWith(SpringRunner.class)@SpringBootTestpublicclassApplicationTests{@AutowiredprivateUserRepositoryuserRepository;@Testpublicvoidtest()throwsException{//創(chuàng)建10條記載userRepository.save(newUser(“AAA”,10));
userRepository.save(newUser(“BBB”,20));
userRepository.save(newUser(“CCC”,30));
userRepository.save(newUser(“DDD”,40));
userRepository.save(newUser(“EEE”,50));
userRepository.save(newUser(“FFF”,60));
userRepository.save(newUser(“GGG”,70));
userRepository.save(newUser(“HHH”,80));
userRepository.save(newUser(“III”,90));
userRepository.save(newUser(“JJJ”,100));//測(cè)驗(yàn)findAll,查詢(xún)一切記載Assert.assertEquals(10,userRepository.findAll().size());//測(cè)驗(yàn)findByName,查詢(xún)名字為FFF的UserAssert.assertEquals(60,userRepository.findByName(“FFF”).getAge().longValue());//測(cè)驗(yàn)findUser,查詢(xún)名字為FFF的UserAssert.assertEquals(60,userRepository.findUser(“FFF”).getAge().longValue());//測(cè)驗(yàn)findByNameAndAge,查詢(xún)名字為FFF而且年紀(jì)為60的UserAssert.assertEquals(“FFF”,userRepository.findByNameAndAge(“FFF”,60).getName());//測(cè)驗(yàn)刪去名字為AAA的UseruserRepository.delete(userRepository.findByName(“AAA”));//測(cè)驗(yàn)findAll,查詢(xún)一切記載,驗(yàn)證上面的刪去是否成功Assert.assertEquals(9,userRepository.findAll().size());
}
}
拓寬閱覽:關(guān)于SpringData
SpringDataJPA在Spring家族中實(shí)踐上是一個(gè)二級(jí)項(xiàng)目,它隸屬于SpringData這個(gè)尖端項(xiàng)目。讀者能夠看一下關(guān)于這個(gè)項(xiàng)目的介紹,它除了涵蓋對(duì)聯(lián)絡(luò)型數(shù)據(jù)庫(kù)的籠統(tǒng)之外,其實(shí)還有許多對(duì)其他數(shù)據(jù)存儲(chǔ)中間件的完結(jié),比方我們常用的Redis、MongoDB、Elasticsearch等。
假如再找?guī)讉€(gè)項(xiàng)目看一下它們的簡(jiǎn)略示例,你會(huì)發(fā)現(xiàn):不管你是要訪(fǎng)問(wèn)什么數(shù)據(jù)存儲(chǔ)產(chǎn)品,它們的編碼方法簡(jiǎn)直都是相同的!這便是SpringData這個(gè)項(xiàng)目充滿(mǎn)魅力的地方!經(jīng)過(guò)對(duì)數(shù)據(jù)訪(fǎng)問(wèn)操作的籠統(tǒng)來(lái)屏蔽細(xì)節(jié),用不同子項(xiàng)目的方法去完結(jié)細(xì)節(jié)。讓開(kāi)發(fā)者只需求學(xué)會(huì)運(yùn)用SpringData,就能便利方便的學(xué)會(huì)對(duì)各種數(shù)據(jù)存儲(chǔ)的操作。所以,關(guān)于SpringData,我是強(qiáng)烈推薦Java開(kāi)發(fā)者們能夠?qū)W、甚至讀一下源碼的重要結(jié)構(gòu)。盡管,現(xiàn)在來(lái)說(shuō)許多大型互聯(lián)網(wǎng)公司并不會(huì)選擇它(功能考量居多,能真正用好它的人不多)作為首要的開(kāi)發(fā)結(jié)構(gòu),但是其背后的籠統(tǒng)思想對(duì)錯(cuò)常值得我們學(xué)習(xí)的。而且,在做一些非高并發(fā)項(xiàng)目的時(shí)分,這簡(jiǎn)直便是一個(gè)方便開(kāi)發(fā)神器,它能夠協(xié)助我們少寫(xiě)非常多的代碼!
廣州天河區(qū)珠江新城富力盈力大廈北塔2706
020-38013166(網(wǎng)站咨詢(xún)專(zhuān)線(xiàn))
400-001-5281 (售后服務(wù)熱線(xiàn))
深圳市坂田十二橡樹(shù)莊園F1-7棟
Site/ http://www.szciya.com
E-mail/ itciya@vip.163.com
品牌服務(wù)專(zhuān)線(xiàn):400-001-5281
長(zhǎng)沙市天心區(qū)芙蓉中路三段398號(hào)新時(shí)空大廈5樓
聯(lián)系電話(huà)/ (+86 0731)88282200
品牌服務(wù)專(zhuān)線(xiàn)/ 400-966-8830
旗下運(yùn)營(yíng)網(wǎng)站:
Copyright ? 2016 廣州思洋文化傳播有限公司,保留所有權(quán)利。 粵ICP備09033321號(hào)