Java EE輕量級(jí)框架應(yīng)用實(shí)戰(zhàn)-SSM框架(Spring MVC+Spring+MyBatis)(第2版)課件 第5、6章 深入使用MyBatis、初識(shí)Spring_第1頁(yè)
Java EE輕量級(jí)框架應(yīng)用實(shí)戰(zhàn)-SSM框架(Spring MVC+Spring+MyBatis)(第2版)課件 第5、6章 深入使用MyBatis、初識(shí)Spring_第2頁(yè)
Java EE輕量級(jí)框架應(yīng)用實(shí)戰(zhàn)-SSM框架(Spring MVC+Spring+MyBatis)(第2版)課件 第5、6章 深入使用MyBatis、初識(shí)Spring_第3頁(yè)
Java EE輕量級(jí)框架應(yīng)用實(shí)戰(zhàn)-SSM框架(Spring MVC+Spring+MyBatis)(第2版)課件 第5、6章 深入使用MyBatis、初識(shí)Spring_第4頁(yè)
Java EE輕量級(jí)框架應(yīng)用實(shí)戰(zhàn)-SSM框架(Spring MVC+Spring+MyBatis)(第2版)課件 第5、6章 深入使用MyBatis、初識(shí)Spring_第5頁(yè)
已閱讀5頁(yè),還剩109頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

MyBatis插件的應(yīng)用——實(shí)現(xiàn)分頁(yè)MyBatis的緩存機(jī)制MyBatis的常用注解第5章

深入使用MyBatis2024/1/29學(xué)習(xí)目標(biāo)/Target2

掌握如何使用MyBatis插件實(shí)現(xiàn)分頁(yè)

熟悉MyBatis的緩存機(jī)制

掌握MyBatis的常用注解及其使用方法章節(jié)概述/Summary3通過(guò)學(xué)習(xí)前面介紹的MyBatis的基本用法、關(guān)聯(lián)映射和動(dòng)態(tài)SQL語(yǔ)句等重要知識(shí),讀者可以了解到使用MyBatis可以很方便地通過(guò)面向?qū)ο筮M(jìn)行數(shù)據(jù)庫(kù)訪問(wèn),本章將介紹一些Web應(yīng)用程序中的分頁(yè)方式,以及合理地利用緩存來(lái)加快數(shù)據(jù)庫(kù)的查詢速度,進(jìn)而有效地提升數(shù)據(jù)庫(kù)性能的方法。前面章節(jié)中介紹的MyBatis的所有配置都是使用XML文件完成的,由于大量XML文件的編寫工作非常煩瑣,因此可以使用MyBatis提供的更加簡(jiǎn)便的注解配置。本章將介紹MyBatis的深入使用,內(nèi)容包括MyBatis插件的應(yīng)用——實(shí)現(xiàn)分頁(yè)、MyBatis的緩存機(jī)制,以及MyBatis的常用注解。目錄/CONTENTSMyBatis插件的應(yīng)用——實(shí)現(xiàn)分頁(yè)MyBatis的常用注解MyBatis的緩存機(jī)制4132MyBatis插件的應(yīng)用

——實(shí)現(xiàn)分頁(yè)01第5章深入使用MyBatis實(shí)現(xiàn)分頁(yè)功能6分頁(yè)方式分為兩種前端分頁(yè)一次性請(qǐng)求數(shù)據(jù)表格中的所有記錄(Ajax),然后在前端緩存并且計(jì)算count和分頁(yè)邏輯,一般前端組件(例如dataTable)會(huì)提供分頁(yè)動(dòng)作。特點(diǎn)是:簡(jiǎn)單,很適合小規(guī)模的web平臺(tái);當(dāng)數(shù)據(jù)量大的時(shí)候會(huì)產(chǎn)生性能問(wèn)題,在查詢和網(wǎng)絡(luò)傳輸?shù)臅r(shí)間會(huì)很長(zhǎng)。后端分頁(yè)在Ajax請(qǐng)求中指定頁(yè)碼(pageNum)和每頁(yè)的大小(pageSize),后端查詢出當(dāng)頁(yè)的數(shù)據(jù)返回,前端只負(fù)責(zé)渲染。特點(diǎn)是:復(fù)雜一些;性能瓶頸在MySQL的查詢性能,這個(gè)當(dāng)然可以調(diào)優(yōu)解決。一般來(lái)說(shuō),WEB開發(fā)使用的是這種方式。借助SQL語(yǔ)句進(jìn)行分頁(yè)7通過(guò)SQL語(yǔ)句實(shí)現(xiàn)分頁(yè)也是非常簡(jiǎn)單的,只是需要改變我們查詢的語(yǔ)句就能實(shí)現(xiàn)了,即在SQL語(yǔ)句后面添加limit分頁(yè)語(yǔ)句。簡(jiǎn)單來(lái)說(shuō)MySQL對(duì)分頁(yè)的支持是通過(guò)limit子句。請(qǐng)看下面的例子。limit關(guān)鍵字的用法是offset是相對(duì)于首行的偏移量(首行是0),rows是返回條數(shù)。MySQL的分頁(yè)功能是基于內(nèi)存的分頁(yè)查出來(lái)所有記錄,再按起始位置和頁(yè)面容量取出結(jié)果。LIMIT[offset,]rows#每頁(yè)10條記錄,取第一頁(yè),返回的是前10條記錄select*fromtableAlimit0,10;#每頁(yè)10條記錄,取第二頁(yè),返回的是第11條記錄,到第20條記錄select*fromtableAlimit10,10;借助SQL語(yǔ)句進(jìn)行分頁(yè)需求說(shuō)明:為用戶管理之查詢用戶列表功能增加分頁(yè)實(shí)現(xiàn)列表結(jié)果按照創(chuàng)建時(shí)間降序排列分頁(yè)-DAO層實(shí)現(xiàn)limit(起始位置,頁(yè)面容量)查詢用戶列表的方法增加2個(gè)參數(shù)frompageSize8演示示例:MyBatis分頁(yè)功能實(shí)現(xiàn)-用戶列表分析publicList<User>getUserList( @Param("userName")StringuserName, @Param("userRole")IntegerroleId,

@Param("from")IntegercurrentPageNo, @Param("pageSize")IntegerpageSize);<!--查詢用戶列表(分頁(yè)顯示)--><selectid="getUserList"resultMap="userList"> SELECTu.*,r.roleNameuserRoleName FROMtb_useru,dsscm_roler WHEREu.userRole=r.id <iftest="userRole!=null"> andu.userRole=#{userRole} </if> <iftest="userName!=nullanduserName!=''"> andu.userNamelikeCONCAT('%',#{userName},'%') </if> orderbycreationDateDESClimit#{from},#{pageSize}</select>分頁(yè)參數(shù)RowBounds9分頁(yè)原理通過(guò)RowBounds實(shí)現(xiàn)分頁(yè)和通過(guò)數(shù)組方式分頁(yè)原理差不多,都是一次獲取所有符合條件的數(shù)據(jù),然后在內(nèi)存中對(duì)大數(shù)據(jù)進(jìn)行操作,實(shí)現(xiàn)分頁(yè)效果。只是數(shù)組分頁(yè)需要我們自己去實(shí)現(xiàn)分頁(yè)邏輯,這里更加簡(jiǎn)化而已。RowBounds:在接口中的方法中傳入RowBounds對(duì)象。

