Mybatis面試整理


  1. #{}和${}的區別

    • #{}是預編譯處理,${}是字符串替換。

    • Mybatis在處理#{}時,會將sql中的#{}替換為?號,調用PreparedStatement的set方法來賦值;

    • Mybatis在處理${}時,就是把${}替換成變量的值。使用#{}可以有效的防止SQL注入,提高系統安全性。

  2. 當實體類中的屬性名和表中的字段名不一樣,如果將查詢的結果封裝到指定pojo

    • 通過在查詢的sql語句中定義字段名的別名

    • 通過<resultMap>來映射字段名和實體類屬性名的一一對應的關系.

  3. 模糊查詢like語句該怎么寫

    • 在java中拼接通配符,通過#{}賦值

    • 在Sql語句中拼接通配符 (不安全 會引起Sql注入)

  4. 通常一個Xml映射文件,都會寫一個Dao接口與之對應, Dao的工作原理,是否可以重載

    • 不能重載,因為通過Dao尋找Xml對應的sql的時候全限名+方法名的保存和尋找策略。

    • 接口工作原理為jdk動態代理原理,運行時會為dao生成proxy,代理對象會攔截接口方法,去執行對應的sql返回數據

  5. Mybatis是如何進行分頁的,分頁插件實現的原理

    • Mybatis使用RowBounds對象進行分頁,也可以直接編寫sql實現分頁,也可以使用Mybatis的分頁插件

    • 分頁插件的原理:實現Mybatis提供的接口,實現自定義插件,在插件的攔截方法內攔截待執行的sql,然后重寫sql。

  6. Xml映射文件中,除了常見的select|insert|updae|delete標簽之外,還有哪些標簽

    • <resultMap>、<parameterMap>、<sql>、<include>、<selectKey>加上動態sql的標簽,比如where|set|foreach|if|choose|when|otherwise

    • <sql>為sql片段,<include>引入sql片段

  7. Mybatis動態sql是做什么的?都有哪些動態sql?簡述一下動態sql的執行原理

    • Mybatis動態sql可以讓我們在Xml映射文件內,以標簽的形式編寫動態sql,完成邏輯判斷和動態拼接sql的功能,Mybatis提供了9種動態sql標簽trim|where|set|foreach|if|choose|when|otherwise|bind。

    • 使用OGNL從sql參數對象中計算表達式的值,根據表達式的值動態拼接sql,以此來完成動態sql的功能。

  8. Mybatis是如何將sql執行結果封裝為目標對象並返回的?都有哪些映射形式

    • 第一種是使用 標簽,逐一定義列名和對象屬性名之間的映射關系。第二種是使用sql列的別名功能,將列別名書寫為對象屬性名

    • 有了列名與屬性名的映射關系后,Mybatis通過反射創建對象,同時使用反射給對象的屬性逐一賦值並返回,那些找不到映射關系的屬性,是無法完成賦值的。

  9. Mybatis能執行一對一、一對多的關聯查詢嗎?都有哪些實現方式,以及它們之間的區別

    • Mybatis不僅可以執行一對一、一對多的關聯查詢,還可以執行多對一,多對多的關聯查詢,多對一查詢,其實就是一對一查詢,只需要把selectOne()修改為selectList()即可;多對多查詢,其實就是一對多查詢,只需要把selectOne()修改為selectList()即可。

    • 一種是單獨發送一個sql去查詢關聯對象,賦給主對象,然后返回主對象。另一種是使用嵌套查詢,嵌套查詢的含義為使用join查詢,一部分列是A對象的屬性值,另外一部分列是關聯對象B的屬性值,好處是只發一個sql查詢,就可以把主對象和其關聯對象查出來。其去重復的原理是 標簽內的 子標簽,指定了唯一確定一條記錄的id列,

  10. Mybatis是否支持延遲加載

    • Mybatis僅支持association關聯對象和collection關聯集合對象的延遲加載,association指的就是一對一,collection指的就是一對多查詢。在Mybatis配置文件中,可以配置是否啟用延遲加載lazyLoadingEnabled=true|false。
  11. Mybatis的Xml映射文件中,不同的Xml映射文件,id是否可以重復

    • 不同的Xml映射文件,如果配置了namespace,那么id可以重復;如果沒有配置namespace,那么id不能重復;畢竟namespace不是必須的,只是最佳實踐而已。原因就是namespace+id是作為Map<String, MappedStatement>的key使用的,如果沒有namespace,就剩下id,那么,id重復會導致數據互相覆蓋。有了namespace,自然id就可以重復,namespace不同,namespace+id自然也就不同。
  12. 如何進行批處理

    • 使用BatchExecutor完成批處理。
  13. Mybatis都有哪些Executor執行器?它們之間的區別是什么

    • Mybatis有三種基本的Executor執行器,SimpleExecutor、ReuseExecutor、BatchExecutor。

    • SimpleExecutor:每執行一次update或select,就開啟一個Statement對象,用完立刻關閉Statement對象。

    • ReuseExecutor:執行update或select,以sql作為key查找Statement對象,存在就使用,不存在就創建,用完后,不關閉Statement對象,而是放置於Map<String, Statement>內,供下一次使用。簡言之,就是重復使用Statement對象。

    • 批處理

  14. Mybatis中如何指定使用哪一種Executor執行器

    • 在Mybatis配置文件中,可以指定默認的ExecutorType執行器類型,也可以手動給DefaultSqlSessionFactory的創建SqlSession的方法傳遞ExecutorType類型參數。
  15. Mybatis映射文件中,如果A標簽通過include引用了B標簽的內容,位置問題

    • 被引用的B標簽依然可以定義在任何地方,Mybatis都可以正確識別。在訪問A標簽時會標記B標簽,然后等全部標簽解析完畢會再一次重新解析標記的標簽
  16. 為什么說Mybatis是半自動ORM映射工具?它與全自動的區別在哪里

    • Hibernate屬於全自動ORM映射工具,使用Hibernate查詢關聯對象或者關聯集合對象時,可以根據對象關系模型直接獲取,所以它是全自動的。而Mybatis在查詢關聯對象或關聯集合對象時,需要手動編寫sql來完成,所以,稱之為半自動ORM映射工具。
  17. 如何獲取自動生成的(主)鍵值

    • 配置文件設置usegeneratedkeys 為true
  18. 在mapper中如何傳遞多個參數

    • 直接在方法中傳遞參數,xml文件用#{0} #{1}來獲取

    • 使用 @param 注解:這樣可以直接在xml文件中通過#{name}來獲取

  19. Mybatis對象關聯實例

    • 在單表查詢中,屬性名和數據庫相同的字段可以省略,多表不可省略,省略則為空

      // 一對一
      <resultMap type="Orders" id="orders">
          <result column="id" property="id"/>
      
          <association property="user" javaType="User">
          //關聯另一張表
              <id column="id" property="id"/>   // id
              <result column="name" property="name"></result>  // 屬性 即查詢出來顯示的名字
          </association>
      </resultMap>
      
      <select id="onemany" resultMap="orders">
          select u.id ,o.number,o.dic,u.name from orders o left JOIN user u on o.user_id=u.id
      </select>		
      
      // 一對多
      <resultMap type="User" id="user">
          <id column="id" property="id"/>
          <result column="name" property="name"/>
          <!-- 一對多 -->
          <collection property="list2" ofType="Orders">   // ofType : 每個屬性的類型
              <id column="oid" property="id"/>   //需要設置id,如果兩個對象屬性相同,則會視為一條記錄
              <result column="number" property="number"/>
          </collection>
      </resultMap>
      <select id="selectUserList" resultMap="user">
          select u.id,o.id as oid,o.number,o.dic,u.name from user u left JOIN orders o on o.user_id=u.id
      </select>
      
      
  20. resultType resultMap的區別

    • 類的名字和數據庫相同時,可以直接設置resultType參數為Pojo類

    • 若不同,需要設置resultMap 將結果名字和Pojo名字進行轉換,

  21. Map 直接#{key}就可以取得對應的值


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM