微服務(wù)SpringDATA筆記

Spring Data

一罗售、 學(xué)習(xí)安排

Spring-data、spring-boot、spring-cloud
Spring-data是一個spring提供的數(shù)據(jù)訪問層框架崭闲。封裝若干中數(shù)據(jù)服務(wù)訪問能力。如:spring-data-jpa威蕉、spring-data-jdbc刁俭、spring-data-redis等。
Spring-data-jpa: 是通過JPA標(biāo)準(zhǔn)規(guī)范韧涨,底層使用Hibernate框架做為實現(xiàn)牍戚,開發(fā)的關(guān)系型數(shù)據(jù)庫訪問模塊。
Spring-data-jdbc: 就是底層使用Spring-jdbc實現(xiàn)的關(guān)系型數(shù)據(jù)庫訪問模塊虑粥∪缧ⅲ可以使用Mybatis技術(shù)作為底層實現(xiàn)的替代產(chǎn)品。
Spring-data-redis:底層使用jedis實現(xiàn)的訪問redis數(shù)據(jù)服務(wù)的模塊娩贷。
上述三個描述的模塊是Spring-data中詳細(xì)講解的內(nèi)容第晰。其他的模塊非常多,不可能全部講解彬祖。主要作為介紹和配置簡單描述茁瘦。

二、 Spring Data 簡介

官網(wǎng): projects.spring.io/spring-data
Spring Data’s mission is to provide a familiar and consistent, Spring-based programming model for data access while still retaining the special traits of the underlying data store.
It makes it easy to use data access technologies, relational and non-relational databases, map-reduce frameworks, and cloud-based data services. This is an umbrella project which contains many subprojects that are specific to a given database. The projects are developed by working together with many of the companies and developers that are behind these exciting technologies.
Spring Data是一個保持底層數(shù)據(jù)存儲特性的储笑,基于Spring編程模型的甜熔,數(shù)據(jù)訪問技術(shù)。
Spring Data可以簡單快速的訪問關(guān)系型數(shù)據(jù)庫南蓬、非關(guān)系型數(shù)據(jù)庫纺非、map-reduce框架和基于云的數(shù)據(jù)服務(wù)。且Spring Data的開發(fā)有這些數(shù)據(jù)服務(wù)廠商和開發(fā)人員參與赘方。
總而言之烧颖,這是一個數(shù)據(jù)訪問層框架,可以高效的訪問現(xiàn)今絕大多數(shù)數(shù)據(jù)存儲服務(wù)窄陡,可以統(tǒng)一數(shù)據(jù)訪問層技術(shù)炕淮,讓開發(fā)和維護(hù)更加方便。

三跳夭、 Spring Data JPA

Java persistence api在spring-data工程中的具體應(yīng)用涂圆。
Spring-data-jpa底層是使用Hibernate實現(xiàn)的们镜。
Spring-data-jpa1.8.x+底層依賴的是Hibernate5.x版本的框架。
課程中使用的是spring-data-jpa1.11.x版本润歉。
底層使用Hibernate實現(xiàn)是因為Hibernate本身就是JPA標(biāo)準(zhǔn)規(guī)范的實現(xiàn)框架模狭。Hibernate又是經(jīng)歷了長時間商業(yè)項目驗證的穩(wěn)定的數(shù)據(jù)訪問層框架。所以spring-data-jpa選擇的是Hibernate作為底層實現(xiàn)踩衩。
1 Spring-DATA-JPA框架提供的接口的繼承樹
Spring-Data-JPA提供了若干的Repository接口嚼鹉,提供很多的關(guān)系型數(shù)據(jù)庫訪問能力。只要對Repository接口有足夠的掌握驱富,不需要寫SQL就可以使用數(shù)據(jù)庫的訪問操作锚赤。
1.1 類圖


image.png

1.2 Repository

標(biāo)記接口『峙福可以繼承此接口线脚,根據(jù)指定的規(guī)則,實現(xiàn)數(shù)據(jù)查詢叫榕。