RowBounds存在問(wèn)題:一次性從數(shù)據(jù)庫(kù)獲取的數(shù)據(jù)可能會(huì)很多,對(duì)內(nèi)存的消耗很大,可能導(dǎo)致性能變差,甚至引發(fā)內(nèi)存溢出。以對(duì)于大量的數(shù)據(jù)查詢,它的性能并不佳,此時(shí)可以通過(guò)分頁(yè)插件去處理。適用場(chǎng)景:在數(shù)據(jù)量很大的情況下,建議還是適用攔截器實(shí)現(xiàn)分頁(yè)效果。RowBounds建議在數(shù)據(jù)量相對(duì)較小的情況下使用。提示分頁(yè)參數(shù)RowBounds需求說(shuō)明:為用戶管理之查詢用戶列表功能增加分頁(yè)實(shí)現(xiàn)列表結(jié)果按照創(chuàng)建時(shí)間降序排列10publicList<User>getUserList2( @Param("userName")StringuserName, @Param("userRole")IntegerroleId, RowBoundsrowBounds);<!--查詢用戶列表(分頁(yè)顯示--RowBounds)--><selectid="getUserList2"resultType="User"> SELECTu.*,r.roleNameuserRoleName FROMtb_useru,tb_roler WHEREu.userRole=r.id <iftest="userRole!=null"> andu.userRole=#{userRole} </if> <iftest="userName!=nullanduserName!=''"> andu.userNamelikeCONCAT('%',#{userName},'%') </if> orderbycreationDateDESC</select>UserMapper.xml的getUserList查詢SQL語(yǔ)句,不需要limit關(guān)鍵字,mappep.xml里面正常配置,不用對(duì)rowBounds任何操作。MyBatis的攔截器自動(dòng)操作rowBounds進(jìn)行分頁(yè)使用PageHelper插件實(shí)現(xiàn)分頁(yè)11PageHelperPageHelper是一個(gè)MyBatis的分頁(yè)插件,負(fù)責(zé)將已經(jīng)寫好的sql語(yǔ)句,進(jìn)行分頁(yè)加工jar文件pagehelper-4.1.4.jarjsqlparser-1.1.jar使用PageHelper插件實(shí)現(xiàn)分頁(yè)12PageHelper的配置<!--com.github.pagehelper為PageHelper類所在包名--><plugininterceptor="com.github.pagehelper.PageHelper"><propertyname="dialect"value="mysql"/><!--該參數(shù)默認(rèn)為false--><!--設(shè)置為true時(shí),會(huì)將RowBounds第一個(gè)參數(shù)offset當(dāng)成pageNum頁(yè)碼使用

和startPage中的pageNum效果一樣--><propertyname="offsetAsPageNum"value="false"/><!--該參數(shù)默認(rèn)為false,

設(shè)置為true時(shí),使用RowBounds分頁(yè)會(huì)進(jìn)行count查詢--><propertyname="rowBoundsWithCount"value="true"/>

<!--設(shè)置為true時(shí),如果pageSize=0或者RowBounds.limit=0就會(huì)查詢出全部的結(jié)果--><!--(相當(dāng)于沒(méi)有執(zhí)行分頁(yè)查詢,但是返回結(jié)果仍然是Page類型)<propertyname="pageSizeZero"value="true"/>-->

<!--3.3.0版本可用-分頁(yè)參數(shù)合理化,默認(rèn)false禁用--><!--啟用合理化時(shí),如果pageNum<1會(huì)查詢第一頁(yè),如果pageNum>pages會(huì)查詢最后一頁(yè)--><!--禁用合理化時(shí),如果pageNum<1或pageNum>pages會(huì)返回空數(shù)據(jù)--><propertyname="reasonable"value="true"/><!--3.5.0版本可用-為了支持startPage(Objectparams)方法--><!--增加了一個(gè)`params`參數(shù)來(lái)配置參數(shù)映射,用于從Map或ServletRequest中取值--><!--可以配置pageNum,pageSize,count,pageSizeZero,reasonable,不配置映射的用默認(rèn)值--><!--不理解該含義的前提下,不要隨便復(fù)制該配置<propertyname="params"value="pageNum=start;pageSize=limit;"/>--></plugin>使用PageHelper插件實(shí)現(xiàn)分頁(yè)13PageHelper中Page的APItrue表示需要統(tǒng)計(jì)總數(shù),這樣會(huì)多進(jìn)行一次請(qǐng)求selectcount(0);省略掉true參數(shù)只返回分頁(yè)數(shù)據(jù)。對(duì)于統(tǒng)計(jì)總數(shù)(將SQL語(yǔ)句變?yōu)閟electcount(0)fromxxx,只對(duì)簡(jiǎn)單SQL語(yǔ)句其效果,復(fù)雜SQL語(yǔ)句需要自己寫)。Pagepage=PageHelper.startPage(pageNum,pageSize,true);Page<?>page=PageHelper.startPage(1,-1);longcount=page.getTotal();使用PageHelper插件實(shí)現(xiàn)分頁(yè)14PageHelper中Page的API在分頁(yè)參數(shù)中,pageNum表示第N頁(yè),pageSize表示每頁(yè)M條數(shù)。只分頁(yè)不統(tǒng)計(jì)(每次只執(zhí)行分頁(yè)語(yǔ)句)分頁(yè)并統(tǒng)計(jì)(每次執(zhí)行2條語(yǔ)句,一條selectcount語(yǔ)句,一條分頁(yè)語(yǔ)句)適用于查詢分頁(yè)時(shí)數(shù)據(jù)發(fā)生變動(dòng),需要將實(shí)時(shí)的變動(dòng)信息反映到分頁(yè)結(jié)果上。在使用PageHelper查全部(不分頁(yè))。Pagepage=PageHelper.startPage(pageNum,pageSize,true);PageHelper.startPage([pageNum],[pageSize]);List<?>pagelist=queryForList(xxx.class,"queryAll",param);//pagelist就是分頁(yè)之后的結(jié)果Page<?>page=PageHelper.startPage([pageNum],[pageSize],[iscount]);List<?>pagelist=queryForList(xxx.class,"queryAll",param);longcount=page.getTotal();//也可以List<?>pagelist=page.getList();獲取分頁(yè)后的結(jié)果集PageHelper.startPage(1,0);List<?>alllist=queryForList(xxx.class,"queryAll",param);使用PageHelper插件實(shí)現(xiàn)分頁(yè)需求說(shuō)明:為用戶管理之查詢用戶列表功能增加分頁(yè)實(shí)現(xiàn)列表結(jié)果按照創(chuàng)建時(shí)間降序排列15publicList<User>getUserList3(@Param("userName")StringuserName, @Param("userRole")IntegerroleId);<!--查詢用戶列表(分頁(yè)顯示)--><selectid="getUserList3"resultType="User"> SELECTu.*,r.roleNameuserRoleName FROMtb_useru,tb_roler WHEREu.userRole=r.id <iftest="userRole!=null"> andu.userRole=#{userRole} </if> <iftest="userName!=nullanduserName!=''"> andu.userNamelikeCONCAT('%',#{userName},'%') </if> orderbycreationDateDESC</select>List<User>userList=newArrayList<User>();StringuserName="";IntegerroleId=null;IntegerpageNum=1;IntegerpageSize=5;//開啟分頁(yè)P(yáng)ageHelper.startPage(pageNum,pageSize);//獲取查詢數(shù)據(jù)放入分頁(yè)對(duì)象、//查詢時(shí)無(wú)需關(guān)注查詢的條數(shù)不需要向Dao層中的方法傳入limit后邊的兩個(gè)參數(shù)(limit1,5)//調(diào)用Dao層方法userList=sqlSession.getMapper(UserMapper.class).getUserList3(userName,roleId);//封裝pageInfo對(duì)象并返回PageInfo可以看到源碼你就明白所有意思PageInfo<User>pageInfo=newPageInfo<User>(userList);for(Useruser:pageInfo.getList()){ logger.debug(user);}logger.debug("當(dāng)前頁(yè)數(shù):"+pageInfo.getPageNum());logger.debug("每頁(yè)條數(shù):"+pageInfo.getPageSize());logger.debug("總頁(yè)數(shù):"+pageInfo.getPages());logger.debug("總條數(shù):"+pageInfo.getTotal());分頁(yè)顯示供應(yīng)商列表和訂單列表16需求說(shuō)明:為供應(yīng)商管理之查詢供應(yīng)商列表功能增加分頁(yè)實(shí)現(xiàn)為訂單管理之查詢訂單列表功能增分頁(yè)實(shí)現(xiàn)列表結(jié)果按照創(chuàng)建時(shí)間降序排列分頁(yè)-DAO層實(shí)現(xiàn)limit(起始位置,頁(yè)面容量)查詢的方法增加2個(gè)參數(shù)frompageSize完成時(shí)間:20分鐘練習(xí)指導(dǎo)共性問(wèn)題集中講解17常見問(wèn)題及解決辦法代碼規(guī)范問(wèn)題調(diào)試技巧共性問(wèn)題集中講解MyBatis的緩存機(jī)制02第5章深入使用MyBatisMyBatis緩存19MyBatis緩存MyBatis提供了默認(rèn)下基于JavaHashMap的緩存實(shí)現(xiàn),以及用于與OSCache、Ehcache、Hazelcast和Memcached連接的默認(rèn)連接器。重點(diǎn)的那句話就是:MyBatis執(zhí)行SQL語(yǔ)句之后,這條語(yǔ)句就是被緩存,以后再執(zhí)行這條語(yǔ)句的時(shí)候,會(huì)直接從緩存中拿結(jié)果,而不是再次執(zhí)行SQL。MyBatis將數(shù)據(jù)緩存設(shè)計(jì)成兩級(jí)結(jié)構(gòu):一級(jí)緩存,一級(jí)緩存的作用域scope是SqlSession。二級(jí)緩存,也稱作全局緩存,作用域globalscope。一級(jí)緩存20一級(jí)緩存是Session會(huì)話級(jí)別的緩存,位于表示一次數(shù)據(jù)庫(kù)會(huì)話的SqlSession對(duì)象之中,又被稱之為本地緩存。一級(jí)緩存是MyBatis內(nèi)部實(shí)現(xiàn)的一個(gè)特性,用戶不能配置,默認(rèn)情況下自動(dòng)支持的緩存,用戶沒(méi)有定制它的權(quán)利(不過(guò)這也不是絕對(duì)的,可以通過(guò)開發(fā)插件對(duì)它進(jìn)行修改)。—級(jí)緩存是基于PerpetualCache(MyBatis自帶)的HashMap本地緩存,作用范圍為session域內(nèi),當(dāng)sessionflush或者close之后,該session中所有的cache就會(huì)被清空。STEP01

