1.Mybatis是一個(gè)半ORM(對(duì)象關(guān)系映射)框架,它內(nèi)部封裝了JDBC,開(kāi)發(fā)時(shí)只需要關(guān)注SQL語(yǔ)句本身,不需要花費(fèi)精力去處理加載驅(qū)動(dòng)、創(chuàng)建連接、創(chuàng)建statement等繁雜的過(guò)程;
2.MyBatis 可以使用 XML 或注解來(lái)配置和映射原生信息,將 POJO映射成數(shù)據(jù)庫(kù)中的記錄,避免了幾乎所有的 JDBC 代碼和手動(dòng)設(shè)置參數(shù)以及獲取結(jié)果集;
3.通過(guò)xml 文件或注解的方式將要執(zhí)行的各種 statement 配置起來(lái),并通過(guò)java對(duì)象和 statement中MySQL的動(dòng)態(tài)參數(shù)進(jìn)行映射生成最終執(zhí)行的sql語(yǔ)句,最后由mybatis框架執(zhí)行sql并將結(jié)果映射為java對(duì)象并返回。
1.創(chuàng)建SqlSessionFactory
2.通過(guò)SqlSessionFactory創(chuàng)建SqlSession
3.通過(guò)SqlSession執(zhí)行數(shù)據(jù)庫(kù)操作
4.調(diào)用SqlSession的commit()方法提交事務(wù)
5.調(diào)用SqlSession的close()方法關(guān)閉會(huì)話(huà)
1.基于SQL語(yǔ)句編程,相對(duì)靈活,接觸sql與程序代碼的藕合,便于統(tǒng)一管理,支持寫(xiě)動(dòng)態(tài)sql語(yǔ)句并可重復(fù)使用;
2.減少代碼量,消除了冗余代碼;
3.數(shù)據(jù)庫(kù)兼容能夠與Spring集成;
4.提供映射標(biāo)簽支持字段關(guān)系映射;
1.SQL語(yǔ)句的編寫(xiě)工作量較大,尤其當(dāng)字段多、關(guān)聯(lián)表多時(shí),對(duì)開(kāi)發(fā)人員編寫(xiě)SQL的功底有一定要求;
2.SQL語(yǔ)句依賴(lài)于數(shù)據(jù)庫(kù),導(dǎo)致數(shù)據(jù)庫(kù)移植性差,不能隨意更換數(shù)據(jù)庫(kù)。
1.傳入的參數(shù)在SQL中顯示不同
#傳入的參數(shù)在SQL中相當(dāng)占位符,#方式能夠很大程度防止sql注入;而$傳入的參數(shù)在SQL中相當(dāng)字符串,$方式無(wú)法防止Sql注入.
--------------------------------------------
例:使用以下SQL
1)select id,name,age from student where name=#{name};
2)select id,name,age from student where name =${name}:
當(dāng)我們傳遞的參數(shù)name為 "‘zs ' or 1=1" 時(shí),上述 sql分別會(huì)解析為:
select id,name,age from student where id ="‘zs' or 1=1"
select id,name,age from student where id =‘zs' or 1=1
這樣第二條sql語(yǔ)句的會(huì)查出所有學(xué)生的信息,這是非常不安全的,有sql注入的風(fēng)險(xiǎn)。所以#可以防止SQL注入的風(fēng)險(xiǎn)(語(yǔ)句的拼接);但$無(wú)法防止Sql注入。
------------------------------------------------------
2.$方式一般用于傳入數(shù)據(jù)庫(kù)對(duì)象,例如傳入表名。
3.大多數(shù)情況下還是經(jīng)常使用#,但有些情況下必須使用$,例:MyBatis排序時(shí)使用order by 動(dòng)態(tài)參數(shù)時(shí)需要注意,用$而不是#。
1.一級(jí)緩存 Mybatis的一級(jí)緩存是指SQLSession,一級(jí)緩存的作用域是SQlSession, Mabits默認(rèn)開(kāi)啟一級(jí)緩存。 在同一個(gè)SqlSession中,執(zhí)行相同的SQL查詢(xún)時(shí);第一次會(huì)去查詢(xún)數(shù)據(jù)庫(kù),并寫(xiě)在緩存中,第二次會(huì)直接從緩存中取。 當(dāng)執(zhí)行SQL時(shí)候兩次查詢(xún)中間發(fā)生了增刪改的操作,則SQLSession的緩存會(huì)被清空。 每次查詢(xún)會(huì)先去緩存中找,如果找不到,再去數(shù)據(jù)庫(kù)查詢(xún),然后把結(jié)果寫(xiě)到緩存中。 Mybatis的內(nèi)部緩存使用一個(gè)HashMap,key為hashcode+statementId+sql語(yǔ)句。Value為查詢(xún)出來(lái)的結(jié)果集映射成的java對(duì)象。 SqlSession執(zhí)行insert、update、delete等操作commit后會(huì)清空該SQLSession緩存。
2.二級(jí)緩存 二級(jí)緩存是mapper級(jí)別的,Mybatis默認(rèn)是沒(méi)有開(kāi)啟二級(jí)緩存的。 第一次調(diào)用mapper下的SQL去查詢(xún)用戶(hù)的信息,查詢(xún)到的信息會(huì)存放代該mapper對(duì)應(yīng)的二級(jí)緩存區(qū)域。 第二次調(diào)用namespace下的mapper映射文件中,相同的sql去查詢(xún)用戶(hù)信息,會(huì)去對(duì)應(yīng)的二級(jí)緩存內(nèi)取結(jié)果。 如果調(diào)用相同namespace下的mapepr映射文件中增刪改sql,并執(zhí)行了commit操作,此時(shí)會(huì)情況該
Mybatis 使用 RowBounds 對(duì)象進(jìn)行分頁(yè),它是針對(duì) ResultSet 結(jié)果集執(zhí)行的內(nèi) 存分頁(yè),而非物理分頁(yè)。可以在 sql 內(nèi)直接書(shū)寫(xiě)帶有物理分頁(yè)的參數(shù)來(lái)完成物理分 頁(yè)功能,也可以使用分頁(yè)插件來(lái)完成物理分頁(yè)。 分頁(yè)插件的基本原理是使用 Mybatis 提供的插件接口,實(shí)現(xiàn)自定義插件,在插件 的攔截方法內(nèi)攔截待執(zhí)行的 sql,然后重寫(xiě) sql,根據(jù) dialect 方言,添加對(duì)應(yīng)的物 理分頁(yè)語(yǔ)句和物理分頁(yè)參數(shù)。舉例:select * from student,攔截sql后重寫(xiě)為:select t.* from (select * from student)t limit 0,10
Mybatis使用JDK的動(dòng)態(tài)代理,為需要攔截的接口生成代理對(duì)象以實(shí)現(xiàn)接口方法攔截功能,每當(dāng)執(zhí)行這4種接口對(duì)象的方法時(shí),就會(huì)進(jìn)入攔截方法,具體就是InvocationHandler的invoke()方法。
1)在MyBatis配置文件中,可以配置是否啟用延遲加載lazyLoadingEnabled=true|false。MyBatis僅支持association關(guān)聯(lián)對(duì)象和collection關(guān)聯(lián)集合對(duì)象的延遲加載,association指的就是一對(duì)一,collection指的就是一對(duì)多查詢(xún)。
2)它的原理是,使用CGLIB創(chuàng)建目標(biāo)對(duì)象的代理對(duì)象,當(dāng)調(diào)用目標(biāo)方法時(shí),進(jìn)入攔截器方法,比如調(diào)用a.getB().getName(),攔截器invoke()方法發(fā)現(xiàn)a.getB()是null值,那么就會(huì)單獨(dú)發(fā)送事先保存好的查詢(xún)關(guān)聯(lián)B對(duì)象的sql,把B查詢(xún)上來(lái),然后調(diào)用a.setB(b),于是a的對(duì)象b屬性就有值了,接著完成a.getB().getName()方法的調(diào)用。這就是延遲加載的基本原理。
1.Mybatis和hibernate不同,它不完全是一個(gè)ORM框架,因?yàn)镸yBatis需要程序員自己編寫(xiě)Sql語(yǔ)句。
2.Mybatis直接編寫(xiě)原生態(tài)sql,可以嚴(yán)格控制sql執(zhí)行性能,靈活度高,非常適合對(duì)關(guān)系數(shù)據(jù)模型要求不高的軟件開(kāi)發(fā),因?yàn)檫@類(lèi)軟件需求變化頻繁,一但需求變化要求迅速輸出成果。但是靈活的前提是mybatis無(wú)法做到數(shù)據(jù)庫(kù)無(wú)關(guān)性,如果需要實(shí)現(xiàn)支持多種數(shù)據(jù)庫(kù)的軟件,則需要自定義多套sql映射文件,工作量大。
3.Hibernate對(duì)象/關(guān)系映射能力強(qiáng),數(shù)據(jù)庫(kù)無(wú)關(guān)性好,對(duì)于關(guān)系模型要求高的軟件,如果用hibernate開(kāi)發(fā)可以節(jié)省很多代碼,提高效率。
1)在 sql 里面變量命名有原來(lái)的#變量# 變成了#{變量}
2)原來(lái)的$變量$變成了${變量}
3)原來(lái)在 sql 節(jié)點(diǎn)里面的 class 都換名字交 type
4)原來(lái)的 queryForObject queryForList 變成了 selectOne selectList
5)原來(lái)的別名設(shè)置在映射文件里面放在了核心配置文件里
1. IBatis 里面的核心處理類(lèi)交 SqlMapClient,MyBatis 里面的核心處理類(lèi)叫做 SqlSession