Mybatis常見的面試題總結
什麼是Mybatis?
1. mybatis是一個半ORM框架,它內部封裝了JDBC,開發時只需要關乎sql語句本身,不需要花費精力去處理驅動,建立連線,建立1statement等繁複過程。 2. mybatis可以使用xml或註解來配置和對映原生資訊。將pijo對映成資料庫中的記錄,避免了幾乎所有的JDBC 程式碼和手動設定引數以及獲取結果集。 3. 通過xm檔案或註解的方式將要執行的各種statement配置起來,並通java物件和statement中sql的動態引數進行對映生成最終的sql語句,最後由mybatis框架執行sql並將結果對映java物件返回.
Mybatis的優缺點?
優點:
1. 基於sql語句程式設計,相當靈活,不會對應用程式或者資料庫的現有設計造成任何影響,sql寫在xml裡,解除了sql與程式程式碼的耦合, 2. 能夠與spring很好的整合, 3. 消除了JDBC的大量冗餘程式碼,不需要手動開關連線,很好的與各種資料庫相容
缺點:
1. sql語句編寫量偏多, 2. sql'語句依賴於資料庫,倒追資料庫移植性差,不能隨意更換資料庫.
Mybatis使用場合?
專注於sql本身,是一個足夠靈活的dao層解決方案.,對效能的要求很高,或者需求多變的專案,
#{}和${}的區別是什麼?
#{}是預編譯處理,${}是字串替換。
Mybatis在處理#{}時,會將sql中的#{}替換為?號,呼叫PreparedStatement的set方法來賦值;
Mybatis在處理${}時,就是把${}替換成變數的值。
使用#{}可以有效的防止SQL注入,提高系統安全性。
當實體類的屬性名和表種欄位名不一致怎麼辦?
有兩種解決方案:可以在sql語句給欄位名取別名,別名於實體類屬性名同名,也可以用<resultMap>來對映欄位名和實體類屬性名一一對應.
模糊查詢like語句該怎麼寫?
第一種:在java程式碼新增sql萬用字元
<select id=”selectlike”>
select * from foo where bar like #{value}
</select>
第二種:在sql語句中拼接萬用字元,會引起sql注入
<select id=”selectlike”>
select * from foo where bar like "%"#{value}"%"
</select>
通常一個Xml對映檔案,都會寫一個Dao介面與之對應,請問,這個Dao介面的工作原理是什麼?Dao接口裡的方法,引數不同時,方法能過載嗎?
Dao介面即Mapper介面。介面的全限名,就是對映檔案中的namespace的值;介面的方法名,就是對映檔案中Mapper的Statement的id值;介面方法內的引數,就是傳遞給sql的引數。 mapper介面是沒有實現類的,當呼叫介面方法時,介面全限名+方法名拼接字串作為key值,可唯一定位一個MapperStatement。在Mybatis中,每一個<select>、<insert>、<update>、<delete>標籤,都會被解析為一個MapperStatement物件。
mapper接口裡的方法是不能被過載的,因為是使用 全限名+方法名 的儲存和尋找策略
Mybatis是如何將sql執行結果封裝為目標物件並返回的?都有哪些對映形式?
第一種是使用<resultMap>標籤,逐一定義資料庫列名和物件屬性名之間的對映關係。
第二種是使用sql列的別名功能,將列的別名書寫為物件屬性名。
有了列名與屬性名的對映關係後,Mybatis通過反射建立物件,同時使用反射給物件的屬性逐一賦值並返回,那些找不到對映關係的屬性,是無法完成賦值的。
如何執行批量插入?
先建立一個簡單的插入語句
<insert id=”insertname”>
insert into names (name) values (#{value})
</insert>
然後在程式碼執行下面的
list<string> names = new arraylist();
names.add(“fred”);
names.add(“barney”);
names.add(“betty”);
names.add(“wilma”);
// 注意這裡 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();
}
如何獲取自動生成的(主)鍵值?
<insert id=”insertname” usegeneratedkeys=”true” keyproperty=”id”>
insert into names (name) values (#{name})
</insert>
在mapper中如何傳遞多個引數?
(1)第一種:
//DAO層的函式
Public UserselectUser(String name,String area);
//對應的xml,#{0}代表接收的是dao層中的第一個引數,#{1}代表dao層中第二引數,更多引數一致往後加即可。
<select id="selectUser"resultMap="BaseResultMap">
select * fromuser_user_t whereuser_name = #{0} anduser_area=#{1}
</select>
(2)第二種: 使用 @param 註解:
public interface usermapper {
user selectuser(@param(“username”) string username,@param(“hashedpassword”) string hashedpassword);
}
然後,就可以在xml像下面這樣使用(推薦封裝為一個map,作為單個引數傳遞給mapper):
<select id=”selectuser” resulttype=”user”>
select id, username, hashedpassword
from some_table
where username = #{username}
and hashedpassword = #{hashedpassword}
</select>
(3)第三種:多個引數封裝成map
try{
//對映檔案的名稱空間.SQL片段的ID,就可以呼叫對應的對映檔案中的SQL
//由於我們的引數超過了兩個,而方法中只有一個Object引數收集,因此我們使用Map集合來裝載我們的引數
Map<String, Object> map = new HashMap();
map.put("start", start);
map.put("end", end);
return sqlSession.selectList("StudentID.pagination", map);
}catch(Exception e){
e.printStackTrace();
sqlSession.rollback();
throw e; }
finally{
MybatisUtil.closeSqlSession();
}
Mybatis的Xml對映檔案中,不同的Xml對映檔案,id是否可以重複?
不同的Xml對映檔案,如果配置了namespace,那麼id可以重複;如果沒有配置namespace,那麼id不能重複
Mybatis的一級、二級快取:
一級快取 事務範圍:快取只能被當前事務訪問。快取的生命週期 依賴於事務的生命週期當事務結束時,快取也就結束生命週期。 在此範圍下,快取的介質是記憶體。 二級快取 程序範圍:快取被程序內的所有事務共享。這些事務有 可能是併發訪問快取,因此必須對快取採取必要的事務隔離機制。 快取的生命週期依賴於程序的生命週期,程序結束時, 快取也就結束了生命週期。程序範圍的快取可能會存放大量的資料, 所以存放的介質可以是記憶體或硬碟。
什麼是MyBatis的介面繫結?有哪些實現方式?
介面繫結,就是在MyBatis中任意定義介面,然後把接口裡面的方法和SQL語句繫結, 我們直接呼叫介面方法就可以,這樣比起原來了SqlSession提供的方法我們可以有更加靈活的選擇和設定。
介面繫結有兩種實現方式,一種是通過註解繫結,就是在介面的方法上面加上 @Select、@Update等註解,裡面包含Sql語句來繫結;另外一種就是通過xml裡面寫SQL來繫結, 在這種情況下,要指定xml對映檔案裡面的namespace必須為介面的全路徑名。當Sql語句比較簡單時候,用註解繫結, 當SQL語句比較複雜時候,用xml繫結,一般用xml繫結的比較多。
使用MyBatis的mapper介面呼叫時有哪些要求?
① Mapper介面方法名和mapper.xml中定義的每個sql的id相同; ② Mapper介面方法的輸入引數型別和mapper.xml中定義的每個sql 的parameterType的型別相同; ③ Mapper介面方法的輸出引數型別和mapper.xml中定義的每個sql的resultType的型別相同; ④ Mapper.xml檔案中的namespace即是mapper