MyBatis的一級(jí)緩存是SqlSession級(jí)別的緩存。如果同一個(gè)SqlSession對(duì)象多次執(zhí)行完全相同的SQL語(yǔ)句時(shí),在第一次執(zhí)行完成后,MyBatis會(huì)將查詢結(jié)果寫入到一級(jí)緩存中,此后,如果程序沒(méi)有執(zhí)行插入、更新、刪除操作,當(dāng)?shù)诙螆?zhí)行相同的查詢語(yǔ)句時(shí),MyBatis會(huì)直接讀取一級(jí)緩存中的數(shù)據(jù),而不用再去數(shù)據(jù)庫(kù)查詢,從而提高了數(shù)據(jù)庫(kù)的查詢效率。STEP03MyBatis的一級(jí)緩存級(jí)別一級(jí)緩存21STEP01

例如,存在數(shù)據(jù)表tb_book,從表中多次查詢id為1的圖書信息,當(dāng)程序第一次查詢id為1的圖書信息時(shí),程序會(huì)將查詢結(jié)果寫入MyBatis一級(jí)緩存,當(dāng)程序第二次查詢id為1的圖書信息時(shí),MyBatis直接從一級(jí)緩存中讀取,不再訪問(wèn)數(shù)據(jù)庫(kù)進(jìn)行查詢。當(dāng)程序?qū)?shù)據(jù)庫(kù)執(zhí)行了插入、更新、刪除操作,MyBatis會(huì)清空一級(jí)緩存中的內(nèi)容以防止程序誤讀。STEP03舉例說(shuō)明MyBatis的一級(jí)緩存級(jí)別一級(jí)緩存22MyBatis如何防止程序誤讀

當(dāng)程序?qū)?shù)據(jù)庫(kù)執(zhí)行了插入、更新、刪除操作后,MyBatis會(huì)清空一級(jí)緩存中的內(nèi)容,以防止程序誤讀。MyBatis一級(jí)緩存被清空之后,再次使用SQL查詢語(yǔ)句訪問(wèn)數(shù)據(jù)庫(kù)時(shí),MyBatis會(huì)重新訪問(wèn)數(shù)據(jù)庫(kù)。例如上面的例子,首先查詢id為1的圖書信息,然后使用更新語(yǔ)句對(duì)數(shù)據(jù)庫(kù)中的圖書信息進(jìn)行更改,更改之后,再次對(duì)id為1的圖書信息進(jìn)行查詢時(shí),MyBatis依然會(huì)從數(shù)據(jù)庫(kù)中查詢。一級(jí)緩存23二級(jí)緩存24二級(jí)緩存是mapper級(jí)別的緩存。使用二級(jí)緩存時(shí),多個(gè)SqlSession使用同一個(gè)Mapper的SQL語(yǔ)句去操作數(shù)據(jù)庫(kù),得到的數(shù)據(jù)會(huì)存在二級(jí)緩存區(qū)域,它同樣是使用HashMap進(jìn)行數(shù)據(jù)存儲(chǔ)。相比一級(jí)緩存SqlSession,二級(jí)緩存的范圍更大,多個(gè)SqlSession可以共用二級(jí)緩存,二級(jí)緩存是跨SqlSession的。二級(jí)緩存是多個(gè)SqlSession共享的,其作用域是mapper的同一個(gè)namespace。不同的SqlSession兩次執(zhí)行相同的namespace下的SQL語(yǔ)句,且向SQL中傳遞的參數(shù)也相同,即最終執(zhí)行相同的SQL語(yǔ)句,則第一次執(zhí)行完畢會(huì)將數(shù)據(jù)庫(kù)中查詢的數(shù)據(jù)寫到緩存(內(nèi)存),第二次查詢時(shí)會(huì)從緩存中獲取數(shù)據(jù),不再去底層數(shù)據(jù)庫(kù)查詢,從而提高查詢效率。STEP01

