項目告一段落,業務代碼也寫得差不多了,框架仍然用的是 ssm ,為了省去單表數據庫操作的代碼編寫,繼續用 mybatis generator 生成單表對應的實體類、dao層映射關聯及配置文件,私下還嘗試了幾個實現批量插入,翻頁查詢及實體類序列化的插件,還是很奏效的。下面着重介紹一下近期開發中常見的 mybatis xml 中的特殊寫法。
1. 關於 >,< 比較運算符的使用
一種寫法是直接將 > 換成 > 把 < 換成 <
<if test="start != null"> AND call_time >= #{start} </if> <if test="end != null"> AND call_time <= #{end} </if>
另一種寫法是用 <![CDATA[ *** ]]> 將 sql 包起來:
<![CDATA[ and create_time >= #{start} ]]>
2. 實現模糊查詢 like
一種是比較規矩一點的寫法,用 <bind name=" *** " value = " *** " /> 實現 like 子句的綁定:
<if test="secretId != null and secretId != ''"> <bind name="pattern" value="'%' + secretId + '%'" /> and secret_id like #{pattern} </if>
注意將 <bind .../> 寫在條件判斷里面,否則當 secretId 為 null 的時候是會出異常的。
另一種比較簡單粗暴,直接寫為 '%${like_clause}%' 放到語句中:
<if test="batchNo != null and batchNo != ''"> WHERE batch_no LIKE '%${batchNo}%' </if>
3. IF(***,***,***) 這樣的 mysql 函數在 mybatis 中無效:
<select id="getCallerItems" parameterType="java.lang.String"> SELECT a.account AS name, IF(tmp1.calledNum IS NULL,0,tmp1.calledNum), IF(tmp2.ownedCallNum IS NULL,0,tmp2.ownedCallNum) FROM account a LEFT JOIN ( SELECT COUNT(*) AS calledNum,`owner` FROM secret_pool WHERE `status` = 0 <if test="batchNo !=null"> and batch_no = #{batchNo} </if> AND call_round > 0 GROUP BY `owner` )tmp1 ON a.account = tmp1.`owner` LEFT JOIN ( SELECT COUNT(*) AS ownedCallNum,`owner` FROM secret_pool WHERE `status` = 0 <if test="batchNo !=null"> and batch_no = #{batchNo} </if> GROUP BY `owner` )tmp2 ON a.account = tmp2.`owner` </select>
這里我是想用將外連接中因匹配不到對應結果而產生的 null 替換成 0 ,結果非但沒有替換成功還查不出正確的結果,心塞。
4. <where>,<choose>,<foreach> 標簽的應用:
<where></where> 廣泛用於非必傳參數的條件查詢;
mybatis 中沒有表示 else if 的標簽,可用<choose> 配合 <otherwise> 來代替;
<foreach> 在傳入參數包含集合的時候可用到;
<select id="selectByPagination" resultMap="BaseResultMap" parameterType="bz.sunlight.dto.UserSearchDTO"> SELECT u.* FROM `user` u LEFT JOIN user_role ur ON u.Id = ur.User_Id LEFT JOIN role r ON ur.Role_Id = r.Id <where> <if test="name != null and name != ''"> u.`Name` LIKE '%${name}%' </if> <if test="status != null"> AND u.Status = #{status} </if> <if test="roleId != null"> AND r.Id IN <foreach item="item" collection="roleIds" separator="," open="(" close=")" index=""> #{item, jdbcType=VARCHAR} </foreach> </if> </where> <if test="sortField != null and sortField != ''"> ORDER BY <choose> <when test="isDesc != null and isDesc"> ${sortField} DESC </when> <otherwise> ${sortField} </otherwise> </choose> </if> <if test="pageSize != null"> <if test="offset != null"> limit ${offset}, ${pageSize} </if> <if test="offset == null"> limit ${pageSize} </if> </if> </select>
其實說到底,不管哪種寫法都是為了實現一條 sql 語句,后台開發核心還是 sql ,即使框架用得再熟,如果對理解不透數據模型不能高效地查出准確的結果,什么高大上的實現方式都是花架子,至於到底選擇哪種寫法,個人覺得越簡單越好。我雖然在上面列舉了不同的實現方式都因為在對的時間遇到了不一定對的它,記下來緬懷那段邂逅。
