mybatis中mapper的用法以及一些注意事項
這幾天在公司做專案,到了收尾的階段,但是發現自己在使用mybatis的時候給自己留下了很多的坑,於是乎花了兩天的時間來除錯和重新構思自己寫下的mapper.xml檔案,總算是有些收穫,在這裡分享給大家。
一、何為mapper.xml
mapper.xml是mybatis中的重要的組成部分,也算是核心之一,我們可以看到的就是他是由一些定義好的查詢資料庫的語句和一些xml規範定義好的。我們在使用mybatis的時候可以看到,在這裡mapper檔案相當於是一個dao層介面的實現,因為mapper中定義的查詢,id都必須要和dao層的方法是一致的,這樣才可以進行查詢。這裡最能體現mybatis特點的就是這個mapper配置檔案了,因為mybatis能從裡面的內容讀取對映,生成sql語句進行查詢。
二、mapper的寫法和注意事項
我們的mapper有很多種使用方法,這裡簡要說明與總結一下:
(1)、直接當做sql語句使用
我們可以使用mapper中的<select><udpate><insert><delete>標籤來拼接我們的sql語句,這裡寫的標籤為mybatis解析的頭,所以我們對應的sql語句必須寫在對應的標籤下面,方可成功。
(2)、加判斷的條件查詢語句
在mapper中,我們可以對條件加上應有的判斷,來進行一些分條件的查詢,尤其是在where子句中,這裡注意的是,使用判斷,也就是if也是一個標籤為<if test=""></if> 其中在test中為if的判斷條件,這裡的判斷就是一些取值的判斷,並沒有其他的作用但是寫法需要注意,可以直接使用Dao介面中傳下來的變數直接進行判斷。如下語句為增加了一個判斷用於拼接sql語句用的:
<if test='state=="0"'>
AND t_acceptanceform.acceptancestate!='0'
</if>
<if test='state!=0'>
AND t_acceptanceform.acceptancestate =#{state}
</if>
這裡就是在where中通過變數不同的條件來選擇不同的語句,使sql語句更加的靈活。
(3)、增加一些變數集合,用於查詢或者返回值
這裡所指的變數集合其實是兩種,一種是map型別的集合,一種是sql中自定義查詢欄位集合,我們在做返回值還有mybatis自動生成的程式碼中常見的就是這種map集合,一般叫做resultmap,他是可以和pojo等型別的實體類進行對應的,用於對於查詢返回值的接收和傳送,可以被mybatis機制自動轉換為一些List集合或者其他的集合之類的東西。
格式:
<resultMap id="" type="" > <!--id為標識這個map的唯一標誌,不能重複,type為對應到的pojo包路徑-->
<id column="" property="" jdbcType="" /> <!--column是列名,property為對應projo物件名,type就是資料庫中的型別-->
<result column="" property="" jdbcType="" />
</resultMap>
第二個是<sql>標籤為頭的一般查詢結果集,他的好處是可以自定義,也可以加入一些判斷,我們在做複雜查詢的時候一般可以用到他,下面是我寫的一個例子:
<sql id="outPutOrderDetail">
outputrepositorycode,
outdate,
consignee,
ordersno,
repocode,
transferpath,
acceptanceformcode,
address,
totalproducts,
createtime,
batchcount,
comments,
customerid,
pitposition
</sql>
使用的查詢:
<select id="queryOutPutHead" resultType="com.cn.echuxianshengshop.pojo.ext.OutPutOrderDetail">
SELECT
<include refid="outPutOrderDetail"/>
FROM
t_outputorderb , t_acceptanceform ,t_orders
WHERE
ordercode=belongorderid AND ordercode=ordersNo AND outputrepositorycode=#{opCode}
</select>
這裡再附上軟體自動生成的<sql>標籤內容,沒有仔細研究過裡面的東西,但是用到了for迴圈和if,應該就是邏輯判斷的一種,和寫條件都是差不多的。
<sql id="Example_Where_Clause" >
<where >
<foreach collection="oredCriteria" item="criteria" separator="or" >
<if test="criteria.valid" >
<trim prefix="(" suffix=")" prefixOverrides="and" >
<foreach collection="criteria.criteria" item="criterion" >
<choose >
<when test="criterion.noValue" >
and ${criterion.condition}
</when>
<when test="criterion.singleValue" >
and ${criterion.condition} #{criterion.value}
</when>
<when test="criterion.betweenValue" >
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
</when>
<when test="criterion.listValue" >
and ${criterion.condition}
<foreach collection="criterion.value" item="listItem" open="(" close=")" separator="," >
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>
這裡就是mybatis裡面用於拼接查詢條件進行查詢的一個拼接判斷,可以好好研究一下。
三、傳值的注意
我們都知道,在mapper中寫查詢的時候,我們都會用到一些查詢條件和傳入變數進行關聯的事情,一般這種都用的是#{變數名}或者是${變數名}來做取值,那麼他們到底有什麼區別呢?
1、#{param}會產生PreparedStatement,並且可以安全地設定引數(=?)的值。以為sql語句已經預編譯好了,傳入引數的時候,不會重新生產sql語句。安全性高。
2、${parem}則直接將{}號中的param插入字串,會產生sql注入的問題:
例如:select * from userwhere userName= ${userName}
輸出的結果為
select * from userwhere userName= “小明”
3、在特定場景下,例如如果在使用諸如order by '{param}',這時候就可以使用${}
4、#{}方式能夠很大程度防止sql注入,${}方式無法防止sql注入
5、${}方式一般用於傳入資料庫物件,例如傳入表名
字串替換:
預設情況下,使用#{}格式的語法會導致MyBatis建立預處理語句屬性並以它為背景設定安全的值(比如?)。這樣做很安全,很迅速也是首選做法,有時你只是想直接在SQL語句中插入一個不改變的字串。比如,像ORDER BY,你可以這樣來使用:
ORDER BY ${columnName}
這裡MyBatis不會修改或轉義字串。
重要:接受從使用者輸出的內容並提供給語句中不變的字串,這樣做是不安全的。這會導致潛在的SQL注入攻擊,因此你不應該允許使用者輸入這些欄位,或者通常自行轉義並檢查。
這裡一定要注意的是,可以用#{param}的時候儘量不要用${param}。