由5.2節(jié)的內(nèi)容可知,相同的Mapper類,相同的SQL語(yǔ)句,如果SqlSession不同,則兩個(gè)SqlSession查詢數(shù)據(jù)庫(kù)時(shí),會(huì)查詢數(shù)據(jù)庫(kù)兩次,這樣也會(huì)降低數(shù)據(jù)庫(kù)的查詢效率。為了解決這個(gè)問(wèn)題,就需要用到MyBatis的二級(jí)緩存。MyBatis的二級(jí)緩存是Mapper級(jí)別的緩存,與一級(jí)緩存相比,二級(jí)緩存的范圍更大,多個(gè)SqlSession可以共用二級(jí)緩存,并且二級(jí)緩存可以自定義緩存資源。STEP03使用二級(jí)緩存的好處二級(jí)緩存25STEP01在MyBatis中,一個(gè)Mapper.xml文件通常稱為一個(gè)Mapper,MyBatis以namespace區(qū)分Mapper,如果多個(gè)SqlSession對(duì)象使用同一個(gè)Mapper的相同查詢語(yǔ)句去操作數(shù)據(jù)庫(kù),在第一個(gè)SqlSession對(duì)象執(zhí)行完后,MyBatis會(huì)將查詢結(jié)果寫入二級(jí)緩存,此后,如果程序沒(méi)有執(zhí)行插入、更新、刪除操作,當(dāng)?shù)诙€(gè)SqlSession對(duì)象執(zhí)行相同的查詢語(yǔ)句時(shí),MyBatis會(huì)直接讀取二級(jí)緩存中的數(shù)據(jù)。STEP03MyBatis二級(jí)緩存的執(zhí)行過(guò)程二級(jí)緩存26STEP01STEP03MyBatis二級(jí)緩存的執(zhí)行過(guò)程圖解二級(jí)緩存27STEP01

與MyBatis的一級(jí)緩存不同的是,MyBatis的二級(jí)緩存需要手動(dòng)開啟,開啟二級(jí)緩存通常要完成以下兩個(gè)步驟。STEP03二級(jí)緩存與一級(jí)緩存的不同點(diǎn)二級(jí)緩存28二級(jí)緩存29二級(jí)緩存的配置MyBatis的全局cache配置在MapperXML文件中設(shè)置緩存,默認(rèn)情況下是沒(méi)有開啟緩存的在MapperXML文件配置支持cache后,如果需要對(duì)個(gè)別查詢進(jìn)行調(diào)整,可以單獨(dú)設(shè)置cache<settings><settingname="cacheEnabled"value="true"/></settings><cacheeviction="FIFO"flushInterval="60000"size="512"readOnly="true"/><selectid="selectAll"resultType="Emp"useCache="true">STEP01

與使用二級(jí)緩存前,需要在MyBatis的核心配置mybatis-config.xml文件中通過(guò)<settings>元素開啟二級(jí)緩存的全局配置。STEP03a.開啟二級(jí)緩存的全局配置<settings> <settingname="cacheEnabled"value="true"/></settings>二級(jí)緩存30STEP01

開啟當(dāng)前Mapper的namespace下的二級(jí)緩存,可以通過(guò)MyBatis映射文件中的<cache>元素來(lái)完成。

STEP03b.開啟當(dāng)前Mapper的namespace下的二級(jí)緩存<!--開啟當(dāng)前Mapper的namespace下的二級(jí)緩存--><cache></cache>二級(jí)緩存31STEP01(1)映射文件中所有select語(yǔ)句將會(huì)被緩存。(2)映射文件中的所有insert、update和delete語(yǔ)句都會(huì)刷新緩存。(3)緩存會(huì)使用LRU算法回收。(4)沒(méi)有刷新間隔,緩存不會(huì)以任何時(shí)間順序來(lái)刷新。(5)緩存會(huì)存儲(chǔ)列表集合或?qū)ο蟮?024個(gè)引用。(6)緩存是可讀/可寫的緩存,這意味著對(duì)象檢索不是共享的,緩存可以安全的被調(diào)用者修改,而不干擾其他調(diào)用者或線程所做的潛在修改。

STEP03默認(rèn)狀態(tài)的二級(jí)緩存可實(shí)現(xiàn)的功能二級(jí)緩存32<cache>元素的屬性屬性說(shuō)明flushInterval刷新間隔。該屬性可以被設(shè)置為任意的正整數(shù),而且它們代表一個(gè)合理的毫秒形式的時(shí)間段。默認(rèn)情況下是不設(shè)置值。size引用數(shù)目。該屬性可以被設(shè)置為任意正整數(shù),默認(rèn)值為1024。readOnly只讀。該屬性可以被設(shè)置為true或者false。當(dāng)緩存設(shè)置為只讀時(shí),緩存對(duì)象不能被修改,但此時(shí)緩存性能較高。當(dāng)緩存設(shè)置為可讀寫時(shí),性能較低,但安全性高。

eviction回收策略。該屬性有4個(gè)可選值。以上是二級(jí)緩存在默認(rèn)狀態(tài)下的特性,如果需要調(diào)整上述特性,可通過(guò)<cache>元素的屬性來(lái)實(shí)現(xiàn)。LRU:最近最少使用的策略。移除最長(zhǎng)時(shí)間不被使用的對(duì)象。FIFO:先進(jìn)先出策略。按對(duì)象進(jìn)入緩存的順序來(lái)移除它們。SOFT:軟引用策略。移除基于垃圾回收器狀態(tài)和軟引用規(guī)則的對(duì)象。WEAK:弱引用策略。更積極地移除基于垃圾收集器狀態(tài)和弱引用規(guī)則的對(duì)象.二級(jí)緩存33STEP01

在實(shí)際開發(fā)中,經(jīng)常會(huì)遇到多個(gè)SqlSession在同一個(gè)Mapper中執(zhí)行操作,例如,SqlSession1執(zhí)行查詢操作,SqlSession2執(zhí)行插入、更新、刪除操作,SqlSession3又執(zhí)行和SqlSession1相同的查詢操作。當(dāng)SqlSession1執(zhí)行查詢操作時(shí),程序會(huì)將查詢結(jié)果寫入MyBatis二級(jí)緩存,當(dāng)SqlSession2對(duì)數(shù)據(jù)庫(kù)執(zhí)行了插入、更新、刪除操作后,MyBatis會(huì)清空二級(jí)緩存中的內(nèi)容,以防止程序誤讀。當(dāng)SqlSession3執(zhí)行和SqlSession1相同的查詢操作時(shí),MyBatis會(huì)重新訪問(wèn)數(shù)據(jù)庫(kù)。STEP03多個(gè)SqlSession在同一個(gè)Mapper中執(zhí)行二級(jí)緩存34MyBatis緩存機(jī)制35STEP01