1.2.1 方法名稱規(guī)則查詢

這種查詢也是有局限性的浑侥。只能做單表查詢,且查詢結(jié)果一定是實體類型對象或?qū)嶓w類型對象的集合翠霍。畢竟是一個InvocationHandler實現(xiàn)的模板代碼锭吨,難以完成絕對的定制化開發(fā)。只能實現(xiàn)最基礎(chǔ)的通用的功能寒匙×闳纾互聯(lián)網(wǎng)商業(yè)項目中,有半數(shù)以上的查詢是單表查詢锄弱。
命名規(guī)則:findBy(關(guān)鍵字)+屬性名稱(屬性名稱的首字母大寫)+查詢條件(首字母大寫)

關(guān)鍵字 方法命名 sql where字句
And findByNameAndPwd where name= ? and pwd =?
Or findByNameOrSex where name= ? or sex=?
Is,Equal findById,findByIdEquals where id= ?
Between findByIdBetween where id between ? and ?
LessThan findByIdLessThan where id < ?
LessThanEqual findByIdLessThanEquals where id <= ?
GreaterThan findByIdGreaterThan where id > ?
GreaterThanEqual findByIdGreaterThanEquals where id > = ?
After findByIdAfter where id > ?
Before findByIdBefore where id < ?
IsNull findByNameIsNull where name is null
isNotNull,NotNull findByNameNotNull where name is not null
Like findByNameLike where name like ?
NotLike findByNameNotLike where name not like ?
StartingWith findByNameStartingWith where name like '?%'
EndingWith findByNameEndingWith where name like '%?'
Containing findByNameContaining where name like '%?%'
OrderBy findByIdOrderByXDesc where id=? order by x desc
Not findByNameNot where name <> ?
In findByIdIn(Collection<?> c) where id in (?)
NotIn findByIdNotIn(Collection<?> c) where id not in (?)
TRUE findByAaaTue where aaa = true
FALSE findByAaaFalse where aaa = false
IgnoreCase findByNameIgnoreCase where UPPER(name)=UPPER(?)

1.2.2 @Query注解查詢

使用@Query注解描述方法考蕾,可以繞過方法命名規(guī)則,通過編寫JPQL或SQL來實現(xiàn)數(shù)據(jù)訪問会宪。
JPQL:java persistence 通過Hibernate的HQL演變過來的肖卧。他和HQL語法及其相似。JPQL語法查詢掸鹅,可以實現(xiàn)投影查詢塞帐,可以實現(xiàn)表連接查詢,畢竟是通過一種查詢語法規(guī)則實現(xiàn)的查詢邏輯巍沙。From Users葵姥、 select username from Users、from Users u,Roles r where u.xxx = r.xxx句携。JPQL語法查詢的時候榔幸,在JPQL(1.11.14)中,傳遞參數(shù)的時候,使用變量命名的方式削咆,通過’:變量名’來定義語法中的變量牍疏,方法的參數(shù)表中,通過@Param注解拨齐,描述方法參數(shù)表中的參數(shù)和JPQL中變量的對應(yīng)關(guān)系鳞陨,注解的屬性value代表JPQL中變量的名稱。
nativeQuery: 通過SQL語法實現(xiàn)數(shù)據(jù)查詢奏黑。效率更高的執(zhí)行邏輯炊邦。因為spring-data-jpa不需要實現(xiàn)JPQL->SQL的語法轉(zhuǎn)換编矾。少了JPQL字符串的解析熟史,SQL字符串的拼接等過程,效率相對更高窄俏。
語法如下:JPQL或SQL中的變量占位符順序?qū)?yīng)方法參數(shù)表中的參數(shù)順序蹂匹。

public interface IA{
  @Query(value="JPQL")
  List xxx();
  @Query(value="SQL", nativeQuery=true)
  List yyy();
}

1.2.3 @Query注解實現(xiàn)數(shù)據(jù)寫操作

