摘要:一級(jí)緩存值得注意的地方默認(rèn)就是支持一級(jí)緩存的,并不需要我們配置和整合后進(jìn)行代理開發(fā),不支持一級(jí)緩存,和整合,按照的模板去生成代理對象,模板中在最后統(tǒng)一關(guān)閉??偨Y(jié)的一級(jí)緩存是級(jí)別的。
前言
本文主要講解Mybatis的以下知識(shí)點(diǎn):
Mybatis緩存
一級(jí)緩存
二級(jí)緩存
與Ehcache整合
Mapper代理
使用Mapper代理就不用寫實(shí)現(xiàn)類了
逆向工程
自動(dòng)生成代碼
Mybatis緩存緩存的意義
將用戶經(jīng)常查詢的數(shù)據(jù)放在緩存(內(nèi)存)中,用戶去查詢數(shù)據(jù)就不用從磁盤上(關(guān)系型數(shù)據(jù)庫數(shù)據(jù)文件)查詢,從緩存中查詢,從而提高查詢效率,解決了高并發(fā)系統(tǒng)的性能問題。
mybatis提供一級(jí)緩存和二級(jí)緩存
mybatis一級(jí)緩存是一個(gè)SqlSession級(jí)別,sqlsession只能訪問自己的一級(jí)緩存的數(shù)據(jù)
二級(jí)緩存是跨sqlSession,是mapper級(jí)別的緩存,對于mapper級(jí)別的緩存不同的sqlsession是可以共享的。
看完上面對Mybatis的緩存的解釋,我們發(fā)現(xiàn)Mybatis的緩存和Hibernate的緩存是極為相似的..
Mybatis一級(jí)緩存Mybatis的一級(jí)緩存原理:
第一次發(fā)出一個(gè)查詢sql,sql查詢結(jié)果寫入sqlsession的一級(jí)緩存中,緩存使用的數(shù)據(jù)結(jié)構(gòu)是一個(gè)map
key:hashcode+sql+sql輸入?yún)?shù)+輸出參數(shù)(sql的唯一標(biāo)識(shí))
value:用戶信息
同一個(gè)sqlsession再次發(fā)出相同的sql,就從緩存中取不走數(shù)據(jù)庫。如果兩次中間出現(xiàn)commit操作(修改、添加、刪除),本sqlsession中的一級(jí)緩存區(qū)域全部清空,下次再去緩存中查詢不到所以要從數(shù)據(jù)庫查詢,從數(shù)據(jù)庫查詢到再寫入緩存。
Mybatis一級(jí)緩存值得注意的地方:
Mybatis默認(rèn)就是支持一級(jí)緩存的,并不需要我們配置.
mybatis和spring整合后進(jìn)行mapper代理開發(fā),不支持一級(jí)緩存,mybatis和spring整合,spring按照mapper的模板去生成mapper代理對象,模板中在最后統(tǒng)一關(guān)閉sqlsession。
Mybatis二級(jí)緩存二級(jí)緩存原理:
二級(jí)緩存的范圍是mapper級(jí)別(mapper同一個(gè)命名空間),mapper以命名空間為單位創(chuàng)建緩存數(shù)據(jù)結(jié)構(gòu),結(jié)構(gòu)是map
需要我們在Mybatis的配置文件中配置二級(jí)緩存
上面已經(jīng)說了,二級(jí)緩存的范圍是mapper級(jí)別的,因此我們的Mapper如果要使用二級(jí)緩存,還需要在對應(yīng)的映射文件中配置..
查詢結(jié)果映射的pojo序列化
mybatis二級(jí)緩存需要將查詢結(jié)果映射的pojo實(shí)現(xiàn) java.io.serializable接口,如果不實(shí)現(xiàn)則拋出異常:
org.apache.ibatis.cache.CacheException: Error serializing object. Cause: java.io.NotSerializableException: cn.itcast.mybatis.po.User
二級(jí)緩存可以將內(nèi)存的數(shù)據(jù)寫到磁盤,存在對象的序列化和反序列化,所以要實(shí)現(xiàn)java.io.serializable接口。
如果結(jié)果映射的pojo中還包括了pojo,都要實(shí)現(xiàn)java.io.serializable接口。
對于變化頻率較高的sql,需要禁用二級(jí)緩存:
在statement中設(shè)置useCache=false可以禁用當(dāng)前select語句的二級(jí)緩存,即每次查詢都會(huì)發(fā)出sql去查詢,默認(rèn)情況是true,即該sql使用二級(jí)緩存。、、
刷新緩存有的同學(xué)到這里可能會(huì)有一個(gè)疑問:為什么緩存我們都是在查詢語句中配置??而使用增刪改的時(shí)候,緩存默認(rèn)就會(huì)被清空【刷新了】???
緩存其實(shí)就是為我們的查詢服務(wù)的,對于增刪改而言,如果我們的緩存保存了增刪改后的數(shù)據(jù),那么再次讀取時(shí)就會(huì)讀到臟數(shù)據(jù)了!
我們在特定的情況下,還可以多帶帶配置刷新緩存【但不建議使用】flushCache,默認(rèn)是的true
了解Mybatis緩存的一些參數(shù)update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}
mybatis的cache參數(shù)只適用于mybatis維護(hù)緩存。
flushInterval(刷新間隔)可以被設(shè)置為任意的正整數(shù),而且它們代表一個(gè)合理的毫秒形式的時(shí)間段。默認(rèn)情況是不設(shè)置,也就是沒有刷新間隔,緩存僅僅調(diào)用語句時(shí)刷新。 size(引用數(shù)目)可以被設(shè)置為任意正整數(shù),要記住你緩存的對象數(shù)目和你運(yùn)行環(huán)境的可用內(nèi)存資源數(shù)目。默認(rèn)值是1024。 readOnly(只讀)屬性可以被設(shè)置為true或false。只讀的緩存會(huì)給所有調(diào)用者返回緩存對象的相同實(shí)例。因此這些對象不能被修改。這提供了很重要的性能優(yōu)勢??勺x寫的緩存會(huì)返回緩存對象的拷貝(通過序列化)。這會(huì)慢一些,但是安全,因此默認(rèn)是false。 如下例子:mybatis和ehcache緩存框架整合這個(gè)更高級(jí)的配置創(chuàng)建了一個(gè) FIFO 緩存,并每隔 60 秒刷新,存數(shù)結(jié)果對象或列表的 512 個(gè)引用,而且返回的對象被認(rèn)為是只讀的,因此在不同線程中的調(diào)用者之間修改它們會(huì)導(dǎo)致沖突。可用的收回策略有, 默認(rèn)的是 LRU: 1.LRU – 最近最少使用的:移除最長時(shí)間不被使用的對象。 2.FIFO – 先進(jìn)先出:按對象進(jìn)入緩存的順序來移除它們。 3.SOFT – 軟引用:移除基于垃圾回收器狀態(tài)和軟引用規(guī)則的對象。 4.WEAK – 弱引用:更積極地移除基于垃圾收集器狀態(tài)和弱引用規(guī)則的對象。
ehcache是專門用于管理緩存的,Mybatis的緩存交由ehcache管理會(huì)更加得當(dāng)..
在mybatis中提供一個(gè)cache接口,只要實(shí)現(xiàn)cache接口就可以把緩存數(shù)據(jù)靈活的管理起來。
整合jar包mybatis-ehcache-1.0.2.jar
ehcache-core-2.6.5.jar
ehcache對cache接口的實(shí)現(xiàn)類:
ehcache.xml配置信息這個(gè)xml配置文件是配置全局的緩存管理方案
如果我們Mapper想多帶帶擁有一些特性,需要在mapper.xml中多帶帶配置
應(yīng)用場景與局限性 應(yīng)用場景
對查詢頻率高,變化頻率低的數(shù)據(jù)建議使用二級(jí)緩存。
對于訪問多的查詢請求且用戶對查詢結(jié)果實(shí)時(shí)性要求不高,此時(shí)可采用mybatis二級(jí)緩存技術(shù)降低數(shù)據(jù)庫訪問量,提高訪問速度
業(yè)務(wù)場景比如:
耗時(shí)較高的統(tǒng)計(jì)分析sql、
電話賬單查詢sql等。
實(shí)現(xiàn)方法如下:通過設(shè)置刷新間隔時(shí)間,由mybatis每隔一段時(shí)間自動(dòng)清空緩存,根據(jù)數(shù)據(jù)變化頻率設(shè)置緩存刷新間隔flushInterval,比如設(shè)置為30分鐘、60分鐘、24小時(shí)等,根據(jù)需求而定。
局限性mybatis局限性
mybatis二級(jí)緩存對細(xì)粒度的數(shù)據(jù)級(jí)別的緩存實(shí)現(xiàn)不好,比如如下需求:對商品信息進(jìn)行緩存,由于商品信息查詢訪問量大,但是要求用戶每次都能查詢最新的商品信息,此時(shí)如果使用mybatis的二級(jí)緩存就無法實(shí)現(xiàn)當(dāng)一個(gè)商品變化時(shí)只刷新該商品的緩存信息而不刷新其它商品的信息,因?yàn)閙ybaits的二級(jí)緩存區(qū)域以mapper為單位劃分,當(dāng)一個(gè)商品信息變化會(huì)將所有商品信息的緩存數(shù)據(jù)全部清空。解決此類問題需要在業(yè)務(wù)層根據(jù)需求對數(shù)據(jù)有針對性緩存。
Mapper代理方式Mapper代理方式的意思就是:程序員只需要寫dao接口,dao接口實(shí)現(xiàn)對象由mybatis自動(dòng)生成代理對象。
經(jīng)過我們上面的幾篇博文,我們可以發(fā)現(xiàn)我們的DaoImpl是十分重復(fù)的...
1 dao的實(shí)現(xiàn)類中存在重復(fù)代碼,整個(gè)mybatis操作的過程代碼模板重復(fù)(先創(chuàng)建sqlsession、調(diào)用sqlsession的方法、關(guān)閉sqlsession)
2、dao的實(shí)現(xiàn) 類中存在硬編碼,調(diào)用sqlsession方法時(shí)將statement的id硬編碼。
以前的重復(fù)代碼和硬編碼如下:
public class StudentDao { public void add(Student student) throws Exception { //得到連接對象 SqlSession sqlSession = MybatisUtil.getSqlSession(); try{ //映射文件的命名空間.SQL片段的ID,就可以調(diào)用對應(yīng)的映射文件中的SQL sqlSession.insert("StudentID.add", student); sqlSession.commit(); }catch(Exception e){ e.printStackTrace(); sqlSession.rollback(); throw e; }finally{ MybatisUtil.closeSqlSession(); } } public static void main(String[] args) throws Exception { StudentDao studentDao = new StudentDao(); Student student = new Student(3, "zhong3", 10000D); studentDao.add(student); } }Mapper開發(fā)規(guī)范
想要Mybatis幫我們自動(dòng)生成Mapper代理的話,我們需要遵循以下的規(guī)范:
1、mapper.xml中namespace指定為mapper接口的全限定名
此步驟目的:通過mapper.xml和mapper.java進(jìn)行關(guān)聯(lián)。
2、mapper.xml中statement的id就是mapper.java中方法名
3、mapper.xml中statement的parameterType和mapper.java中方法輸入?yún)?shù)類型一致
4、mapper.xml中statement的resultType和mapper.java中方法返回值類型一致.
再次說明:statement就是我們在mapper.xml文件中命名空間+sql指定的id
Mapper代理返回值問題mapper接口方法返回值:
如果是返回的單個(gè)對象,返回值類型是pojo類型,生成的代理對象內(nèi)部通過selectOne獲取記錄
如果返回值類型是集合對象,生成的代理對象內(nèi)部通過selectList獲取記錄。
Mybatis解決JDBC編程的問題1、數(shù)據(jù)庫鏈接創(chuàng)建、釋放頻繁造成系統(tǒng)資源浪費(fèi)從而影響系統(tǒng)性能,如果使用數(shù)據(jù)庫鏈接池可解決此問題。
解決:在SqlMapConfig.xml中配置數(shù)據(jù)鏈接池,使用連接池管理數(shù)據(jù)庫鏈接。
2、Sql語句寫在代碼中造成代碼不易維護(hù),實(shí)際應(yīng)用sql變化的可能較大,sql變動(dòng)需要改變java代碼。
解決:將Sql語句配置在XXXXmapper.xml文件中與java代碼分離。
3、向sql語句傳參數(shù)麻煩,因?yàn)閟ql語句的where條件不一定,可能多也可能少,占位符需要和參數(shù)一一對應(yīng)。
解決:Mybatis自動(dòng)將java對象映射至sql語句,通過statement中的parameterType定義輸入?yún)?shù)的類型。
4、對結(jié)果集解析麻煩,sql變化導(dǎo)致解析代碼變化,且解析前需要遍歷,如果能將數(shù)據(jù)庫記錄封裝成pojo對象解析比較方便。
解決:Mybatis自動(dòng)將sql執(zhí)行結(jié)果映射至java對象,通過statement中的resultType定義輸出結(jié)果的類型。
Mybatis逆向工程在Intellij idea下,沒有學(xué)習(xí)Maven的情況下使用Mybatis的逆向工程好像有點(diǎn)復(fù)雜,資料太少了...找到的資料好像也行不通...
于是學(xué)完Maven之后,我就再來更新Idea下使用Mybatis的逆向工程配置...
借鑒博文:http://blog.csdn.net/for_my_life/article/details/51228098
修改pom.xml文件向該工程添加逆向工程插件..
generatorConfig.xml配置文件4.0.0 asdf asdf 1.0-SNAPSHOT zhongfucheng org.mybatis.generator mybatis-generator-maven-plugin 1.3.2 true true
使用插件步驟 最后生成代碼
如果對我們上面generatorConfig.xml配置的包信息不清楚的話,那么可以看一下我們的完整項(xiàng)目結(jié)構(gòu)圖...
因?yàn)槲覀冊贗dea下是不用寫對應(yīng)的工程名字的,而在eclipse是有工程名字的。
總結(jié)Mybatis的一級(jí)緩存是sqlSession級(jí)別的。只能訪問自己的sqlSession內(nèi)的緩存。如果Mybatis與Spring整合了,Spring會(huì)自動(dòng)關(guān)閉sqlSession的。所以一級(jí)緩存會(huì)失效的。
一級(jí)緩存的原理是map集合,Mybatis默認(rèn)就支持一級(jí)緩存
二級(jí)緩存是Mapper級(jí)別的。只要在Mapper命名空間下都可以使用二級(jí)緩存。需要我們自己手動(dòng)去配置二級(jí)緩存
Mybatis的緩存我們可以使用Ehcache框架來進(jìn)行管理,Ehcache實(shí)現(xiàn)Cache接口就代表使用Ehcache來環(huán)境Mybatis緩存。
由于之前寫的DaoImpl是有非常多的硬編碼的??梢允褂肕apper代理的方式來簡化開發(fā)
命名空間要與JavaBean的全類名相同
sql片段語句的id要與Dao接口的方法名相同
方法的參數(shù)和返回值要與SQL片段的接收參數(shù)類型和返回類型相同。
> 如果文章有錯(cuò)的地方歡迎指正,大家互相交流。**習(xí)慣在微信看技術(shù)文章,想要獲取更多的Java資源的同學(xué),可以關(guān)注微信公眾號(hào):Java3y**
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/68781.html
摘要:前言由于寫的文章已經(jīng)是有點(diǎn)多了,為了自己和大家的檢索方便,于是我就做了這么一個(gè)博客導(dǎo)航。 前言 由于寫的文章已經(jīng)是有點(diǎn)多了,為了自己和大家的檢索方便,于是我就做了這么一個(gè)博客導(dǎo)航。 由于更新比較頻繁,因此隔一段時(shí)間才會(huì)更新目錄導(dǎo)航哦~想要獲取最新原創(chuàng)的技術(shù)文章歡迎關(guān)注我的公眾號(hào):Java3y Java3y文章目錄導(dǎo)航 Java基礎(chǔ) 泛型就這么簡單 注解就這么簡單 Druid數(shù)據(jù)庫連接池...
摘要:有必要建一個(gè)資源服務(wù)器存放靜態(tài)資源。一些用戶級(jí)別的數(shù)據(jù)輕量可以考慮存儲(chǔ)在中。存儲(chǔ)的是值,可以通過來對和對象之間的轉(zhuǎn)換如果我們的數(shù)據(jù)是在后臺(tái)傳過去或者轉(zhuǎn)換而成的,在前臺(tái)上并沒有做什么改變的話。 移動(dòng)商城項(xiàng)目總結(jié) 移動(dòng)商城項(xiàng)目是我第二個(gè)做得比較大的項(xiàng)目,該項(xiàng)目系統(tǒng)來源于傳智Java168期,十天的視頻課程(想要視頻的同學(xué)關(guān)注我的公眾號(hào)就可以直接獲取了) 通過這次的項(xiàng)目又再次開闊了我的視野,...
摘要:如問到是否使用某框架,實(shí)際是是問該框架的使用場景,有什么特點(diǎn),和同類可框架對比一系列的問題。這兩個(gè)方向的區(qū)分點(diǎn)在于工作方向的側(cè)重點(diǎn)不同。 [TOC] 這是一份來自嗶哩嗶哩的Java面試Java面試 32個(gè)核心必考點(diǎn)完全解析(完) 課程預(yù)習(xí) 1.1 課程內(nèi)容分為三個(gè)模塊 基礎(chǔ)模塊: 技術(shù)崗位與面試 計(jì)算機(jī)基礎(chǔ) JVM原理 多線程 設(shè)計(jì)模式 數(shù)據(jù)結(jié)構(gòu)與算法 應(yīng)用模塊: 常用工具集 ...
摘要:哪吒社區(qū)技能樹打卡打卡貼函數(shù)式接口簡介領(lǐng)域優(yōu)質(zhì)創(chuàng)作者哪吒公眾號(hào)作者架構(gòu)師奮斗者掃描主頁左側(cè)二維碼,加入群聊,一起學(xué)習(xí)一起進(jìn)步歡迎點(diǎn)贊收藏留言前情提要無意間聽到領(lǐng)導(dǎo)們的談話,現(xiàn)在公司的現(xiàn)狀是碼農(nóng)太多,但能獨(dú)立帶隊(duì)的人太少,簡而言之,不缺干 ? 哪吒社區(qū)Java技能樹打卡?【打卡貼 day2...
閱讀 1210·2021-11-10 11:35
閱讀 2951·2021-09-24 10:35
閱讀 2975·2021-09-22 15:38
閱讀 2815·2019-08-30 15:43
閱讀 1349·2019-08-29 18:39
閱讀 2592·2019-08-29 15:22
閱讀 2802·2019-08-28 18:17
閱讀 619·2019-08-26 13:37