終端用戶訪問(wèn)緩存時(shí),如果在緩存中查找到了要被訪問(wèn)的數(shù)據(jù),就叫做命中。如果緩存中沒(méi)有查找到要被訪問(wèn)的數(shù)據(jù),就是沒(méi)有命中。當(dāng)多次執(zhí)行查詢操作時(shí),緩存命中次數(shù)與總的查詢次數(shù)(緩存命中次數(shù)+緩存沒(méi)有命中次數(shù))的比,就叫作緩存命中率,即緩存命中率=緩存命中次數(shù)/總的查詢次數(shù)。當(dāng)MyBatis開啟二級(jí)緩存后,第一次查詢數(shù)據(jù)時(shí),由于數(shù)據(jù)還沒(méi)有進(jìn)入緩存,所以需要在數(shù)據(jù)庫(kù)中查詢而不是在緩存中查詢,此時(shí),緩存命中率為0。第一次查詢過(guò)后,MyBatis會(huì)將查詢到的數(shù)據(jù)寫入緩存中,當(dāng)?shù)诙卧俨樵兿嗤臄?shù)據(jù)時(shí),MyBatis會(huì)直接從緩存中獲取這條數(shù)據(jù),緩存將命中,此時(shí)的緩存命中率為0.5(1/2)。當(dāng)?shù)谌尾樵兿嗤臄?shù)據(jù),則緩存命中率為0.66666(2/3),以此類推。STEP03多學(xué)一招:CacheHitRatio(緩存命中率)二級(jí)緩存36MyBatis的常用注解03第5章深入使用MyBatis常用注解38MyBatis的注解位于org.apache.ibatis.annotations包下。常用的注解如下:Select映射查詢的SQL語(yǔ)句。Insert映射插入的SQL語(yǔ)句。Update映射更新的SQL語(yǔ)句。Delete映射刪除的SQL語(yǔ)句。Param當(dāng)映射器方法需要多個(gè)參數(shù)時(shí),這個(gè)注解可以被應(yīng)用于映射器方法參數(shù)來(lái)給每個(gè)參數(shù)取一個(gè)名字。否則,多參數(shù)將會(huì)以它們的順序位置和SQL語(yǔ)句中的表達(dá)式進(jìn)行映射,這是默認(rèn)的。使用@Param("id"),SQL中參數(shù)應(yīng)該被命名為#{id}。映射注解39屬性描述SelectProviderSelect語(yǔ)句的動(dòng)態(tài)SQL映射。允許指定一個(gè)類名和一個(gè)方法在執(zhí)行時(shí)返回運(yùn)行的查詢語(yǔ)句。有兩個(gè)屬性:type和method,type屬性是類的完全限定名,method是該類中的那個(gè)方法名。InsertProviderInsert語(yǔ)句的動(dòng)態(tài)SQL映射。允許指定一個(gè)類名和一個(gè)方法在執(zhí)行時(shí)返回運(yùn)行的插入語(yǔ)句。有兩個(gè)屬性:type和method,type屬性是類的完全限定名,method是該類中的那個(gè)方法名。UpdateProviderUpdate語(yǔ)句的動(dòng)態(tài)SQL映射。允許指定一個(gè)類名和一個(gè)方法在執(zhí)行時(shí)返回運(yùn)行的更新語(yǔ)句。有兩個(gè)屬性:type和method,type屬性是類的完全限定名,method是該類中的那個(gè)方法名。DeleteProviderDelete語(yǔ)句的動(dòng)態(tài)SQL映射。允許指定一個(gè)類名和一個(gè)方法在執(zhí)行時(shí)返回運(yùn)行的刪除語(yǔ)句。有兩個(gè)屬性:type和method,type屬性是類的完全限定名,method是該類中的那個(gè)方法名。Result在列和屬性之間的單獨(dú)結(jié)果映射。屬性包括:id、column、property、javaType、jdbcType、typeHandler、one、many。id屬性是一個(gè)布爾值,表示是否被用于主鍵映射。one屬性是單獨(dú)的聯(lián)系,和XML配置中的<association>相似,而many屬性是對(duì)集合而言的,和XML配置的<collection>相似。Results多個(gè)結(jié)果映射(Result)列表。Options提供配置選項(xiàng)的附加值,它們通常在映射語(yǔ)句上作為附加功能配置出現(xiàn)。One復(fù)雜類型的單獨(dú)屬性值映射。必須指定select屬性,表示己映射的SQL語(yǔ)句的完全限定名。Many復(fù)雜類型的集合屬性映射。必須指定select屬性,表示已映射的SQL語(yǔ)句的完全限定名。增刪改查注解的使用40@select、@insert、@update和@delete可以完成常見的CRUD(增刪改查)SQL語(yǔ)句映射。//查詢所有User@Select("select*fromtb_useru")publicList<User>findAllUser();//根據(jù)id查詢User@Select("select*fromtb_useruwhereu.id=#{id}")publicUserfindUserById(@Param("id")Integerid);//添加用戶@Insert("insertintotb_user(userCode,userName,userPassword,gender,birthday,phone,email,address,userDesc,userRole,createdBy,creationDate,imgPath)values(#{userCode},#{userName},#{userPassword},#{gender},#{birthday},#{phone},#{email},#{address},#{userDesc},#{userRole},#{createdBy},#{creationDate},#{imgPath})")publicintadd(Useruser);//修改用戶@Update("updatetb_usersetuserCode=#{userCode},userName=#{userName},userPassword=#{userPassword},gender=#{gender},birthday=#{birthday},phone=#{phone},email=#{email},address=#{address},userDesc=#{userDesc},userRole=#{userRole},modifyBy=#{modifyBy},modifyDate=#{modifyDate},imgPath=#{imgPath}whereid=#{id}")publicintmodify(Useruser);//根據(jù)id刪除User@Delete("deletefromtb_userwhereid=#{id}")publicintdeleteUserById(@Param("id")Integerid);關(guān)聯(lián)注解的使用41一對(duì)一一對(duì)多@Select("SELECT*FROMtb_userWHEREid=#{id}")@Results({ @Result(id=true,column="id",property="id"), @Result(column="userCode",property="userCode"), @Result(column="userName",property="userName"), @Result(column="userPassword",property="userPassword"), @Result(column="userRole",property="role",

one=@One(select="cn.dsscm.dao.UserMapper.getRoleById"))})publicUsergetUserById(@Param("id")Integerid);//根據(jù)id查詢商品類別信息@Select("SELECT*FROMtb_product_categoryWHEREID=#{id}ORDERBYid")@Results({ @Result(id=true,column="id",property="id"), @Result(column="name",property="name"), @Result(column="id",property="products",