@Query注解是用于描述數(shù)據(jù)訪問語法的,所以可以執(zhí)行CRUD任意操作凹蜈。但是JPQL只能執(zhí)行查詢和更新操作限寞,SQL可以執(zhí)行CRUD任意操作。語法如下:JPQL或SQL中的變量占位符順序?qū)?yīng)方法參數(shù)表中的參數(shù)順序仰坦。

public interface IA{
  @Query(value="JPQL")
  @Modifying
  List xxx();
  @Query(value="SQL", nativeQuery=true)
  @Modifying
  List yyy();
}

1.3 CrudRepository
定義了CRUD操作的接口履植,是Repository的子接口。接口中沒有定義獨立的更新方法悄晃,調(diào)用新增數(shù)據(jù)方法(save)的時候玫霎,底層會根據(jù)方法參數(shù)決定是新增數(shù)據(jù)還是更新數(shù)據(jù)。因為底層是Hibernate妈橄,Hibernate中有方法saveOrUpdate庶近,而spring-data-jpa中提供的save方法底層使用的就是Hibernate中的saveOrUpdate方法。判斷依據(jù)眷蚓,就是數(shù)據(jù)是否存在鼻种,就是數(shù)據(jù)對象的id是否存在。
1.4 PagingAndSortingRepository
定義了分頁和排序查詢的接口沙热,是CrudRepository的子接口叉钥。
1.5 JpaRepository
PagingAndSortingRepository的子接口,提供了對緩存的處理方法篙贸。
1.6 JpaSpecificationExecutor
提供了條件查詢和分頁處理的接口投队,是一個相對獨立的接口。這個接口的使用必須配合Repository接口樹中的任意接口歉秫。

2 自定義Repository

Spring-data-jpa做開發(fā)的時候蛾洛,一般不會去定義DAO接口的實現(xiàn)類。因為spring-data-jpa會提供一個動態(tài)代理對象,動態(tài)代理對象的類型是SimpleJpaRepository轧膘。

2.1 自定義Repository接口

定義一個Repository接口钞螟,不需要繼承任何接口,定義需要的自定義方法谎碍。

2.2 定義Dao接口

定義一個Dao接口鳞滨,這個接口是服務(wù)代碼調(diào)用的。Dao接口繼承spring-data-jpa提供的Repository接口和自定義的Repository接口蟆淀。

2.3 定義Dao接口實現(xiàn)

提供一個接口實現(xiàn)類拯啦,這個實現(xiàn)類只需要實現(xiàn)自定義Repository接口,但是其類名必須和Dao接口相關(guān)熔任,命名規(guī)則為"Dao接口名Impl"褒链,如:Dao接口為UserDao,實現(xiàn)類命名為UserDaoImpl疑苔,實現(xiàn)類實現(xiàn)接口Repository甫匹。
符合上述要求的代碼spring-data-jpa會自動為Dao創(chuàng)建一個動態(tài)代理對象,這個動態(tài)代理對象會提供spring-data-jpa定義的Repository相關(guān)代碼實現(xiàn)惦费,并使用自定義的接口實現(xiàn)類提供自定義Repository接口的方法實現(xiàn)兵迅。
類圖如下:


image.png

3 Spring-data-jpa正向工程建表

在默認(rèn)情況下(spring-data-jpa 1.11.x),spring-data-jpa使用正向工程創(chuàng)建的數(shù)據(jù)庫表格薪贫,是有默認(rèn)配置的恍箭,其建表語句如下:

create table tb_users (
userid integer not null auto_increment, 
userage integer, 
username varchar(255), 
primary key (userid)
) engine=MyISAM

Spring-data-jpa默認(rèn)情況下,創(chuàng)建的MySQL數(shù)據(jù)庫表格是MyISAM引擎的表格瞧省。這種表格扯夭,適合查詢,不支持事務(wù)臀突,不支持外鍵約束勉抓。
但是,因為其不支持事務(wù)候学,所有有臟數(shù)據(jù)出現(xiàn)的可能藕筋。
可以在配置LocalContainerEntityManagerFactoryBean的時候,增加配置信息梳码,約束建表的引擎隐圾。

