125.mybatis 中 #{}和 ${}的區(qū)別是什么?
'#{}'是預(yù)編譯處理宣决,KaTeX parse error: Expected 'EOF', got '#' at position 21: …串替換雕憔; Mybatis在處理#?{}時缤骨,會將sql中的#{}替…{}時族操,就是把${}替換成變量的值停忿;
使用#{}可以有效的防止SQL注入,提高系統(tǒng)安全性可婶。
126.mybatis 有幾種分頁方式沿癞?
- 數(shù)組分頁
- sql分頁
- 攔截器分頁
- RowBounds分頁
127.RowBounds 是一次性查詢?nèi)拷Y(jié)果嗎?為什么矛渴?
128.mybatis 邏輯分頁和物理分頁的區(qū)別是什么椎扬?
物理分頁速度上并不一定快于邏輯分頁惫搏,邏輯分頁速度上也并不一定快于物理分頁。
物理分頁總是優(yōu)于邏輯分頁:沒有必要將屬于數(shù)據(jù)庫端的壓力加諸到應(yīng)用端來蚕涤,就算速度上存在優(yōu)勢,然而其它性能上的優(yōu)點足以彌補這個缺點筐赔。
129.mybatis 是否支持延遲加載?延遲加載的原理是什么揖铜?
Mybatis僅支持association關(guān)聯(lián)對象和collection關(guān)聯(lián)集合對象的延遲加載茴丰,association指的就是一對一,collection指的就是一對多查詢天吓。在Mybatis配置文件中贿肩,可以配置是否啟用延遲加載lazyLoadingEnabled=true|false。
它的原理是龄寞,使用CGLIB創(chuàng)建目標(biāo)對象的代理對象汰规,當(dāng)調(diào)用目標(biāo)方法時,進(jìn)入攔截器方法物邑,比如調(diào)用a.getB().getName()溜哮,攔截器invoke()方法發(fā)現(xiàn)a.getB()是null值,那么就會單獨發(fā)送事先保存好的查詢關(guān)聯(lián)B對象的sql色解,把B查詢上來茂嗓,然后調(diào)用a.setB(b),于是a的對象b屬性就有值了冒签,接著完成a.getB().getName()方法的調(diào)用在抛。這就是延遲加載的基本原理。
當(dāng)然了萧恕,不光是Mybatis刚梭,幾乎所有的包括Hibernate,支持延遲加載的原理都是一樣的票唆。
130.說一下 mybatis 的一級緩存和二級緩存朴读?
一級緩存: 基于 PerpetualCache 的 HashMap 本地緩存,其存儲作用域為 Session走趋,當(dāng) Session flush 或 close 之后衅金,該 Session 中的所有 Cache 就將清空,默認(rèn)打開一級緩存簿煌。
二級緩存與一級緩存其機(jī)制相同氮唯,默認(rèn)也是采用 PerpetualCache,HashMap 存儲姨伟,不同在于其存儲作用域為 Mapper(Namespace)惩琉,并且可自定義存儲源,如 Ehcache夺荒。默認(rèn)不打開二級緩存瞒渠,要開啟二級緩存良蒸,使用二級緩存屬性類需要實現(xiàn)Serializable序列化接口(可用來保存對象的狀態(tài)),可在它的映射文件中配置 ;
對于緩存數(shù)據(jù)更新機(jī)制伍玖,當(dāng)某一個作用域(一級緩存 Session/二級緩存Namespaces)的進(jìn)行了C/U/D 操作后嫩痰,默認(rèn)該作用域下所有 select 中的緩存將被 clear。
131.mybatis 和 hibernate 的區(qū)別有哪些窍箍?
(1)Mybatis和hibernate不同串纺,它不完全是一個ORM框架,因為MyBatis需要程序員自己編寫Sql語句仔燕。
(2)Mybatis直接編寫原生態(tài)sql造垛,可以嚴(yán)格控制sql執(zhí)行性能魔招,靈活度高晰搀,非常適合對關(guān)系數(shù)據(jù)模型要求不高的軟件開發(fā),因為這類軟件需求變化頻繁办斑,一但需求變化要求迅速輸出成果外恕。但是靈活的前提是mybatis無法做到數(shù)據(jù)庫無關(guān)性,如果需要實現(xiàn)支持多種數(shù)據(jù)庫的軟件乡翅,則需要自定義多套sql映射文件鳞疲,工作量大。
(3)Hibernate對象/關(guān)系映射能力強(qiáng)蠕蚜,數(shù)據(jù)庫無關(guān)性好尚洽,對于關(guān)系模型要求高的軟件,如果用hibernate開發(fā)可以節(jié)省很多代碼靶累,提高效率腺毫。
132.mybatis 有哪些執(zhí)行器(Executor)?
Mybatis有三種基本的執(zhí)行器(Executor):
SimpleExecutor:每執(zhí)行一次update或select挣柬,就開啟一個Statement對象潮酒,用完立刻關(guān)閉Statement對象。
ReuseExecutor:執(zhí)行update或select邪蛔,以sql作為key查找Statement對象急黎,存在就使用,不存在就創(chuàng)建侧到,用完后勃教,不關(guān)閉Statement對象,而是放置于Map內(nèi)匠抗,供下一次使用故源。簡言之,就是重復(fù)使用Statement對象戈咳。
BatchExecutor:執(zhí)行update(沒有select心软,JDBC批處理不支持select)壕吹,將所有sql都添加到批處理中(addBatch()),等待統(tǒng)一執(zhí)行(executeBatch())删铃,它緩存了多個Statement對象耳贬,每個Statement對象都是addBatch()完畢后,等待逐一執(zhí)行executeBatch()批處理猎唁。與JDBC批處理相同咒劲。
133.mybatis 分頁插件的實現(xiàn)原理是什么?
分頁插件的基本原理是使用Mybatis提供的插件接口诫隅,實現(xiàn)自定義插件腐魂,在插件的攔截方法內(nèi)攔截待執(zhí)行的sql,然后重寫sql逐纬,根據(jù)dialect方言蛔屹,添加對應(yīng)的物理分頁語句和物理分頁參數(shù)。
134.mybatis 如何編寫一個自定義插件豁生?
Mybatis自定義插件針對Mybatis四大對象(Executor兔毒、StatementHandler 、ParameterHandler 甸箱、ResultSetHandler )進(jìn)行攔截育叁,具體攔截方式為:
Executor:攔截執(zhí)行器的方法(log記錄)
StatementHandler :攔截Sql語法構(gòu)建的處理
ParameterHandler :攔截參數(shù)的處理
ResultSetHandler :攔截結(jié)果集的處理
Mybatis自定義插件必須實現(xiàn)Interceptor接口:
public interface Interceptor {
Object intercept(Invocation invocation) throws Throwable;
Object plugin(Object target);
void setProperties(Properties properties);
}
intercept方法:攔截器具體處理邏輯方法
plugin方法:根據(jù)簽名signatureMap生成動態(tài)代理對象
setProperties方法:設(shè)置Properties屬性
自定義插件demo:
// ExamplePlugin.java
@Intercepts({@Signature(
type= Executor.class,
method = "update",
args = {MappedStatement.class,Object.class})})
public class ExamplePlugin implements Interceptor {
public Object intercept(Invocation invocation) throws Throwable {
Object target = invocation.getTarget(); //被代理對象
Method method = invocation.getMethod(); //代理方法
Object[] args = invocation.getArgs(); //方法參數(shù)
// do something ...... 方法攔截前執(zhí)行代碼塊
Object result = invocation.proceed();
// do something .......方法攔截后執(zhí)行代碼塊
return result;
}
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
public void setProperties(Properties properties) {
}
}
一個@Intercepts可以配置多個@Signature,@Signature中的參數(shù)定義如下:
type:表示攔截的類芍殖,這里是Executor的實現(xiàn)類豪嗽;
method:表示攔截的方法,這里是攔截Executor的update方法豌骏;
args:表示方法參數(shù)龟梦。