鎖屏面試題百日百刷-Mybatis篇(一)
鎖屏面試題百日百刷,每個工作日堅持更新面試題。鎖屏面試題app、小程式現已上線,官網地址:https://www.demosoftware.cc/#/introductionPage。已收錄了每日更新的面試題的所有內容,還包含特色的解鎖螢幕複習面試題、每日程式設計題目郵件推送等功能。讓你在面試中先人一步,吊打面試官!接下來的是今日的面試題:
====Mybatis 中#和$的區別?
#相當於對資料 加上 雙引號,$相當於直接顯示資料
1. #將傳入的資料都當成一個字串,會對自動傳入的資料加一個雙引號。如:order by #user_id#,如果傳入的值是111,那麼解析成 sql 時的值為
2. $將傳入的資料直接顯示生成在 sql 中。如:order by $user_id$,如果傳入的值是 111,那麼解析成 sql 時的值為order by 111, 如果傳入的值是 id,則解析成的 sql 為 order by id.
3. #方式能夠很大程度防止 sql 注入。$方式無法防止 Sql 注入。
4.$方式一般用於傳入資料庫物件,例如傳入表名.
5.一般能用#的就別用$.
====Mybatis 的程式設計步驟是什麼樣的?
1、建立 SqlSessionFactory
// 根據 mybatis-config.xml 配置的資訊得到 sqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
2、通過 SqlSessionFactory 建立 SqlSession
3、通過 sqlsession
4、呼叫 session.commit()提交事務
5、呼叫 session.close()關閉會話
====JDBC 程式設計有哪些不足之處,MyBatis 是如何解決這些問題的?
1. 資料庫連結建立、釋放頻繁造成系統資源浪費從而影響系統性能,如果使用資料庫連結池可解決此問題。
解決:在 SqlMapConfig.xml 中配置資料鏈接池,使用連線池管理資料庫連結。
2. Sql 語句寫在程式碼中造成程式碼不易維護,實際應用 sql 變化的可能較大,sql 變動需要改變 java 程式碼。
解決:將 Sql 語句配置在 XXXXmapper.xml 檔案中與 java 程式碼分離。
3. 向 sql 語句傳引數麻煩,因為 sql 語句的 where 條件不一定,可能多也可能少,佔位符需要和引數一一對應。
解決: Mybatis 自動將 java 物件對映至 sql 語句。
4. 對結果集解析麻煩,sql 變化導致解析程式碼變化,且解析前需要遍歷,如果能將資料庫記錄封裝成 pojo 物件解析比較方便。
解決:Mybatis 自動將 sql 執行結果對映至 java 物件。
====使用 MyBatis 的 mapper 介面呼叫時有哪些要求?
1. Mapper 介面方法名和 mapper.xml 中定義的每個 sql 的 id 相同
2. Mapper 介面方法的輸入引數型別和 mapper.xml 中定義的每個 sql 的 parameterType 的型別相同
3. Mapper 介面方法的輸出引數型別和 mapper.xml 中定義的每個 sql 的 resultType 的型別相同
4. Mapper.xml 檔案中的 namespace 即是 mapper 介面的類路徑。
====講一講Mybatis 中一級快取與二級快取?
1. 一級快取: 基於 PerpetualCache 的 HashMap 本地快取,其儲存作用域為 Session,當 Session flush 或
close 之後,該 Session 中的所有 Cache 就將清空。
2. 二級快取與一級快取其機制相同,預設也是採用 PerpetualCache,HashMap 儲存,不同在於其儲存作用域為Mapper(Namespace),並且可自定義儲存源,如 Ehcache。作用域為 namespance 是指對該 namespance 對應的配置檔案中所有的 select 操作結果都快取,這樣不同執行緒之間就可以共用二級快取。啟動二級快取:在 mapper 配置檔案中配置<cache />節點。
<mapper namespace="com.yihaomen.mybatis.dao.StudentMapper">
<!--開啟本mapper的namespace下的二級快取-->
<!--
eviction:代表的是快取回收策略,目前MyBatis提供以下策略。
(1) LRU,最近最少使用的,一處最長時間不用的物件
(2) FIFO,先進先出,按物件進入快取的順序來移除他們
(3) SOFT,軟引用,移除基於垃圾回收器狀態和軟引用規則的物件
(4) WEAK,弱引用,更積極的移除基於垃圾收集器狀態和弱引用規則的物件。這裡採用的是LRU,移除最長時間不用的對形象
flushInterval:重新整理間隔時間,單位為毫秒,這裡配置的是100秒重新整理,如果你不配置它,那麼當SQL被執行的時候才會去重新整理快取。
size:引用數目,一個正整數,代表快取最多可以儲存多少個物件,不宜設定過大。設定過大會導致記憶體溢位。這裡配置的是1024個物件
readOnly:只讀,意味著快取資料只能讀取而不能修改,這樣設定的好處是我們可以快速讀取快取,缺點是我們沒有辦法修改快取,他的預設值是false,不允許我們修改-->
<cache eviction="LRU" flushInterval="100000" readOnly="true" size="1024"/>
</mapper>
3.對於快取資料更新機制,當某一個作用域(一級快取 Session/二級快取 Namespaces)的進行了 C/U/D 操作後,預設該作用域下所有 select 中的快取將被 clear。
====MyBatis 如何設定在 insert 插入操作時返回主鍵 ID?
資料庫為 MySql 時:
<insert id="insert" parameterType="com.test.User" keyProperty="userId"
useGeneratedKeys="true" > “keyProperty”表示返回的 id 要儲存到物件的那個屬性中,“useGeneratedKeys”表示主鍵 id 為自增長模式。
MySQL 中做以上配置就 OK 了
資料庫為 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。
更多面試題可關注"demo鎖屏面試題"公眾號通過小程式或App獲取面試題和學習資源