<!-- Spring整合JPA  配置EntityManagerFactory-->
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <!-- hibernate相關(guān)的屬性的注入 -->
                <!-- 配置數(shù)據(jù)庫類型 -->
                <property name="database" value="MYSQL"/>
                <!-- 正向工程 自動創(chuàng)建表 -->
                <property name="generateDdl" value="true"/>
                <!-- 顯示執(zhí)行的SQL -->
                <property name="showSql" value="true"/>
                <!-- 提供數(shù)據(jù)庫特性配置。和數(shù)據(jù)庫的獨特功能緊密相關(guān)掰茶。這個配置是使用Hibernate提供的Dialect來配置的暇藏。 -->
                <property name="databasePlatform" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
            </bean>
        </property>
        <!-- 掃描實體的包 -->
        <property name="packagesToScan">
            <list>
                <value>com.bjsxt.pojo</value>
            </list>
        </property>
    </bean>

修改配置后,建表語句如下:

create table tb_users (
userid integer not null auto_increment, 
userage integer, 
username varchar(255), 
primary key (userid)
) engine=InnoDB

是否需要配置數(shù)據(jù)庫特性濒蒋,由具體業(yè)務(wù)決定盐碱。一般來說把兔,商業(yè)項目中,不可能使用正向工程建表瓮顽。也就是說县好,配置應(yīng)該是<property name="generateDdl" value="false"/>

4 關(guān)聯(lián)操作

關(guān)聯(lián)操作在spring-data-jpa中主要通過JPA注解來實現(xiàn)。如:@OneToOne暖混、@OneToMany缕贡、@ManyToOne、@ManyToMany拣播、@JoinColumn晾咪、@JoinTable等。
詳見代碼贮配。

四谍倦、 Spring Data Redis

spring-data框架中的每個子模塊其版本未必一致,畢竟對應(yīng)不同數(shù)據(jù)服務(wù)的訪問層框架牧嫉,更新時間和周期是不同的剂跟。在本案例中,使用的spring-data-redis版本為1.8.14酣藻。
spring-data-redis框架的執(zhí)行需要jackson組件的輔助,建議導(dǎo)入jackson版本為2.7+(對應(yīng)當(dāng)前環(huán)境中的spring-data-redis版本)鳍置。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末辽剧,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子税产,更是在濱河造成了極大的恐慌怕轿,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件辟拷,死亡現(xiàn)場離奇詭異撞羽,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)衫冻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進(jìn)店門诀紊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人隅俘,你說我怎么就攤上這事邻奠。” “怎么了为居?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵碌宴,是天一觀的道長。 經(jīng)常有香客問我蒙畴,道長贰镣,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮碑隆,結(jié)果婚禮上董朝,老公的妹妹穿的比我還像新娘。我一直安慰自己干跛,他們只是感情好子姜,可當(dāng)我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著楼入,像睡著了一般哥捕。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上嘉熊,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天遥赚,我揣著相機(jī)與錄音,去河邊找鬼阐肤。 笑死凫佛,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的孕惜。 我是一名探鬼主播愧薛,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼衫画!你這毒婦竟也來了毫炉?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤削罩,失蹤者是張志新(化名)和其女友劉穎瞄勾,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體弥激,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡进陡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了微服。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片趾疚。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖职辨,靈堂內(nèi)的尸體忽然破棺而出盗蟆,到底是詐尸還是另有隱情,我是刑警寧澤舒裤,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布喳资,位于F島的核電站,受9級特大地震影響腾供,放射性物質(zhì)發(fā)生泄漏仆邓。R本人自食惡果不足惜鲜滩,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望节值。 院中可真熱鬧徙硅,春花似錦、人聲如沸搞疗。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽匿乃。三九已至桩皿,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間幢炸,已是汗流浹背泄隔。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留宛徊,地道東北人佛嬉。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像闸天,于是被迫代替她去往敵國和親暖呕。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容