mybatis标签
想实现一个类似于下面这样的动态sql
select * from user where ( id like '%1%' or name like '%foo%') and active=1
其中参数可以是动态的,可以为null
因为要实现权限分离,所以下面一行的AND是自动拼接的
这样就需要把上面的条件括起来。
最开始用<if>
但是会报错,就不展示了
后来改成这样,就好使了
SELECT
*
FROM
p_ve_association pva
LEFT JOIN p_park pp ON pva.park_id = pp.park_key
LEFT JOIN ( SELECT count( id ) AS subCount, association_id FROM p_ve_association_sub GROUP BY association_id ) subCount ON subCount.association_id = pva.id
right JOIN (
SELECT
*
FROM
p_vehicle pv
LEFT JOIN p_ve_association_sub pvas ON pv.id = pvas.vehicle_id
WHERE
pv.tombstone = 0
<if test="tombstone != null">AND pvas.tombstone = #{tombstone}</if>
) pvv ON pva.id = pvv.associationId
<where>
(
<trim prefixOverrides="and|or">
<if test="deleteTimeStart !=null and deleteTimeEnd !=null">
and pva.updated_at between #{deleteTimeStart} and #{deleteTimeEnd}
</if>
<if test="parkId != null and parkId != '' ">
and pva.park_id = #{parkId}
</if>
<if test="lotModel != null and lotModel != '' ">
and pp.park_module = #{lotModel}
</if>
<if test="carNum != null and carNum != '' ">
and pvv.number like '%${carNum}%'
</if>
<if test="name != null and name != '' ">
and pvv.name like '%${name}%'
</if>
<if test="phone != null and phone != '' ">
and pvv.phone = #{phone}
</if>
<if test="enable != null and enable != '' ">
and pva.enable = #{enable}
</if>
<if test=" isValid != null and isValid != '' and isValid != 0 ">
and pva.is_valid = #{isValid}
</if>
<if test="tombstone != null">
AND pva.tombstone = #{tombstone}
</if>
<if test="auditStatus != null and auditStatus != '' and auditStatus != 9">
and pva.audit_status = #{auditStatus}
</if>
<if test="auditStatus == null or auditStatus == ''">
and pva.audit_status != 3
</if>
<choose>
<when test="carNum == null or carNum == '' ">
<choose>
<when test="auditStatus != null and auditStatus != '' and auditStatus == 9">
or pva.audit_status = 3)
</when>
<otherwise>
)
</otherwise>
</choose>
</when>
<otherwise>
)
</otherwise>
</choose>
</trim>
<!-- 数据范围过滤 -->
${dataScop}
</where>
order by pva.updated_at desc
记录下标签属性
<where>标签
示例如下:
<select id="findUserInfoByUnoQuantity" parameterType="Map"
resultMap="UserInfoResult">
select * from userinfo
<where>
<if test="department!=null">
and department like #{department}
</if>
<if test="gender!=null">
AND gender=#{gender}
</if>
<if test="position!=null">
AND position like #{position}
</if>
</where>
</select>
【解释】
a.select之后没有直接写Sql语句的where,而是使用标签
b.按照标准写法,第一个标签内的AND应该不写,但是,就算开发中书写也不会报错。这就是where标签帮助我们自动的移除了第一个AND链接。但是,第二个之后的标签内,必须有AND链接。
c.如果没有一个条件符合,则返回所有条目。
d.标签的其他用法请参考前文,这里不再赘述
3.修改单元测试方法,如下:
@Test
public void testSeletOne() {
try {
Map<String, Object> map = new HashMap<String, Object>();
map.put("department", "1");
map.put("gender", "1");
map.put("position", "工程师");
Departments d = new Departments("2", "%售%");
map.put("d", d);
UserInfoDao userInfo = sqlSession.getMapper(UserInfoDao.class);
List<UserInfo> UIList = userInfo.findUserInfoByUnoQuantity(map);
for (UserInfo ui : UIList) {
System.out.println(ui.toString());
}
} catch (Exception e) {
e.printStackTrace();
}
}
4.运行单元测试方法,观察输出即可。
5.结论:where 元素知道只有在一个以上的条件有值的情况下才去插入“WHERE”子句。而且,若内容是“AND”或“OR”开头的,where 元素也知道如何将他们去除。
<trim>标签
1.该标签的功能与类似,并且额外的提供了前缀后缀功能。具体用法如下:
2.修改Mapper文件,具体内容如下:
<select id="findUserInfoByTrim" parameterType="Map"
resultMap="UserInfoResult">
select * from userinfo
<trim prefix="where" prefixOverrides="and|or">
<if test="department!=null">
AND department like #{department}
</if>
<if test="gender!=null">
AND gender=#{gender}
</if>
<if test="position!=null">
AND position like #{position}
</if>
</trim>
</select>
【解释】
a.我们使用替代标签。
b.属性 prefix=“where” 表示:加前缀 where。
c.属性prefixOverrides=“and|or” 表示:自动覆盖第一个and或者or.
d.后缀的用法类似;