many=@Many(select="cn.dsscm.dao.ProductMapper.getProduct"))})publicList<ProductCategory>selectById(@Param("id")Integerid);(1)property屬性用來(lái)指定關(guān)聯(lián)屬性。(2)column屬性用來(lái)指定關(guān)聯(lián)的數(shù)據(jù)庫(kù)表中的字段。(3)one屬性用來(lái)指定數(shù)據(jù)表之間屬于哪種關(guān)聯(lián)關(guān)系,通過(guò)@One注解表明數(shù)據(jù)表之間是一對(duì)一關(guān)聯(lián)關(guān)系。@Result注解的三個(gè)屬性及含義一對(duì)一查詢42動(dòng)態(tài)SQL43查詢用戶列表——使用字符串拼接@SelectProvider(type=UserDynaSqlProvider.class,method="getUserList")publicList<User>getUserList(@Param("userName")StringuserName,@Param("userRole")IntegerroleId); publicStringgetUserList(Map<String,Object>para){ Stringsql="SELECT*FROMtb_userWHERE1=1"; if(null!=para.get("userName")&&!"".equals(para.get("userName"))){ sql+="ANDuserNamelikeCONCAT('%',#{userName},'%')"; } if(null!=para.get("userRole")){ sql+="ANDuserRole=#{userRole}"; } returnsql; }注解動(dòng)態(tài)SQL類44方法說(shuō)明TSELECT(Stringcolumns)開始或追加SELECT子句,參數(shù)通常是一個(gè)逗號(hào)分隔的列表的列TFROM(Stringtable)啟動(dòng)或追加FROM子句,可以調(diào)用超過(guò)一次,這些參數(shù)通常是一個(gè)表名TJOIN(Stringjoin)向JOIN子句添加一個(gè)新的查詢條件,該參數(shù)通常是一個(gè)表,也可以包括一個(gè)標(biāo)準(zhǔn)的連接返回的結(jié)果集TINNER_JOIN(Stringjoin)同JOIN子句,連接方式是內(nèi)連接(INNER_JOIN)TLEFT_OUTER_JOIN(Stringjoin)同JOIN子句,連接方式是左外連接(LEFT_OUTER_JOIN)TRIGHT_OUTER_J0IN(Stringjoin)同JOIN子句,連接方式是右外連接(RIGHT_OUTER_JOIN)TWHERE(Stringconditions)追加一個(gè)新的WHERE子句條件,可以多次調(diào)用TOR()使用OR拆分當(dāng)前WHERE子句條件,可以不止一次被調(diào)用TAND()使用AND拆分當(dāng)前WHERE子句條件,可以不止一次被調(diào)用TGROUP_BY(Stringcolumns)追加一個(gè)新的GROUPBY子句元素THAVING(Stringconditions)追加一個(gè)新的HAVING子句條件TORDER_BY(Stringcolumns)追加一個(gè)新的ORDERBY子句元素TINSERTJNTO(StringtableName)啟動(dòng)INSERT語(yǔ)句插入到指定表,應(yīng)遵循由一個(gè)或多個(gè)VALUES()調(diào)用TVALUES(Stringcolumns,Stringvalues)追加的INSERT語(yǔ)句,第一個(gè)參數(shù)是要插入的列,第二個(gè)參數(shù)是插入的值TDELETE_FROM(Stringtable)啟動(dòng)DELETE語(yǔ)句,并指定表刪除TUPDATE(Stringtable)啟動(dòng)一個(gè)更新(UPDATE)語(yǔ)句,并指定表更新TSET(Stringsets)追加一個(gè)更新語(yǔ)句SET列表查詢用戶列表——使用注解動(dòng)態(tài)SQL類45@SelectProvider(type=UserDynaSqlProvider.class,method="getUserList2")publicList<User>getUserList2(@Param("userName")StringuserName,@Param("userRole")IntegerroleId);publicStringgetUserList2(finalMap<String,Object>para){ returnnewSQL(){ {

SELECT("*");

FROM("tb_user"); if(null!=para.get("userName")&&!"".equals(para.get("userName"))){

WHERE("userNamelikeCONCAT('%',#{userName},'%')"); } if(null!=para.get("userRole")){

WHERE("userRole=#{userRole}"); } } }.toString();}使用注解動(dòng)態(tài)SQL類——修改用戶信息46@UpdateProvider(type=UserDynaSqlProvider.class,method="modify")publicintmodify(Useruser);publicStringmodify(Useruser){ returnnewSQL(){ {

UPDATE("tb_user"); if(user.getUserCode()!=null){

SET("userCode=#{userCode}"); } if(user.getUserName()!=null){

SET("userName=#{userName}"); } if(user.getUserPassword()!=null){

SET("userPassword=#{userPassword}"); } ……

WHERE("id=#{id}"); } }.toString();}二級(jí)緩存47@CacheNamespace(eviction=LruCache.class,flushInterval=60000,size=512,readWrite=true)publicinterfaceUserMapper{

//根據(jù)id查詢User @Select("SELECT*FROMtb_userWHEREid=#{id}")

@Options(useCache=true) UserselectUserById(Integerid);

//根據(jù)id刪除User @Delete("DELETEFROMTB_USERWHEREid=#{id}") voiddeleteUserById(Integerid);

}學(xué)生表(s_student)與班級(jí)表(c_class)詳情學(xué)生idid學(xué)生姓名name學(xué)生年齡age所屬班級(jí)cid1張三1812李四1823王五1924趙六201班級(jí)idid班級(jí)名稱classname1一班2二班

現(xiàn)有一個(gè)學(xué)生表s_student(學(xué)生id、學(xué)生姓名、學(xué)生年齡、所屬班級(jí))和一個(gè)班級(jí)表c_class(班級(jí)id、班級(jí)名稱),其中,班級(jí)表c_class和學(xué)生表s_student是一對(duì)多的關(guān)系?;贛yBatis注解的學(xué)生管理程序48(1)MyBatis注解實(shí)現(xiàn)查詢操作。根據(jù)表1和表2在數(shù)據(jù)庫(kù)分別創(chuàng)建一個(gè)學(xué)生表s_student和一個(gè)班級(jí)表c_class,并查詢id為2的學(xué)生的信息。(2)MyBatis注解實(shí)現(xiàn)修改操作。修改id為4的學(xué)生的姓名修改為李雷,年齡修改為21。(3)MyBatis注解實(shí)現(xiàn)一對(duì)多查詢。查詢出二班所有學(xué)生的信息。

使用MyBatis注解實(shí)現(xiàn)下列要求基于MyBatis注解的學(xué)生管理程序49共性問(wèn)題集中講解50常見問(wèn)題及解決辦法代碼規(guī)范問(wèn)題調(diào)試技巧共性問(wèn)題集中講解本章小結(jié)

本章首先介紹了不同方式實(shí)現(xiàn)分頁(yè)顯示功能;接著介紹了MyBatis的緩存機(jī)制,包括一級(jí)緩存SqlSessicm和二級(jí)緩存mapper。使用緩存可以最大程度地減輕數(shù)據(jù)查詢壓力,提高數(shù)據(jù)庫(kù)性能本章詳細(xì)介紹了MyBatis的常用注解,包括增刪改查和一對(duì)一、一對(duì)多、動(dòng)態(tài)SQL和二級(jí)緩存的操作。

通過(guò)本章的學(xué)習(xí),讀者可以掌握數(shù)據(jù)表的分頁(yè)顯示,

并能夠使用MyBatis框架對(duì)操作實(shí)現(xiàn)緩存機(jī)制進(jìn)行處理。MyBatis中的常用注解熟練使用有助于提高項(xiàng)目的開發(fā)效率,讀者一定要多加練習(xí)。本章小結(jié)51本章作業(yè)?

本章作業(yè)簡(jiǎn)述事務(wù)的特性。簡(jiǎn)述MyBatis的數(shù)據(jù)緩存。?預(yù)習(xí)作業(yè)請(qǐng)簡(jiǎn)述Spring框架的優(yōu)點(diǎn)。請(qǐng)簡(jiǎn)述什么是Spring的IoC和DI。52問(wèn)題及作業(yè)集中問(wèn)題&課后作業(yè)Spring概述Spring的核心容器Spring的入門程序DI與IoC第6章

初識(shí)Spring2024/1/29學(xué)習(xí)目標(biāo)/Target55了解Spring的基本概念和優(yōu)點(diǎn)

