mybatis XML 中<if>、<choose>、<when>、<otherwise>等標簽的使用
一般使用在多條查詢,雖然也可以通過注解寫,我比較菜,我不會。
一般多條查詢怎么解決?
1.如果是單表間的多條件查詢我是直接調用mybatis plus的api ,里面可以有直接判空條件的api。
如:queryWrapper.like(StringUtils.isNotEmpty(變量參數), "表字段",變量參數);
2.如果是多表間的多條件查詢,我建議用XML來做吧,當然注解也行。
<if>其實跟java的if類似,符合條件的就進去,那符合的進去,不符合的怎么辦呢,
mybatis 提供了<choose>、<when>、<otherwise>這組標簽組合着用,<when>就相當於if,<otherwise>就相當於else,但是<when>、<otherwise>需要放在<choose>里面才能使用。
這邊我就用我最近遇到一個業務來演示吧。一個多表且不同表條件的查詢 如下:
看看我的XML文件<if>、<where>、<choose>、<when>、<otherwise>等標簽一條語句搞定。
建議模糊查詢的參數在傳參就先將參數做個處理,如: “%參數%”,網上也有人直接在XML里寫成這樣 '%'||'#{參數}||'%',但是這種寫法查出來的數據范圍可能會偏大 。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="cn.mindgd.mapper.MaterielStorageMapper"> <!--建立查詢的列與對象屬性的對應關系-->
<!--由於查出來的數據是多張表的,我這邊就在實體類添加了一些渲染字段,下面用給這些字段取了別名-->
<resultMap id="BaseResultMap" type="cn.mindgd.domain.MaterielStorage"> <result column="materiel_storage_id" property="materielStorageId"/> <result column="material_code" property="materialCode"/> <result column="material_name" property="materialName"/> <result column="property_name" property="materialTypeName"/> <result column="stock" property="stock"/> <result column="total" property="total"/> </resultMap>
<!--COUNT(1) OVER() mysql 5.7 沒有這個語法OVER() ==>分頁查詢返回總記錄數-->
<select id="findMaterielStorageByMore" resultMap="BaseResultMap"> SELECT ms.materiel_storage_id AS materiel_storage_id,ms.position,m.material_code AS material_code,m.material_name AS material_name,dp.property_name AS property_name,ms.stock AS stock,COUNT(1) OVER() AS total FROM materiel_storage ms LEFT JOIN material m ON m.material_id=ms.material_id LEFT JOIN data_dictionary_property dp ON m.material_type_id=dp.property_id LEFT JOIN warehouse w ON w.warehouse_id=ms.warehouse_id LEFT JOIN construction_team ct ON ct.team_id =ms.team_id WHERE 1=1
<choose>
<!-- 集合判空 --> <when test="(null != warehouseIds and warehouseIds.size>0) and (null != teamIds and teamIds.size>0)"> AND ( w.warehouse_id IN <foreach collection="warehouseIds" item="warehouseId" open="(" separator="," close=")">#{warehouseId} </foreach> OR ct.team_id IN <foreach collection="teamIds" item="teamId" open="(" separator="," close=")">#{teamId} </foreach> ) </when> <otherwise> <if test="null != warehouseIds and warehouseIds.size>0"> AND w.warehouse_id IN <foreach collection="warehouseIds" item="warehouseId" open="(" separator="," close=")">#{warehouseId} </foreach> </if> <if test="null != teamIds and teamIds.size>0"> AND ct.team_id IN <foreach collection="teamIds" item="teamId" open="(" separator="," close=")">#{teamId} </foreach> </if> </otherwise> </choose> <!-- 字符串判空 --> <if test="null != materialName and '' !=materialName"> AND m.material_name like #{materialName} </if> <if test="null != materialCode and '' !=materialCode"> AND m.material_code=#{materialCode} </if> <!-- Integer類型判空 如果加了 and '' !=propertyId ,0 就傳不進去了,也就是不能像判斷字符串一樣去判斷他是否是空字符串--> <if test="null != propertyId"> AND dp.property_id=#{propertyId} </if> <if test="null != teamName and '' !=teamName"> AND ct.team_name like #{teamName} </if> <if test="(null != currentPage) and (null != size)"> LIMIT #{currentPage},#{size} </if> </select> </mapper>
直接在測試類測試
@SpringBootTest public class TestMaterielStorage { @Autowired(required = false) MaterielStorageMapper materielStorageMapper; @Test public void findMaterielStorageByMore() { List<Integer> warehouseIds = new ArrayList<>(); warehouseIds.add(1); warehouseIds.add(2); List<Integer> teamIds = new ArrayList<>(); // teamIds.add(1); // teamIds.add(2); List<MaterielStorage> materielStorageByMore = // materielStorageMapper.findMaterielStorageByMore("施", "P", null, 1, warehouseIds, teamIds, 0, 10); materielStorageMapper.findMaterielStorageByMore(null, null, null, null, null, null, 0, 10); System.out.println("輸出:" + materielStorageByMore); } }
效果1:
效果2:
效果3:
想看更多精彩內容,可以關注我的CSDN