${}和#{}的區別是什么?
${}是字符串替換,#{}是預編譯處理。
Mybatis在處理#{}時,會將sql中的#{}替換為?號,調用PreparedStatement的set方法來賦值;
Mybatis在處理\({}時,就是把\){}原樣替換成變量的值。
使用#{}可以有效的防止SQL注入,提高系統安全性。
當實體類中的屬性名和表中的字段名不一樣 ,怎么辦 ?
方法一:通過在查詢的sql語句中定義字段名的別名,讓字段名的別名和實體類的屬性名一致。
<select id = ”selectorder” parametertype = ”int” resultetype = ”me.gacl.domain.order”>
select order_id id, order_no orderno ,order_price price form orders where order_id=#{id};
</select>
方法二:通過
模糊查詢再MyBatis中怎么寫
一般模糊查詢都是通過 like %xx% 這種形式來查詢的,xx是前端傳過來的查詢變量,在MyBatis中推薦使用字符串拼接函數的形式來使用,這樣出錯的可能性較小。
<if test="xx!= null and xx!= ''">
and user_name like concat('%',#{xx,jdbcType=VARCHAR},'%')
</if>
MyBatis中的Mapper只有接口,那實現類是怎么生成的?當我們調用Mapper接口中的某個方法時,這個方法是怎么跟Mapper映射文件中的SQL語句對應起來的。
在使用MyBatis的時候我們只需要定義Mapper接口進行了,具體的Mapper接口實現是通過動態代理的方式生成的。
MyBatis在啟動的時候會為每個Mapper映射文件指定一個MapperProxyFactory類,這個類是MapperProxy的工廠類,當我們調用sqlSession1.getMapper時,就會使用
MapperProxyFactory來生成動態代理類。生成的動態代理類代理了Mapper的所有接口。
CbondissuerMapper cbondissuerMapper10 = sqlSession1.getMapper(CbondissuerMapper.class);
下面來回答第二個問題,Mapper接口中的方法是怎么和映射文件中的SQL匹配起來的。
上面提到,Mapper接口的實現類是通過動態代理生成的,熟悉動態代理的應該知道調用Mapper接口的任何接口方法都會調到InvocationHandler接口的
invoke方法,在這里也就是MapperProxy的invoke方法。因為MapperProxy實現了InvocationHandler接口。
查看MapperProxy的invoke方法的源代碼,我們會發現接口方法調用可具體的SQL是通過一個叫做MapperStatement的對象關聯起來的。
MyBatis在啟動時會將Mapper文件中的每一個 <select>
、<insert>
、<update>
、<delete>
標簽解析為一個MapperStatement對象,並放入一個Map結構中。
放入時的key就是Mapper文件的namespace加上標簽值的id值。(這里我們也就知道了為什么配置映射文件時namespace需要和接口的全限定名一致,標簽的id需要
和接口的方法名一致)
也就是說在Mapper接口中定義的每個方法都有一個MapperStatement對象和它一一對應,這個MapperStatement對象包含了所有映射文件的信息,自然也包含了SQL
信息。所以Mapper接口就是通過MapperStatement對象和具體SQL匹配的。
Mapper接口中的方法定義能否通過方法簽名重載?
通過上面的介紹我們知道Mapper接口中的方法並不能通過方法名重載。因為MyBatis是通過接口的全限定名和方法名來匹配MapperStatement對象,
兩個方法名相同方法簽名不同的接口會匹配到同一個MapperStatement對象。