MyBatis概念性面試題整理匯總
MyBatis常見的概念性面試題
一、概念性填空題
1、#{}和$ {}的區別是什么?#{}是_____,${}是_____。
2、四個核心接口是()用於執行CRUD操作、()處理SQL的參數、()處理返回結果集、()用於執行SQL語句。
3、MyBatis中提供了一級緩存和二級緩存,其中()默認存在,不可控制,同一SqlSession范圍內的操作共享該緩存,增、刪、改后將()。
4、Mybatis的Xml映射文件中,不同的Xml映射文件,id是否可以重復?
5、MyBatis是一款優秀的支持自定義SQL查詢、存儲過程和高級映射的()框架,幾乎封裝了所有的JDBC代碼和參數的手動設置以及結果集的檢索,通過XML或注解的方式進行配置映射實現數據庫操作,大大
提高了開發效率。
6、模糊查詢like語句應該怎么寫?
二、概念性單選題
1、在mybatis的配置文件中,通過( )標簽來設置實體類的別名。
2、下列( )不屬於 MyBatis全局配置文件中的標簽。
3、在Mybatis中,SQL映射文件中配置insert語句時,在SQLSERVER中插入語句所在的表的ID為自動增長列?
4、在 MyBatis 中,操作數據庫的核心類是?
5、在使用MyBatis的時候,除了可以使用@Param注解來實現多參數入參,還可以用()傳遞多個參數值。
6、 在 MyBatis 中,配置結果映射時,使用( )標簽實現多對1的關聯?
7、MyBatis操作數據庫時的接口方法中,如果傳入的參數名和動態sql中使用時不一致,則需要使用( )注解修飾。
8、在mybatis中,配置結果映射時,使用( )標簽實現一對多的關聯?
9、MyBatis 中對復雜數據映射到一個結果集的配置使用的標簽是( )。
10、在 MyBatis 動態 SQL 中,循環使用的標簽名是( )。
11、看程序進行分析:Public UserselectUser(String name,Stringarea);
MyBatis常見的概念性面試題
一、概念性填空題
1、#{}和$ {}的區別是什么?#{}是_____,${}是_____。
正確答案: 預編譯處理 字符串替換
2、四個核心接口是()用於執行CRUD操作、()處理SQL的參數、()處理返回結果集、()用於執行SQL語句。
正確答案:1.Executor 2.ParameterHandler 3.ResultSetHandler 4.StatementHandler
3、MyBatis中提供了一級緩存和二級緩存,其中()默認存在,不可控制,同一SqlSession范圍內的操作共享該緩存,增、刪、改后將()。
正確答案:一級緩存 清除緩存
4、Mybatis的Xml映射文件中,不同的Xml映射文件,id是否可以重復?
不同的Xml映射文件,如果配置了namespace,那么id____;如果沒有配置namespace,那么id____;
正確答案: 可以重復 不能重復
5、MyBatis是一款優秀的支持自定義SQL查詢、存儲過程和高級映射的()框架,幾乎封裝了所有的JDBC代碼和參數的手動設置以及結果集的檢索,通過XML或注解的方式進行配置映射實現數據庫操作,大大
提高了開發效率。
正確答案:持久層
6、模糊查詢like語句應該怎么寫?
第一種:在Java代碼中添加_____。
第2種:在sql語句中添加_____,會引起sql注入。
正確答案:sql通配符 拼接通配符
二、概念性單選題
1、在mybatis的配置文件中,通過( )標簽來設置實體類的別名。
A. properties
B. settings
C. typeAliases
D. dataSource
正確答案: C
2、下列( )不屬於 MyBatis全局配置文件中的標簽。
A. settings
B. select
C. plugins
D. properties
正確答案: B
3、在Mybatis中,SQL映射文件中配置insert語句時,在SQLSERVER中插入語句所在的表的ID為自動增長列?
下列關於insert標簽的說法,正確的是( )
A. 必須要顯示插入標識列中的值
B. 使用任何數據庫都可以使用自動生成主鍵策略
C. useGeneratedKeys屬性對update標簽也有作用
D. 可以使用useGeneratedKeys屬性允許標識列的自動增長用於生成主鍵
正確答案: D
4、在 MyBatis 中,操作數據庫的核心類是?
A. SqlSessionFactory
B. SqlSession
C. Session
D. SqlSessionFactoryBuilder
正確答案:B
5、在使用MyBatis的時候,除了可以使用@Param注解來實現多參數入參,還可以用()傳遞多個參數值。
A. 用Map對象可以實現傳遞多參數值
B. 用List對象可以實現傳遞多參數值
C. 用數組的方式傳遞
D. 用Set集合的方式傳遞
正確答案:A
6、 在 MyBatis 中,配置結果映射時,使用( )標簽實現多對1的關聯?
A. many-one
B. one-many
C. association
D. collection
正確答案: C
7、MyBatis操作數據庫時的接口方法中,如果傳入的參數名和動態sql中使用時不一致,則需要使用( )注解修飾。
A. @RequestParam
B. @Parameter
C. @String
D. @Param
正確答案: D
8、在mybatis中,配置結果映射時,使用( )標簽實現一對多的關聯?
A. many-one
B. one-many
C. association
D. collection
正確答案:** D**
9、MyBatis 中對復雜數據映射到一個結果集的配置使用的標簽是( )。
A. < resultMap >
B. < result >
C. < map >
D. < collection >
正確答案:A
10、在 MyBatis 動態 SQL 中,循環使用的標簽名是( )。
A. for
B. while
C. foreach
D. do-while
正確答案: C
11、看程序進行分析:Public UserselectUser(String name,Stringarea); <selectid="selectUser"resultMap=“BaseResultMap”>
select * fromuser_user_t whereuser_name = #{0} anduser_area=#{1}#{0} 表示哪一個參數?
A. 程序報錯
B. name
C. area
D. 0
正確答案: B
12、MyBatis對JDBC訪問數據庫的代碼進行封裝,從而大大簡化了數據訪問層的重復性代碼,它是針對三層架構中( )的解決方案。
A. 表現層
B. 業務邏輯層
C. 持久化層
D. 數據庫系統
正確答案: C
13、MyBatis生命周期說法錯誤的是?
A. SqlSessionFactoryBuilder實例的最佳作用域是方法范圍,也就是定義為本地方法變量既可
B. SqlSessionFactory實例的生命周期應該在整個應用的執行期間都存在
C. SqlSession實例時線程不安全的,因此其生命周期應該是請求或方法范圍
D. SqlSession實例通常定義為一個類的靜態變量
正確答案: D
14、以下不屬於一對多的是?
A. 帥哥和美女
B. 學生和班級
C. 投影和學生
D. 學校和班級
正確答案: A
15、在MyBatis中,在進行select查詢映射時,下列關於返回類型的說法,正確的是?
A. 只能是resultType
B. 只能是resultMap
C. 可以是resultType或resultMap
D. 以上說法都不正確
正確答案: C
16、配置實體包的別名,正確的寫法是?
A. < typeAliases>
< package name=“com.swjd.bean”/>
< /typeAliases>
B. < typeAliases>
< package name=“com/swjd/bean”/>
< /typeAliases>
C. < typeAliase>
< package name=“com.swjd.bean”/>
< /typeAliase>
D. < package>
< package name=“com.swjd.bean”/>
< /package>
正確答案: A
17、編譯Java程序的命令是 ?
A. appletviewer
B. javac
C. java
D. javadoc
正確答案: B
18、在MyBatis數據庫操作時,需要編寫( )和對應的Xml文件,其中Xml文件中編寫的是對應Sql語句。
A. 接口和抽象方法
B. 普通類和普通方法
C. 抽象類和抽象方法
D. 普通類和抽象方法
正確答案: A
19、以下關於MyBatis集合類型參數的處理,說法錯誤的是?
A.當參數為Collection接口,轉化為Map, Map的key為collection
B.當參數類型為List接口時,除了collection的值外, list作為key
C.如果參數為數組,也會轉化為Map, Map的key為array
D.如果參數為數組,也會轉化為Map, Map的key為list
正確答案:D
20、MyBatis中用於表示輸入類型的屬性名稱是?
A. resultType
B. parameterType
C. collection
D. returnType
正確答案:B
21、如何獲取自動生成的(主)鍵值?
A.設置resultMap
B.設置useGeneratedKeys
C.設置keyProperty
D.設置Property
正確答案:C
22、主要用於更新是的mybatis動態sql的標簽是?
A Choose(when/otherwise)
B. Set
C. Where
D. Foreach
正確答案:B
23、關於MyBatis中傳遞多參數的情況,如果參數封裝成了Student類,那么應該怎么操作?
A.條件獲取數據可以通過# {屬性名}來獲得
B.條件獲取數據可以通過#{arg0}來獲得
C.條件獲取數據可以通過#{arg1}來獲得
D.條件獲取數據可以通過#{屬性名}或者#(arg0}來獲得
正確答案:A
24、映射一對一使用到的標簽?
A. < one-to-one >
B. < reference >
C. < collection >
D. < association >
正確答案:D
25、在mybatis3動態SQL中,沒有使用下列()標簽?
A.for
B.if
C.choose
D.where
正確答案:A
26、MyBatis針對數據庫就可操作時,修改方法對應的標簽名是?
A.< sql >
B.< insert >
C.< Update >
D.< save >
正確答案:C
27、在MyBatis中調用SqlSessionFactoryBuilder的那個方法獲取SqlSession對象?
A. getSession()
B. openSession()
C. session()
D. showSqlSession()
正確答案:B
28、想實現批量刪除的動態sql的標記可選擇?
A. Choose(when/otherwise)
B. Set
C. Foreach
D. Where
正確答案:C
29、MyBatis針對數據庫操作時,增加方法的標簽名是?
A.< sql >
B.< insert >
C.< add >
D.< save >
正確答案:B
30、MyBatis編程步驟?
A. Step1:創建SQLSessionFactory Step2:通過SQLSssonFactory創建SQLSsion Step3:通過SQLSssion執行數據庫操作Step4:調用session.close()關閉會話
B. Step1:創建SQLSession Step2:通過SQLSession執行數據庫操作Step3:調用session.commit()提交事物Step4:調用session.close()關閉會話
C.Step1:創建SQLSession Step2:通過SQL Ssson創建SQLSssonFactory Step3:通過SQL SssionFactory執行數據庫操作Step4:調用session.commit()提交事物 Step5:調用session.close()關閉會話
D. Step1:創建SQSessionFactory Step2:通過SQLSessionFactory創建SQLSssion Step3:通過SQL Sssion執行數據庫操作Step4:調用Bession.commit()提交事物 Step5:調用session.close()關閉會話
正確答案:D
31、ORM是什么意思?
A.對象數據管理
B.對象關系映射
C.持久化數據
D.持久化對象
正確答案:B
32、關於MyBatis傳遞數組參數的說法錯誤的是?
A.在映射文件中取得數組值應該通過< forEach>標簽
B.< forEach>標簽可以應用於set、List以及數組的取值
C.傳遞數組的值,和多參數傳值一樣在映射文件中只能通過< forEach>取值
D.< forEach>標簽的open和close屬性用於寫開始和結束標簽
正確答案:C
33、MyBatis中對復雜數據庫映射到一個結果集的配置使用的標簽的是?
A. < resultMap>
B. < result>
C. < map>
D. < collection>
正確答案:A
34、MyBatis注解中怎么給參數一個名字?
A.@Param C11
B.@Select
C.@Options
D.@Result
正確答案:A
35、一輛汽車由多個零部件組成,且相同的零部件可適用於不同型號的汽車,則汽車實體集與部件實體集之間的聯系是?
A.1:M
B.1:1
C.M:1
D.M:N
正確答案:D
36、以下關於MyBatis參數處理的說法錯誤的是?
A.當傳入單個參數時,可以直接取出參數並賦值給xml文件
B.當傳入多個參數時,可以直接取出參數並賦值給xml文件
C.當傳入多個參數時,可以使用Map接口的方式封裝參數並取得值
D.當傳入多個參數時,可以使用注解@param的方式標注參數
正確答案:B
三、概念性多選題
1、對mybatis描述有誤的是?
A. MyBatis 是一個可以自定義 SQL、存儲過程和高級映射的持久層框架
B. MyBatis 的緩存分為一級緩存和二級緩存,一級緩存放在 session 里面
C. Mybatis是一個全ORM(對象關系映射)框架,它內部封裝了JDBC
D. MyBatis 只可以使用 XML來配置和映射原生信息
正確答案: C, D
2、Mybatis是如何將sql執行結果封裝為目標對象並返回的?
A. id
B. < resultMap>標簽
C. 使用sql列的別名
D. resultType
正確答案: B, C
3、mybaties中模糊查詢like語句的寫法?
A. select * from foo where bar like #{value}
B. select * from foo where bar like #{%value%}
C. select * from foo where bar like %#{value}%
D. select * from foo where bar like “%”${value}"%"
正確答案: A, D
4、Mybatis的Xml映射文件中,不同的Xml映射文件,id是否可以重復?選擇說法正確的
A. 不同的Xml映射文件,如果配置了namespace,那么id可以重復
B. 如果沒有配置namespace,那么id不能重復
C. 如果沒有配置namespace,id能重復
D. 不同的Xml映射文件,如果配置了namespace,那么id不可以重復
正確答案: A, B
5、Mybatis的mapper接口調用時候的要求正確的是?
A. Mapper接口方法名和Mapper.xml中定義的每個SQL的id相同;
B. Mapper接口方法的輸入參數類型和mapper.xml中定義的每個sqlparameterType類型
相同
C. Mapper接口方法的輸入輸出參數類型和mapper.xml中定義的每個sql的resultType的
類型相同
D. Mapper.xml文件中的namespace,就是接口的名字
正確答案: A, B, C
6、MyBatis內置類型別名有?
A. _int
B. Integer
C. int
D. String
正確答案: A, C
7、Mybatis動態sql標簽有哪些?
A. trim
B. foreach
C. set
D. than
正確答案: A, B, C
8、Mybaits的優點正確的是?
A. 基於SQL語句編程,相當靈活,不會對應用程序或者數據庫的現有設計造成任何影
響,SQL寫在XML里,解除sql與程序代碼的耦合,便於統一管理
B. 與JDBC相比,減少了50%以上的代碼量,消除了JDBC大量冗余的代碼,不需要手
動開關連接
C. 很好的與各種數據庫兼容
D. 它是一全個ORM框架,MyBatis不需要程序員自己編寫Sql語句。
正確答案: A, B, C
9、實體類中的屬性名和表中的字段名不一樣怎么處理?
A. 查詢的sql語句中定義字段名的別名
B. 不用處理
C. 通過< resultMap>來映射字段名和實體類屬性名
D. 通過< resultType>來映射字段名和實體類屬性名
正確答案: A, C
10、MyBatis有兩種管理器類型,分別是()和()。
A. JDBC
B. MANAGED
C. POOLED
D. JNOI
正確答案: A, B
11、關於MyBatis參數處理說法正確的是?
A.傳遞單個參數時,MyBatis會自動封裝到Map集合中
B.傳遞單個參數時,MyBatis會自動進行參數的賦值
C.傳遞多個參數時,MyBatis會自動封裝到Map集合中
D.傳遞多個參數時,MyBatis會自動進行參數的賦值
正確答案:B,C
12、使用MyBatis的mapper接口調用時有哪些要求?
A.Mapper接口方法名和mapper.xml中定義的每個sql的id相同
B.Mapper.xml文件中的namespace即是mapper接口的類路徑
C.Mapper接口方法的輸出參數類型和mapper.xml中定義的每個sql的resultType的類型相同
D.Mapper接口方法色輸入參數類型和mapper.xml中定義的每個sql的parameterType的類型相同
正確答案:A,B,C,D
四、面試問答題
1、什么是MyBatis
(1)MyBatis 本是apache的一個開源項目iBatis, 2010年這個項目由apache software foundation 遷移到了google code,並且改名為MyBatis 。2013年11月遷移到Github。
IBATIS一詞來源於“internet”和“abatis”的組合,是一個基於Java的持久層框架。iBATIS提供的持久層框架包括SQL Maps和Data Access Objects(Dao)。
(2)MyBatis是一個支持普通SQL查詢,存儲過程和高級映射的優秀持久層框架。MyBatis消除了幾乎所有的JDBC代碼和參數的手工設置以及對結果集的檢索封裝。MyBatis可以使用簡單的XML或注解用於配置和原始映射,將接口和Java的POJO(Plain Old Java Objects,普通的Java對象)映射成數據庫中的記錄。
(3)Mybatis提供一種“半自動化”的ORM(Object Ralation Mapping 對象關系映射框架)實現。MyBatis需要手動寫SQL,后期可以逆向工程!這里的“半自動化”,是相對Hibernate等提供了全面的數據庫封裝機制的“全自動化”ORM實現而言,“全自動”ORM實現了POJO和數據庫表之間的映射,以及 SQL 的自動生成和執行。
2、MyBatis的優點
(1)基於SQL語句編程,相當靈活,不會對應用程序或者數據庫的現有設計造成任何影響,SQL寫在XML里,解除sql與程序代碼的耦合,便於統一管理;提供XML標簽,支持編寫動態SQL語句,並可重用。
(2)與JDBC相比,減少了50%以上的代碼量,消除了JDBC大量冗余的代碼,不需要手動開關連接;
(3)很好的與各種數據庫兼容(因為MyBatis使用JDBC來連接數據庫,所以只要JDBC支持的數據庫MyBatis都支持)。
(4)能夠與Spring很好的集成;
(5)提供映射標簽,支持對象與數據庫的ORM字段關系映射;提供對象關系映射標簽,支持對象關系組件維護。
3、MyBatis與Hibernate的區別
Hibernate 全自動框架 SQL語句可以自動生成,不用人工書寫SQL! 笨重
MyBatis 半自動 SQL語句還是需要自己書寫,后期有一些插件可以自動生成SQL! 靈活
(1)Mybatis和hibernate不同,它不完全是一個ORM框架,因為MyBatis需要程序員自己編寫Sql語句。
(2)Mybatis直接編寫原生態sql,可以嚴格控制sql執行性能,靈活度高,非常適合對關系數據模型要求不高的軟件開發,因為這類軟件需求變化頻繁,一但需求變化要求迅速輸出成果。但是靈活的前提是mybatis無法做到數據庫無關性,如果需要實現支持多種數據庫的軟件,則需要自定義多套sql映射文件,工作量大。
(3)Hibernate對象/關系映射能力強,數據庫無關性好,對於關系模型要求高的軟件,如果用hibernate開發可以節省很多代碼,提高效率。
4、#{}與${}的區別
#{}:占位符號,MyBatis在處理#{}會將 sql 中的#{}替換為?號,調用 PreparedStatement 的set 方法來賦值;可以防止SQL的注入,提高系統安全性
$ {}:sql拼接符號,MyBatis在處理${}時like和order by后使用,存在sql注入問題,需手動代碼中過濾
5、如何獲取自動生成的(主)鍵值?
如果采用自增長策略,自動生成的鍵值在 insert 方法執行完后可以被設置到傳入的參數對象中。
usegeneratedkeys=”true” keyproperty=”id”
例:
!--拿主鍵自增長的值1-->
<!--useGeneratedKeys="true":開啟自增長映射,默認為false-->
<!-- keyProperty="id":哪一個屬性是主鍵-->
<insert id="addNum" useGeneratedKeys="true" keyProperty="id">
insert into user values (null,#{userName},#{birthday},#{sex},#{address})
</insert>
User user=new User();
user.setAddress("閃亮101號")
int i=um.addNum(user);
System.out.println(i>0?"成功":"失敗");
<!--拿自增長的id-->
int qq=user.getId();
System.out.println("你最后添加的id:"+qq);
6、Mybatis動態sql有什么用?執行原理?有哪些動態sql?
Mybatis動態sql可以在Xml映射文件內,以標簽的形式編寫動態sql,執行原理是根據表達式的值 完成邏輯判斷並動態拼接sql的功能。
Mybatis提供了9種動態sql標簽:trim | where | set | foreach | if | choose | when | otherwise | bind。
7、Mybatis的Xml映射文件中,不同的Xml映射文件,id是否可以重復?
不同的Xml映射文件,如果配置了namespace,那么id可以重復;如果沒有配置namespace,那么id不能重復;
原因就是namespace+id是作為Map<String, MapperStatement>的key使用的,如果沒有namespace,就剩下id,那么,id重復會導致數據互相覆蓋。有了namespace,自然id就可以重復,namespace不同,namespace+id自然也就不同。
8、當實體類中的屬性名和表中的字段名不一樣 ,怎么辦 ?
第1種: 通過在查詢的sql語句中定義字段名的別名,讓字段名的別名和實體類的屬性名一致。
<select id="getStudentById" resultetype="com.swjd.bean.Students">
select s_id sId,s_name sName,s_age sAge,s_email sEmail,class_id classId from student where id=#{id};
</select>
第2種: 通過< resultMap>來映射字段名和實體類屬性名的一一對應的關系。
<resultMap id="studentQuery" type="com.swjd.bean.Students">
//用id映射主鍵 property為實體類屬性名,column為數據表中的屬性
<id column="s_id" property="sId"></id>
<result column="s_name" property="sName"></result>
//用result映射普通字段
<result column="s_age" property="sAge"></result>
<result column="s_email" property="sEmail"></result>
<result column="class_id" property="classId"></result>
</resultMap>
<select id="getStudentById" resultMap="studentQuery" >
select * from students where s_id=#{sId};
</select>
9、 模糊查詢like語句該怎么寫?
第1種:在Java代碼中添加sql通配符。
<select id="selectLike" parameterType="String" resultType="com.swjd.bean.User">
select * from user where username like "%"#{userName}"%"
</select>
<select id="selectLike2" parameterType="String" resultType="com.swjd.bean.User">
select * from user where username like #{userName}
</select>
第2種:在sql語句中拼接通配符,會引起sql注入
<select id="selectLike3" parameterType="String" resultType="com.swjd.bean.User">
select * from user where username like '%${value}%'
</select>
10、Mybatis是如何進行分頁的?分頁插件的原理是什么?
Mybatis使用RowBounds對象進行分頁,它是針對ResultSet結果集執行的內存分頁,而非物理分頁。可以在sql內直接書寫帶有物理分頁的參數來完成物理分頁功能,也可以使用分頁插件來完成物理分頁。
分頁插件的基本原理是使用Mybatis提供的插件接口,實現自定義插件,在插件的攔截方法內攔截待執行的sql,然后重寫sql,根據dialect方言,添加對應的物理分頁語句和物理分頁參數。
11、如何執行批量插入?
首先,創建一個簡單的insert語句:
<insert id=”insertname”>
insert into names (name) values (#{value})
</insert>
然后在java代碼中像下面這樣執行批處理插入:
list<string> names = new arraylist();
names.add(“小許”);
names.add(“小汪”);
names.add(“小潔”);
// 注意這里 executortype.batch
sqlsession sqlsession = sqlsessionfactory.opensession(executortype.batch);
try {
namemapper mapper = sqlsession.getmapper(namemapper.class);
for (string name : names) {
mapper.insertname(name);
}
sqlsession.commit();
}catch(Exception e){
e.printStackTrace();
sqlSession.rollback();
throw e;
}
finally {
sqlsession.close();
}
12、如何執行批量刪除?
<delete id="batchdeleteEquipment" parameterType="String">
DELETE FROM attend_equipment WHERE e_id IN
<foreach collection="array" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
13、在mapper中如何傳遞多個參數?
第一種:直接在方法中傳遞參數,xml文件用#{0} #{1}來獲取
第二種:使用 @param 注解:這樣可以直接在xml文件中通過#{name}來獲取
第三種:第三種:多個參數封裝成map
14、Mybatis是如何將sql執行結果封裝為目標對象並返回的?都有哪些映射形式?
第一種是使用標簽,逐一定義數據庫列名和對象屬性名之間的映射關系。
第二種是使用sql列的別名功能,將列的別名書寫為對象屬性名。
有了列名與屬性名的映射關系后,Mybatis通過反射創建對象,同時使用反射給對象的屬性逐一賦值並返回,那些找不到映射關系的屬性,是無法完成賦值的。
15、ResultMap和ResultType的差別、ParameterMap和parameterType的差別?
ResultMap和ResultType:
兩者都是表示查詢結果集與java對象之間的一種關系,處理查詢結果集,映射到java對象。
resultType跟resultMap不能同時存在。
resultMap:表示將查詢結果集中的列一一映射到bean對象的各個屬性。
ResultType:表示的是bean中的對象類,此時可以省略掉resultMap標簽的映射,但是必須保證查詢結果集中的屬性 和 bean對象類中的屬性是一一對應的,此時大小寫不敏感,但是有限制。
ParameterMap(不推薦使用)和parameterType:
ParameterMap:與resultMap方法類似,表示將查詢結果集中列值的類型一一映射到java對象屬性的類型上,在開發過程中不推薦這種方式。
parameterType: parameterType直接將查詢結果列值類型自動對應到java對象屬性類型上,不再配置映射關系一一對應。
16、Mybatis 是否支持延遲加載?如果支持,它的實現原理是什么?
答:Mybatis僅支持association關聯對象和collection關聯集合對象的延遲加載,association指的就是一對一,collection指的就是一對多查詢。在Mybatis配置文件中,可以配置是否啟用延遲加載lazyLoadingEnabled=true|false。
它的原理是,使用CGLIB創建目標對象的代理對象,當調用目標方法時,進入攔截器方法,比如調用a.getB().getName(),攔截器invoke()方法發現a.getB()是null值,那么就會單獨發送事先保存好的查詢關聯B對象的sql,把B查詢上來,然后調用a.setB(b),於是a的對象b屬性就有值了,接着完成a.getB().getName()方法的調用。這就是延遲加載的基本原理。
當然了,不光是Mybatis,幾乎所有的包括Hibernate,支持延遲加載的原理都是一樣的。
17、簡述Mybatis的插件運行原理,以及如何編寫一個插件?
1)Mybatis 僅可以編寫針對 ParameterHandler、ResultSetHandler、StatementHandler、Executor 這 4 種接口的插件,Mybatis 通過動態代理,為需要攔截的接口生成代理對象以實現接口方法攔截功能,每當執行這 4 種接口對象的方法時,就會進入攔截方法,具體就是InvocationHandler 的 invoke()方法,當然,只會攔截那些你指定需要攔截的方法。
2)實現 Mybatis 的 Interceptor 接口並復寫 intercept()方法,然后在給插件編寫注解,指定要攔截哪一個接口的哪些方法即可,記住,別忘了在配置文件中配置你編寫的插件。
18、Mybatis的一級、二級緩存?
1)一級緩存: 基於 PerpetualCache 的 HashMap 本地緩存,其存儲作用域為 Session,當 Session flush 或 close 之后,該 Session 中的所有 Cache 就將清空,默認打開一級緩存。
2)二級緩存與一級緩存其機制相同,默認也是采用 PerpetualCache,HashMap 存儲,不同在於其存儲作用域為 Mapper(Namespace),並且可自定義存儲源,如 Ehcache。默認不打開二級緩存,要開啟二級緩存,使用二級緩存屬性類需要實現Serializable序列化接口(可用來保存對象的狀態),可在它的映射文件中配置< cache/> ;
3)對於緩存數據更新機制,當某一個作用域(一級緩存 Session/二級緩存Namespaces)的進行了C/U/D 操作后,默認該作用域下所有 select 中的緩存將被 clear 掉並重新更新,如果開啟了二級緩存,則只根據配置判斷是否刷新。
4)MyBatis中提供了一級緩存和二級緩存,其中一級緩存默認存在,不可控制,同一SqlSession范圍內的操作共享該緩存,增、刪、改后將清除緩存。
19、使用MyBatis的mapper接口調用時有哪些要求?
① Mapper接口方法名和mapper.xml中定義的每個sql的id相同;
② Mapper接口方法的輸入參數類型和mapper.xml中定義的每個sql 的parameterType的類型相同;
③ Mapper接口方法的輸出參數類型和mapper.xml中定義的每個sql的resultType的類型相同;
④ Mapper.xml文件中的namespace即是mapper接口的類路徑。
20、Mybatis全局配置文件中有哪些標簽?分別代表什么意思?
configuration 配置
properties 屬性:可以加載properties配置文件的信息
settings 設置:可以設置mybatis的全局屬性
typeAliases 類型命名
typeHandlers 類型處理器
objectFactory 對象工廠
plugins 插件
environments 環境
environment 環境變量
transactionManager 事務管理器
dataSource 數據源
mappers 映射器
21、一對一關聯查詢使用什么標簽?一對多關聯查詢使用什么標簽?
答:MyBatis中使用collection標簽來解決一對多的關聯查詢,collection標簽可用的屬性如下:
property:指的是集合屬性的值.
ofType:指的是集合中元素的類型.
column:所對應的外鍵字段名稱.
select:使用另一個查詢封裝的結果.
MyBatis中使用association標簽來解決一對一的關聯查詢,association標簽可用的屬性如下:
property:對象屬性的名稱.
javaType:對象屬性的類型.
column:所對應的外鍵字段名稱.
select:使用另一個查詢封裝的結果!
22、通常一個Xml映射文件,都會寫一個Dao接口與之對應,請問,這個Dao接口的工作原理是什么?Dao接口里的方法,參數不同時,方法能重載嗎?
Dao接口即Mapper接口。接口的全限名,就是映射文件中namespace的值;接口的方法名,就是映射文件中Mapper的Statement的id值;接口方法內的參數,就是傳遞給sql的參數。
Mapper接口是沒有實現類的,當調用接口方法時,接口全限名+方法名拼接字符串作為key值,可唯一定位一個MapperStatement。在Mybatis中,每一個< select>、< insert>、< update>、< delete>標簽,都會被解析為一個MapperStatement對象。
Mapper接口里的方法,是不能重載的,因為是使用 全限名+方法名 的保存和尋找策略。Mapper 接口的工作原理是JDK動態代理,Mybatis運行時會使用JDK動態代理為Mapper接口生成代理對象proxy,代理對象會攔截接口方法,轉而執行MapperStatement所代表的sql,然后將sql執行結果返回。
23、Xml映射文件中,除了常見的select|insert|update|delete標簽之外,還有哪些標簽?
答:< resultMap>、< parameterMap>、< sql>、< include>、< selectKey>,加上動態sql的9個標簽,其中< sql>為sql片段標簽,通過< include>標簽引入sql片段,< selectKey>為不支持自增的主鍵生成策略標簽。
24、Mybatis映射文件中,如果A標簽通過include引用了B標簽的內容,請問,B標簽能否定義在A標簽的后面,還是說必須定義在A標簽的前面?
雖然Mybatis解析Xml映射文件是按照順序解析的,但是,被引用的B標簽依然可以定義在任何地方,Mybatis都可以正確識別。
原理是,Mybatis解析A標簽,發現A標簽引用了B標簽,但是B標簽尚未解析到,尚不存在,此時,Mybatis會將A標簽標記為未解析狀態,然后繼續解析余下的標簽,包含B標簽,待所有標簽解析完畢,Mybatis會重新解析那些被標記為未解析的標簽,此時再解析A標簽時,B標簽已經存在,A標簽也就可以正常解析完成了。
25、Mybatis中如何執行批處理?
答:使用BatchExecutor完成批處理。
26、簡述 Mybatis 的 Xml 映射文件和 Mybatis 內部數據結構之間的映射關系?
答:Mybatis將所有Xml配置信息都封裝到All-In-One重量級對象Configuration內部。在Xml映射文件中,< parameterMap>標簽會被解析為ParameterMap對象,其每個子元素會被解析為ParameterMapping對象。< resultMap>標簽會被解析為ResultMap對象,其每個子元素會被解析為ResultMapping對象。每一個< select>、< insert>、< update>、< delete>標簽均會被解析為MappedStatement對象,標簽內的sql會被解析為BoundSql對象。
27、接口綁定有幾種實現方式,分別是怎么實現的?
答:接口綁定有兩種實現方式,一種是通過注解綁定,就是在接口的方法上面加上@Select@Update 等注解里面包含 Sql 語句來綁定,另外一種就是通過 xml 里面寫 SQL 來綁定,在這種情況下,要指定 xml 映射文件里面的 namespace 必須為接口的全路徑名。
28、什么是 MyBatis 的接口綁定,有什么好處?
答:接口映射就是在 MyBatis 中任意定義接口,然后把接口里面的方法和 SQL 語句綁定,我們直接調用接口方法就可以,這樣比起原來了SqlSession 提供的方法我們可以有更加靈活的選擇和設置。
29、Mybatis都有哪些Executor執行器?它們之間的區別是什么?
答:Mybatis有三種基本的Executor執行器,SimpleExecutor、ReuseExecutor、BatchExecutor。
SimpleExecutor:每執行一次update或select,就開啟一個Statement對象,用完立刻關閉Statement對象。
ReuseExecutor:執行update或select,以sql作為key查找Statement對象,存在就使用,不存在就創建,用完后,不關閉Statement對象,而是放置於Map<String, Statement>內,供下一次使用。簡言之,就是重復使用Statement對象。
BatchExecutor:執行update(沒有select,JDBC批處理不支持select),將所有sql都添加到批處理中(addBatch()),等待統一執行(executeBatch()),它緩存了多個Statement對象,每個Statement對象都是addBatch()完畢后,等待逐一執行executeBatch()批處理。與JDBC批處理相同。
作用范圍:Executor的這些特點,都嚴格限制在SqlSession生命周期范圍內。
30、Mybatis中如何指定使用哪一種Executor執行器?
答:在Mybatis配置文件中,可以指定默認的ExecutorType執行器類型,也可以手動給DefaultSqlSessionFactory的創建SqlSession的方法傳遞ExecutorType類型參數。
31、Mybatis是否可以映射Enum枚舉類?
答:Mybatis可以映射枚舉類,不單可以映射枚舉類,Mybatis可以映射任何對象到表的一列上。映射方式為自定義一個TypeHandler,實現TypeHandler的setParameter()和getResult()接口方法。TypeHandler有兩個作用,一是完成從javaType至jdbcType的轉換,二是完成jdbcType至javaType的轉換,體現為setParameter()和getResult()兩個方法,分別代表設置sql問號占位符參數和獲取列查詢結果。
32、什么情況下用注解綁定,什么情況下用 xml 綁定?
答:當 Sql 語句比較簡單時候,用注解綁定;當 SQL 語句比較復雜時候,用 xml 綁定,一般用xml 綁定的比較多
33、為什么說Mybatis是半自動ORM映射工具?它與全自動的區別在哪里?
答:Hibernate屬於全自動ORM映射工具,使用Hibernate查詢關聯對象或者關聯集合對象時,可以根據對象關系模型直接獲取,所以它是全自動的。而Mybatis在查詢關聯對象或關聯集合對象時,需要手動編寫sql來完成,所以,稱之為半自動ORM映射工具。
34、Mapper編寫有哪幾種方式
第一種:接口實現類繼承SqlSessionDaoSupport:使用此種方法需要編寫mapper接口,mapper接口實現類、mapper.xml文件。
(1)在sqlMapConfig.xml中配置mapper.xml的位置
(2)定義mapper接口
(3)實現類集成SqlSessionDaoSupportmapper方法中可以this.getSqlSession()進行數據增刪改查。
(4)spring 配置
第二種:使用org.mybatis.spring.mapper.MapperFactoryBean:
(1)在sqlMapConfig.xml中配置mapper.xml的位置,如果mapper.xml和mappre接口的名稱相同且在同一個目錄,這里可以不用配置
(2)定義mapper接口:
①mapper.xml中的namespace為mapper接口的地址
②mapper接口中的方法名和mapper.xml中的定義的statement的id保持一致
③Spring中定義
第三種:使用mapper掃描器:
(1)mapper.xml文件編寫:
mapper.xml中的namespace為mapper接口的地址;
mapper接口中的方法名和mapper.xml中的定義的statement的id保持一致;
如果將mapper.xml和mapper接口的名稱保持一致則不用在sqlMapConfig.xml中進行配置。
(2)定義mapper接口:
注意mapper.xml的文件名和mapper的接口名稱保持一致,且放在同一個目錄
(3)配置mapper掃描器:
(4)使用掃描器后從spring容器中獲取mapper的實現對象。
35、MyBatis 實現一對一有幾種方式?具體怎么操作的?
答:有聯合查詢和嵌套查詢,聯合查詢是幾個表聯合查詢,只查詢一次,通過在 resultMap 里面配置 association 節點配置一對一的類就可以完成;嵌套查詢是先查一個表,根據這個表里面的結果的外鍵 id,去再另外一個表里面查詢數據,也是通過 association 配置,但另外一個表的查詢通過 select 屬性配置。
36、JDBC編程有哪些不足之處,MyBatis是如何解決這些問題的?
① 數據庫鏈接創建、釋放頻繁造成系統資源浪費從而影響系統性能,如果使用數據庫鏈接池可解決此問題。
解決:在SqlMapConfig.xml中配置數據鏈接池,使用連接池管理數據庫鏈接。
② Sql語句寫在代碼中造成代碼不易維護,實際應用sql變化的可能較大,sql變動需要改變java代碼。
解決:將Sql語句配置在XXXXmapper.xml文件中與java代碼分離。
③ 向sql語句傳參數麻煩,因為sql語句的where條件不一定,可能多也可能少,占位符需要和參數一一對應。
解決: Mybatis自動將java對象映射至sql語句。
④ 對結果集解析麻煩,sql變化導致解析代碼變化,且解析前需要遍歷,如果能將數據庫記錄封裝成pojo對象解析比較方便。
解決:Mybatis自動將sql執行結果映射至java對象。
37、Mybatis執行批量插入,能返回數據庫主鍵列表嗎?
Mybatis在插入單條數據的時候有兩種方式返回自增主鍵: mybatis3.3.1支持批量插入后返回主鍵ID,
首先對於支持自增主鍵的數據庫:useGenerateKeys和keyProperty。
不支持生成自增主鍵的數據庫:< selectKey>。
38、Mybatis分為三層
(1)API接口層:提供給外部使用的接口API
(2)數據處理層:負責具體的SQL
(3)基礎支撐層:負責最基礎的功能支撐,如連接管理,事務管理,配置加載和緩存處理
39、MyBatis的緩存
答:MyBatis的緩存分為一級緩存和二級緩存,一級緩存放在session里面,默認就有,二級緩存放在它的命名空間里,默認是不打開的,使用二級緩存屬性類需要實現Serializable序列化接口(可用來保存對象的狀態),可在它的映射文件中配置< cache/>
40、MyBatis的好處是什么?
答:1)MyBatis把sql語句從Java源程序中獨立出來,放在單獨的XML文件中編寫,給程序的維護帶來了很大便利。
2)MyBatis封裝了底層JDBC API的調用細節,並能自動將結果集轉換成Java Bean對象,大大簡化了Java數據庫編程的重復工作。
3)因為MyBatis需要程序員自己去編寫sql語句,程序員可以結合數據庫自身的特點靈活控制sql語句,因此能夠實現比Hibernate等全自動orm框架更高的查詢效率,能夠完成復雜查詢。
41、resultType resultMap的區別?
答:1)類的名字和數據庫相同時,可以直接設置resultType參數為Pojo類
2)若不同,需要設置resultMap 將結果名字和Pojo名字進行轉換
3)resultmap是手動提交,人為提交,resulttype是自動提交。MyBatis中在查詢進行select映射的時候,返回類型可以用resultType,也可以用resultMap,resultType是直接表示返回類型的,而resultMap則是對外部ResultMap的引用,但是resultType跟resultMap不能同時存在。
4)在MyBatis進行查詢映射時,其實查詢出來的每一個屬性都是放在一個對應的Map里面的,其中鍵是屬性名,值則是其對應的值。
①.當提供的返回類型屬性是resultType時,MyBatis會將Map里面的鍵值對取出賦給resultType所指定的對象對應的屬性。所以其實MyBatis的每一個查詢映射的返回類型都是ResultMap,只是當提供的返回類型屬性是resultType的時候,MyBatis對自動的給把對應的值賦給resultType所指定對象的屬性。
②.當提供的返回類型是resultMap時,因為Map不能很好表示領域模型,就需要自己再進一步的把它轉化為對應的對象,這常常在復雜查詢中很有作用。
42、Mybatis比IBatis比較大的幾個改進是什么?
答:1)有接口綁定,包括注解綁定sql和xml綁定Sql
2)動態sql由原來的節點配置變成OGNL表達式3) 在一對一,一對多的時候引進了association,在一對多的時候引入了collection節點,不過都是在resultMap里面配置
43、IBatis和MyBatis在核心處理類分別叫什么?
答:IBatis里面的核心處理類交SqlMapClient,MyBatis里面的核心處理類叫做SqlSession。
44、IBatis和MyBatis在細節上的不同有哪些?
答:1)在sql里面變量命名有原來的#變量# 變成了#{變量}
2)原來的變量變量變量變成了${變量}
3)原來在sql節點里面的class都換名字交type
4)原來的queryForObject queryForList 變成了selectOne selectList5)原來的別名設置在映射文件里面放在了核心配置文件里
45、MyBatis里面的動態Sql是怎么設定的?用什么語法?
MyBatis里面的動態Sql一般是通過if節點來實現,通過OGNL語法來判斷,但是如果要寫的完整,必須配合where,trim節點,
choose標簽 choose when otherwise標簽,一個choose中至少有一個when,0或1個otherwise,如果when滿足就執行,全不滿足就執行otherwise。
注意where1=1必須添加,防止where關鍵字后面沒有語句.
where標簽是判斷包含節點有內容就插入where,如果where后面的字符串是以AND和OR開頭的,就將AND和OR提出
當if條件都不滿足,where元素中沒有內容,也就不會出現choose標簽那種錯誤。
set標簽更新的時候用:如果該標簽包含的元素中有返回值,就插入一個set;如果set后面的字符串是以逗號結尾的,就將這個逗號剔除。
注意set標簽用法中,SQL后面的逗號沒有問題了,但是如果set元素中沒有內容,照樣會出現SQL錯誤,所以為了避免錯誤產生,類似id=#{id}這樣必然存在的賦值仍然有保留的必要。
46、MyBatis的四大核心對象?JDBC的四個核心對象?
MyBatis的四大核心對象:
(1)SqlSession對象,該對象中包含了執行SQL語句的所有方法。類似於JDBC里面的Connection。
(2)Executor接口,它將根據SqlSession傳遞的參數動態地生成需要執行的SQL語句,同時負責查詢緩存的維護。類似於JDBC里面的Statement/PrepareStatement。
(3)MappedStatement對象,該對象是對映射SQL的封裝,用於存儲要映射的SQL語句的id、參數等信息。
(4)ResultHandler對象,用於對返回的結果進行處理,最終得到自己想要的數據格式或類型。可以自定義返回類型。
JDBC的四個核心對象:
(1)DriverManager,用於注冊數據庫連接
(2)Connection,與數據庫連接對象
(3)Statement/PrepareStatement,操作數據庫SQL語句的對象
(4)ResultSet,結果集或一張虛擬表
47、MyBatis底層實現原理?
MyBatis是一個持久層框架,實現了ORM思想,可以將查詢的結果集自動轉換成Java對象,也可以將Java對象轉換成一條數據插入到數據庫表當中。
那么,查詢結果集是如何自動轉換成Java對象的呢?實際上這里使用了反射機制,在配置文件中假設編寫了一條select語句,查詢之后,列名與屬性名要一一對應(不對應的可以采用給列起別名),然后每個列名前添加“set”,通過反射機制獲取set方法,然后再通過反射機制的method.invoke()來調用這個set方法,給Java對象的屬性賦值。這樣就完成了對象的封裝。
另外,Java對象是如何轉換成一條記錄插入到數據庫的呢?假設在配置文件中編寫了一條insert語句,那么這條語句需要的值從哪里來呢,在mybatis的mapper配置中有parameterType屬性,該屬性是專門給sql語句占位符傳值的,其實這里也是使用了反射機制,其中sql語句的占位符采用#{},其中大括號當中需要提供java對象的屬性名,該屬性名和get進行拼接得到get方法名,然后通過反射機制獲取該get方法,再通過method.invoke()來調用這個get方法,這樣就可以獲取到對應的屬性值,然后傳入了。
其實MyBatis設計最牛的地方當然是采用JDK動態代理的方式生成DAO接口的實現類了。其中DAO接口中的每一個方法名對應sql語句的id。DAO接口中的方法不允許重載,因為id是不允許重復的。以上大概就是我了解的MyBatis實現原理。
48、Mybatis和jdbc的區別
相比與jdbc,Mybatis具有以下優點
(1)數據庫鏈接創建,釋放頻繁造成系統資源浪費會影響系統性能,使用數據庫可以解決
解決:在核心配置文件SqlMapConfig.xml中配置數據鏈接池,使用數據鏈接池管理數據庫鏈接
(2)Sql寫在代碼中不易於維護,修改需要變動java代碼
在映射文件XXXMapper.xml文件中配置sql語句與Java代碼分離
(3)向Sql語句傳輸參數麻煩,因為Sql語句的WHERE條件不一定,可能多也可能少,占位符需要和參數一一對應, Mybatis可以自動將Java對象映射到sql語句
(4)對結果集解析麻煩,sql變化導致解析代碼變化,且解析前需要遍歷,將數據庫記錄封裝成pojo對象解析更加方便,Mybatis可以自動將sql執行結果映射到Java對象。
49、MyBatis中的API?
(1)SqlSessionFactoryBuilder
通過加載MyBatisde 核心配置文件,創建SqlSessionFactory
1
(2)SqlSessionFactory
定義了openSession的不同重載方法
1
(3)sqlSession
定義了數據庫的操作,增刪改查
1
50、Mybatis的編程步驟
(0)創建SqlSessionFactoryBuilder
(1)通過SqlsesionFactoryBuilder創建sqlSessionFactory
(2)通過SqlSessionFactory創建sqlSession
(3)通過sqlSession執行數據庫操作
(4)調用session.commit()提交事務
(5)調用session.close()關閉會話
51、Statement和PrepareStatement的區別
PreparedStatement:表示預編譯的 SQL 語句的對象。
(1)PrepareStatement可以使用占位符,是預編譯的,批處理比Statement效率高
(2)在對數據庫只執行一次性存取的時侯,用 Statement 對象進行處理。
(3)PreparedStatement的第一次執行消耗是很高的. 它的性能體現在后面的重復執行