理解Spring中的DI與IoC的相關(guān)概念掌握ApplicationContext的使用方法掌握屬性setter方法注入的實(shí)現(xiàn)方法章節(jié)概述/Summary56Spring致力于解決JavaEE應(yīng)用中的各種問(wèn)題,對(duì)于一個(gè)Java開發(fā)者來(lái)說(shuō),Spring框架的熟練使用是必備的技能之一。Spring具有良好的設(shè)計(jì)和分層結(jié)構(gòu),它克服了傳統(tǒng)重量型框架臃腫、低效的劣勢(shì),大大簡(jiǎn)化了項(xiàng)目開發(fā)中的技術(shù)復(fù)雜性。本章將對(duì)Spring框架的基礎(chǔ)知識(shí)進(jìn)行詳細(xì)地講解。

目錄/CONTENTSSpring概述DI與IoCSpring的入門程序Spring的核心容器571432Spring概述01第6章初識(shí)Spring什么是Spring?什么是Spring59Spring是分層的JavaSE/EEfull-stack輕量級(jí)開源框架,以IoC(InverseofControl控制反轉(zhuǎn))和AOP(AspectOrientedProgramming面向切面編程)為內(nèi)核,使用基本的JavaBean來(lái)完成以前只可能由EJB完成的工作,取代了EJB的臃腫、低效的開發(fā)模式。什么是Spring60

在實(shí)際開發(fā)中,通常服務(wù)器端在采用三層體系架構(gòu),分別為表示層(Web)、業(yè)務(wù)邏輯層(Service)、持久層(Dao),Spring對(duì)每一層都提供了技術(shù)支持。表示層業(yè)務(wù)邏輯層持久層在表示層提供了與Struts等框架的整合在業(yè)務(wù)邏輯層可以管理事務(wù)、記錄日志等在持久層可以整合MyBatis、Hibernate、JdbcTemplate等技術(shù)Spring的綠草叢61Spring輕量級(jí)框架,JavaEE的春天,當(dāng)前主流框架目標(biāo)使現(xiàn)有技術(shù)更加易用,推進(jìn)編碼最佳實(shí)踐內(nèi)容IoC容器AOP實(shí)現(xiàn)數(shù)據(jù)訪問(wèn)支持簡(jiǎn)化JDBC/ORM框架聲明式事務(wù)Web集成Spring體系結(jié)構(gòu)62Spring的體系結(jié)構(gòu)63Spring框架采用的是分層架構(gòu),它一系列的功能要素被分成20個(gè)模塊。

BeansCoreContextSpELCoreContainerTestJDBCORMOXMJMSDataAccess/IntegrationTransactionsAOPAspectsInstrumentationMessagingWebSocketServletWebPortletWebSpring的體系結(jié)構(gòu)641.CoreContainer(核心容器)BeansCoreContextSpELCoreContainer

提供了BeanFactory,Spring將管理對(duì)象稱為Bean。

提供了Spring框架的基本組成部分,包括IoC和DI功能。建立在Core和Beans模塊的基礎(chǔ)之上,它是訪問(wèn)定義和配置的任何對(duì)象的媒介。

Spring3.0后新增的模塊,是運(yùn)行時(shí)查詢和操作對(duì)象圖的強(qiáng)大的表達(dá)式語(yǔ)言。Spring的體系結(jié)構(gòu)65JDBCORMOXMJMSDataAccess/IntegrationTransactions提供了一個(gè)JDBC的抽象層,大幅度的減少了在開發(fā)過(guò)程中對(duì)數(shù)據(jù)庫(kù)操作的編碼。

提供了一個(gè)支持對(duì)象/XML映射的抽象層實(shí)現(xiàn),如JAXB、Castor、XMLBeans、JiBX和XStream。對(duì)流行的對(duì)象關(guān)系映射API,包括JPA、JDO和Hibernate提供了集成層支持。

支持對(duì)實(shí)現(xiàn)特殊接口以及所有POJO類的編程和聲明式的事務(wù)管理。指Java消息傳遞服務(wù),包含使用和產(chǎn)生信息的特性,自4.1版本后支持與Spring-message模塊的集成。2.DataAccess/Integration(數(shù)據(jù)訪問(wèn)/集成)3.WebSpring的體系結(jié)構(gòu)66WebSocketServletWebPortletWebSpring4.0以后新增的模塊,它提供了WebSocket和SockJS的實(shí)現(xiàn),以及對(duì)STOMP的支持。提供了基本的Web開發(fā)集成特性,如:多文件上傳、使用Servlet監(jiān)聽器來(lái)初始化IoC容器以及Web應(yīng)用上下文。也稱Spring-webmvc模塊,包含Spring模型—視圖—控制器(MVC)和RESTWebServices實(shí)現(xiàn)的Web程序提供了在portlet環(huán)境中使用MVC實(shí)現(xiàn),類似Servlet模塊的功能。Spring的體系結(jié)構(gòu)674.其他模塊AOPAspectsInstrumentationMessagingTest

提供了面向切面編程實(shí)現(xiàn),允許定義方法攔截器和切入點(diǎn),將代碼按照功能進(jìn)行分離,以降低耦合性。提供了類工具的支持和類加載器的實(shí)現(xiàn),可以在特定的應(yīng)用服務(wù)器中使用。提供了與AspectJ的集成功能,AspectJ是一個(gè)功能強(qiáng)大且成熟的面向切面編程(AOP)框架。

提供了對(duì)單元測(cè)試和集成測(cè)試的支持。Spring4.0以后新增的模塊,它提供了對(duì)消息傳遞體系結(jié)構(gòu)和協(xié)議的支持。Spring設(shè)計(jì)理念&核心技術(shù)68Spring設(shè)計(jì)理念Spring是面向Bean的編程Spring兩大核心技術(shù)控制反轉(zhuǎn)(IoC:InversionofControl)/依賴注入(DI:DependencyInjection)面向切面編程(AOP:AspectOrientedProgramming)目的:解耦合。實(shí)現(xiàn)每個(gè)組件時(shí)只關(guān)注組件內(nèi)部的事情要點(diǎn):明確定義組件間的接口控制反轉(zhuǎn)/依賴注入69將組件對(duì)象的控制權(quán)從代碼本身轉(zhuǎn)移到外部容器組件化的思想:分離關(guān)注點(diǎn),使用接口,不再關(guān)注實(shí)現(xiàn)依賴的注入:將組件的構(gòu)建和使用分開組件的使用組件的生產(chǎn)接口的定義運(yùn)行時(shí)注入演示:使用簡(jiǎn)單工廠Spring開發(fā)所需的jar包分為兩個(gè)部分:Spring框架包和第三方依賴包。下載地址:https://spring.io/projects/spring-framework/spring-projects/spring-framework/tree/5.3.xSpring框架包docs文件夾中包含API文檔和開發(fā)規(guī)范libs文件夾中包含JAR包和源碼Schema文件夾中包含開發(fā)所需要的schema文件Spring的下載及目錄結(jié)構(gòu)70

下載后的解壓目錄如下:STEP01

docs文件夾:該文件夾下存放Spring的相關(guān)文檔,包括開發(fā)指南、API參考文檔。

libs文件夾:該文件夾下存放開發(fā)所需的jar包和源碼。整個(gè)Spring框架由21個(gè)模塊組成,libs目錄下Spring為每個(gè)模塊都提供了三個(gè)壓縮包,因此,libs文件夾下一共有63個(gè)jar包。這63個(gè)jar包分為三類。

schema文件夾:該文件夾下存放Spring各種配置文件的XMLSchema文檔。STEP03Spring目錄結(jié)構(gòu)下文件夾介紹Spring的下載及目錄結(jié)構(gòu)71打開libs目錄可以看到60個(gè)JAR文件,具體如下:以.jar結(jié)尾的是class文件JAR包以-javadoc.jar結(jié)尾的是API文檔壓縮包以-sources.jar結(jié)尾的是源文件壓縮包Spring的下載及目錄結(jié)構(gòu)72在libs目錄中有四個(gè)Spring的基礎(chǔ)包,分別對(duì)應(yīng)Spring核心容器的四個(gè)模塊。spring-expression-5.3.26.jar

定義了Spring的表達(dá)式語(yǔ)言。spring-core-5.3.26.jar

包含Spring框架的核心工具類,Spring其它組件都要用到這個(gè)包里的類。spring-beans-5.3.26.jar

所有應(yīng)用都要用到的JAR包,它包含訪問(wèn)配置文件、創(chuàng)建和管理Bean以及進(jìn)行控制反轉(zhuǎn)或者依賴注入操作相關(guān)的所有類。spring-context-5.3.26.jar

提供了在基礎(chǔ)IoC功能上的擴(kuò)展服務(wù),還提供了許多企業(yè)級(jí)服務(wù)的支持Spring的下載及目錄結(jié)構(gòu)73Spring的下載及目錄結(jié)構(gòu)74第三方依賴包在使用Spring開發(fā)時(shí),除了要使用自帶的JAR包外,Spring的核心容器還需要依賴commons.logging的JAR包。下載地址:/proper/commons-logging/download_logging.cgiSpring框架的優(yōu)點(diǎn)75Spring具有簡(jiǎn)單、可測(cè)試和松耦合等特點(diǎn)。Spring不僅可以用于服務(wù)器端開發(fā),也可以應(yīng)用于任何Java應(yīng)用的開發(fā)中。非侵入式設(shè)計(jì)支持AOP方便解耦、簡(jiǎn)化開發(fā)12

3支持聲明式事務(wù)處理4方便程序測(cè)試5方便集成各種優(yōu)秀框架6降低JavaEEAPI的使用難度7Spring框架的7大優(yōu)點(diǎn)Spring的核心容器02第6章初識(shí)SpringSpring容器會(huì)負(fù)責(zé)控制程序之間的關(guān)系,而不是由程序代碼直接控制。Spring為我們提供了兩種核心容器,分別為BeanFactory和ApplicationContext,本節(jié)將對(duì)這兩種核心容器進(jìn)行簡(jiǎn)單介紹。概述Spring的核心容器77BeanFactorybeanFactory=newXmlBeanFactory(newFileSystemResource("F:/applicationContext.xml"));

創(chuàng)建BeanFactory實(shí)例時(shí),需要提供Spring所管理容器的詳細(xì)配置信息,這些信息通常采用XML文件形式來(lái)管理,其加載配置信息的語(yǔ)法如下:小提示:這種加載方式在實(shí)際開發(fā)中并不多用,讀者作為了解即可。XML配置文件的位置BeanFactory78ApplicationContext是BeanFactory的子接口,是另一種常用的Spring核心容器。它由org.springframework.context.ApplicationContext接口定義,不僅包含了BeanFactory的所有功能,還添加了對(duì)國(guó)際化、資源訪問(wèn)、事件傳播等方面的支持。創(chuàng)建ApplicationContext接口實(shí)例,通常采用兩種方法,具體如下:ApplicationContextapplicationContext=newClassPathXmlApplicationContext(StringconfigLocation);

ClassPathXmlApplicationContext會(huì)從類路徑classPath中尋找指定的XML配置文件,找到并裝載完成ApplicationContext的實(shí)例化工作。通過(guò)ClassPathXmlApplicationContext創(chuàng)建

ApplicationContext79通過(guò)FileSystemXmlApplicationContext創(chuàng)建

ApplicationContextapplicationContext=newFileSystemXmlApplicationContext(StringconfigLocation);

FileSystemXmlApplicationContext會(huì)從指定的文件系統(tǒng)路徑(絕對(duì)路徑)中尋找指定的XML配置文件,找到并裝載完成ApplicationContext的實(shí)例化工作。在Java項(xiàng)目中,會(huì)通過(guò)ClassPathXmlApplicationContext類來(lái)實(shí)例化ApplicationContext容器。而在Web項(xiàng)目中,ApplicationContext容器的實(shí)例化工作會(huì)交由Web服務(wù)器來(lái)完成。Web服務(wù)器實(shí)例化ApplicationContext容器時(shí),通常會(huì)使用ContextLoaderListener來(lái)實(shí)現(xiàn),此種方式只需要在web.xml中添加如下代碼:<context-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring/applicationContext.xml</param-value></context-param><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener>ApplicationContext80

創(chuàng)建Spring容器后,就可以獲取Spring容器中的Bean。Spring獲取Bean的實(shí)例通常采用以下兩種方法:ObjectgetBean(Stringname);根據(jù)容器中Bean的id或name來(lái)獲取指定的Bean,獲取之后需要進(jìn)行強(qiáng)制類型轉(zhuǎn)換。<T>TgetBean(Class<T>requiredType);根據(jù)類的類型來(lái)獲取Bean的實(shí)例。由于此方法為泛型方法,因此在獲取Bean之后不需要進(jìn)行強(qiáng)制類型轉(zhuǎn)換。ApplicationContext81Spring的入門程序03第6章初識(shí)Spring創(chuàng)建工程:在IntelliJIDEA中,創(chuàng)建一個(gè)Maven項(xiàng)目,然后在pom.xml文件中加載需使用到的Spring的4個(gè)基礎(chǔ)包,即spring-core-5.3.26.jar、spring-beans-5.3.26.jar、spring-context-5.3.26.jar和spring-expression-5.3.26.jar。除此之外,還需要將Spring依賴包c(diǎn)ommons-logging-1.2.RELEASE.jar也加載到項(xiàng)目中。Spring的入門程序83STEP01<!--Spring的基礎(chǔ)包Spring-core--><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>5.3.26</version></dependency><!--Spring的基礎(chǔ)包Spring-beans--><dependency><groupId>org.springframework</groupId><artifactId>spring-beans</artifactId><version>5.3.26</version></dependency><!--Spring的基礎(chǔ)包Spring-context--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.26</version></dependency><!--Spring的基礎(chǔ)包Spring-expressinon--><dependency><groupId>org.springframework</groupId><artifactId>spring-expression</artifactId><version>5.3.26</version></dependency><!--Spring的依賴包c(diǎn)ommons-logging--><dependency><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId><version>1.2</version></dependency>創(chuàng)建HelloSpring.java在src/main/java目錄下,創(chuàng)建一個(gè)cn.springdemo包,并在包中創(chuàng)建HelloSpring.java,然后在類中定義一個(gè)print()方法publicclassHelloSpring{//定義who屬性,該屬性的值將通過(guò)Spring框架進(jìn)行設(shè)置

privateStringwho=nul

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論