Mybatis使用過程中的一些總結

1. myBatis choose when:條件查詢,以前不太清楚它的含義,都是使用if判斷,或在程序裏判斷,使用了之後,發覺有些場景下還是挺不錯的。

場景1:默認排序
<choose>
	<when test="sortName != null and sortType != null">
		ORDER BY ${sortName} ${sortType}
	</when>
	<otherwise>
		ORDER BY order_create_time DESC
	</otherwise>
</choose>

場景2:通過一個字段判斷是否支持模糊查詢
<choose>
	<when test="isLike != null and isLike !=''">
		<if test="sellerName != null">
			seller_name like #{sellerName,jdbcType=VARCHAR} and
		</if>
	</when>
	<otherwise>
		<if test="sellerName != null">
			seller_name = #{sellerName,jdbcType=VARCHAR} and
		</if>
	</otherwise>
</choose>

2. mybatis的sum()函數返回類型是BigDecimal類型,所以我們處理的時候需要注意下:

   1> 返回 Object 值,然後通過 Integer.parseInt(obj.toString()); 來得到int值;

    2> 返回 BigDecimal 值,然後通過 BigDecimal.intValue()得到需要的值,應該說我們推薦使用第二種方法。

   3> 如果指定resultType爲Long類型的話,則不用考慮BigDecimal;

<select id="selectByParams" resultType="java.util.Map" parameterType="java.util.Map">
		select sum(amount) as amountTotal,company_id as companyId
		from test
		<include refid="selectByParamsWhere" />
</select>

3. 同理,mybatis的count()函數返回類型是Long;


4. mybatis的#{} 和 ${}的不同場景,或者說區別:

  1) #{},預編譯SQL時,會將傳入的數據都當成一個字符串,會對自動傳入的數據加一個引號; ${}僅僅是文本替換。如:

select * from student order by #{stuId}
會轉化爲:
select * from student order by 'stu_id'
select * from student order by ${stuId}
會轉化爲:
select * from student order by stu_id
  2) ${}一般用在order by, limit, group by等場景
<if test=" offset != null and limit != null">
	limit ${offset}, ${limit}
</if>
  3) 能用#{}實現的方式就不要用${}來實現,主要是爲了防止sql注入問題;比如:

select * from ${tableName} where id = #{name}
假如,我們的參數 tableName 爲 
user; delete user; --
那麼 SQL 動態解析階段之後,預編譯之前的 sql 將變爲:
select * from user; delete user; -- where name = ?;
-- 之後的語句將作爲註釋,不起作用,因此本來的一條查詢語句偷偷的包含了一個刪除表數據的 SQL。

  4) 直接接受從用戶傳入的內容並直接訪問數據庫,這種做法是不安全的。這會導致潛在的SQL注入攻擊,因此不應該允許用戶輸入的數據直接訪問數據庫,應該對輸入的數據自行轉義並檢查。


5. mybatis在查詢的時候,如果返回的是map而不是實體對象的話,map中的value如果爲null的話,那這個字段就沒有返回,這樣的話可能會有空指針的出現;

  1)  一種方式就是不返回map,返回實體對象,然後映射一下;

  2)  另一種方式,網上說的,不過還沒驗證過;

在mybatis的配置文件中加入,mybatis必須3.2版本以上
<settings>  
  	<setting name="cacheEnabled" value="true"/>   
    <setting name="callSettersOnNulls" value="true"/>  
</settings>  

  3)  調用到這個接口的地方進行非空判斷;


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章