鎖屏面試題百日百刷-Mybatis篇(一)

? ? ? ?鎖屏面試題百日百刷,每個工作日堅持更新面試題。鎖屏面試題App、小程序現(xiàn)已上線,官網(wǎng)地址:https://www.demosoftware.cc/#/introductionPage。已收錄了每日更新的面試題的所有內(nèi)容,還包含特色的解鎖屏幕復(fù)習(xí)面試題、每日編程題目郵件推送等功能。讓你在面試中先人一步,吊打面試官!接下來的是今日的面試題:
====Mybatis 中#和$的區(qū)別?
#相當(dāng)于對數(shù)據(jù) 加上 雙引號,$相當(dāng)于直接顯示數(shù)據(jù)
1. #將傳入的數(shù)據(jù)都當(dāng)成一個字符串,會對自動傳入的數(shù)據(jù)加一個雙引號。如:order by #user_id#,如果傳入的值是111,那么解析成 sql 時的值為 order by "111", 如果傳入的值是 id,則解析成的 sql 為 order by "id".
2. $將傳入的數(shù)據(jù)直接顯示生成在 sql 中。如:order by $user_id$,如果傳入的值是 111,那么解析成 sql 時的值為order by 111, 如果傳入的值是 id,則解析成的 sql 為 order by id.
3. #方式能夠很大程度防止 sql 注入。$方式無法防止 Sql 注入。
4.$方式一般用于傳入數(shù)據(jù)庫對象,例如傳入表名.
5.一般能用#的就別用$.
?
====Mybatis 的編程步驟是什么樣的?
1、創(chuàng)建 SqlSessionFactory
// 根據(jù) mybatis-config.xml 配置的信息得到 sqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new ?SqlSessionFactoryBuilder().build(inputStream);
2、通過 SqlSessionFactory 創(chuàng)建 SqlSession
3、通過 sqlsession 執(zhí)行數(shù)據(jù)庫操作
4、調(diào)用 session.commit()提交事務(wù)
5、調(diào)用 session.close()關(guān)閉會話
?
====JDBC 編程有哪些不足之處,MyBatis 是如何解決這些問題的?
?
1. 數(shù)據(jù)庫鏈接創(chuàng)建、釋放頻繁造成系統(tǒng)資源浪費從而影響系統(tǒng)性能,如果使用數(shù)據(jù)庫鏈接池可解決此問題。
解決:在 SqlMapConfig.xml 中配置數(shù)據(jù)鏈接池,使用連接池管理數(shù)據(jù)庫鏈接。
2. Sql 語句寫在代碼中造成代碼不易維護,實際應(yīng)用 sql 變化的可能較大,sql 變動需要改變 java 代碼。
解決:將 Sql 語句配置在 XXXXmApper.xml 文件中與 java 代碼分離。
3. 向 sql 語句傳參數(shù)麻煩,因為 sql 語句的 where 條件不一定,可能多也可能少,占位符需要和參數(shù)一一對應(yīng)。
解決: Mybatis 自動將 java 對象映射至 sql 語句。
4. 對結(jié)果集解析麻煩,sql 變化導(dǎo)致解析代碼變化,且解析前需要遍歷,如果能將數(shù)據(jù)庫記錄封裝成 pojo 對象解析比較方便。
解決:Mybatis 自動將 sql 執(zhí)行結(jié)果映射至 java 對象。
?
====使用 MyBatis 的 mApper 接口調(diào)用時有哪些要求?
1. MApper 接口方法名和 mApper.xml 中定義的每個 sql 的 id 相同
2. MApper 接口方法的輸入?yún)?shù)類型和 mApper.xml 中定義的每個 sql 的 parameterType 的類型相同
3. MApper 接口方法的輸出參數(shù)類型和 mApper.xml 中定義的每個 sql 的 resultType 的類型相同
4. MApper.xml 文件中的 namespace 即是 mApper 接口的類路徑。
?
====Mybatis 中一級緩存與二級緩存?
1. 一級緩存: 基于 PerpetualCache 的 HashMap 本地緩存,其存儲作用域為 Session,當(dāng) Session flush 或
close 之后,該 Session 中的所有 Cache 就將清空。
2. 二級緩存與一級緩存其機制相同,默認(rèn)也是采用 PerpetualCache,HashMap 存儲,不同在于其存儲作用域為MApper(Namespace),并且可自定義存儲源,如 Ehcache。作用域為 namespance 是指對該 namespance 對應(yīng)的配置文件中所有的 select 操作結(jié)果都緩存,這樣不同線程之間就可以共用二級緩存。啟動二級緩存:在 mApper 配置文件中配置<cache />節(jié)點。
<mApper namespace="com.yihaomen.mybatis.dao.StudentMApper">
????<!--開啟本mApper的namespace下的二級緩存-->
????<!--
eviction:代表的是緩存回收策略,目前MyBatis提供以下策略。
????????(1) LRU,最近最少使用的,一處最長時間不用的對象
????????(2) FIFO,先進先出,按對象進入緩存的順序來移除他們
????????(3) SOFT,軟引用,移除基于垃圾回收器狀態(tài)和軟引用規(guī)則的對象
????????(4) WEAK,弱引用,更積極的移除基于垃圾收集器狀態(tài)和弱引用規(guī)則的對象。這里采用的是LRU,移除最長時間不用的對形象
flushInterval:刷新間隔時間,單位為毫秒,這里配置的是100秒刷新,如果你不配置它,那么當(dāng)SQL被執(zhí)行的時候才會去刷新緩存。
??????size:引用數(shù)目,一個正整數(shù),代表緩存最多可以存儲多少個對象,不宜設(shè)置過大。設(shè)置過大會導(dǎo)致內(nèi)存溢出。這里配置的是1024個對象
??????readOnly:只讀,意味著緩存數(shù)據(jù)只能讀取而不能修改,這樣設(shè)置的好處是我們可以快速讀取緩存,缺點是我們沒有辦法修改緩存,他的默認(rèn)值是false,不允許我們修改-->
????<cache eviction="LRU" flushInterval="100000" readOnly="true" size="1024"/>
</mApper>
3.?對于緩存數(shù)據(jù)更新機制,當(dāng)某一個作用域(一級緩存 Session/二級緩存 Namespaces)的進行了 C/U/D 操作后,默認(rèn)該作用域下所有 select 中的緩存將被 clear。
====MyBatis 如何設(shè)置在 insert 插入操作時返回主鍵 ID?
數(shù)據(jù)庫為 MySql 時:
<insert id="insert" parameterType="com.test.User" keyProperty="userId"
useGeneratedKeys="true" > “keyProperty”表示返回的 id 要保存到對象的那個屬性中,“useGeneratedKeys”表示主鍵 id 為自增長模式。
MySQL 中做以上配置就 OK 了
數(shù)據(jù)庫為 Oracle 時:
?<insert id="insert" parameterType="com.test.User">
? <selectKey resultType="INTEGER" order="BEFORE" keyProperty="userId">
SELECT SEQ_USER.NEXTVAL as userId from DUAL
</selectKey>
insert into user (user_id, user_name, modified, state)
values (#{userId,jdbcType=INTEGER}, #{userName,jdbcType=VARCHAR},
#{modified,jdbcType=TIMESTAMP}, #{state,jdbcType=INTEGER})
</insert>
由于 Oracle 沒有自增長一說法,只有序列這種模仿自增的形式,所以不能再使用“useGeneratedKeys”屬性。而是使用<selectKey>將 ID 獲取并賦值到對象的屬性中,insert 插入操作時正常插入 id。
?
? ? ? ?更多面試題可關(guān)注"demo鎖屏面試題"公眾號通過小程序或App獲取面試題和學(xué)習(xí)資源
