复杂查询 --- 动态SQL

复杂查询 — 动态SQL

多条件查询

普通的sql查询多条判断条件时

select * from emp 
where 1=1 and ename = ? and job = ? and sal = ?

当其中一个条件为空时或者未提供会报错

mybatis提供了 if 标签

<if test="name != null">
    and ename like concat("%",#{name},"%")
</if>

判断失败则不加入sql语句

实例

//map传参
List<Emp> selectByCondition1(Map<String,Object> searchMap);
//顺序传参
List<Emp> selectByCondition2(String ename,String job,Double sal);
//对象传参
List<Emp> selectByCondition3(SearchMap searchMap);
public class SearchMap {
    private String name;
    private String job;
    private Double sal;
}
<select id="selectByCondition3" parameterType="hasmap" resultMap="empMap">
	select * from emp where
	<if test="ename != null">
		ename like concat("%",#{ename},"%")
	</if>
	<if test="job != null">
		and job  = #{job}
	</if>
	<if test="sal != null">
		and sal > #{sal}
	</if>
</select>

<select id="selectByCondition3" resultMap="empMap">
	select * from emp where
	<if test="param1 != null">
		ename like concat("%",#{param1},"%")
	</if>
	<if test="param2 != null">
		and job  = #{param2}
	</if>
	<if test="param3 != null">
		and sal > #{param3}
	</if>
</select>

<select id="selectByCondition3" parameterType="org.lanqiao.pojo.SearchMap" resultMap="empMap">
	select * from emp where
	<if test="name != null">
		ename like concat("%",#{name},"%")
	</if>
	<if test="job != null">
		and job  = #{job}
	</if>
	<if test="sal != null">
		and sal > #{sal}
	</if>
</select>

这样还是存在问题 如果其中第一条判断失败 那么第二条加入 会变成

select * from emp where and job = #{job}多余的and导致出错

可以通过一般方式解决

select * from emp where 1=1
	<if test="name != null">
		and ename like concat("%",#{name},"%")
	</if>
	<if test="job != null">
		and job  = #{job}
	</if>
	<if test="sal != null">
		and sal > #{sal}
	</if>

为了解决这个问题 mybatis提供了 where标签

select * from emp 
<where>
	<if test="name != null">
		and ename like concat("%",#{name},"%")
	</if>
	<if test="job != null">
		and job  = #{job}
	</if>
	<if test="sal != null">
		and sal > #{sal}
	</if>
</where>

where标签会自动出掉多余的第一个and或者or

foreach查询

需求

传入多个 id 查询用户信息,用下边两个 sql 实现:

SELECT * FROM USERS WHERE username LIKE '%张%' AND (id =10 OR id =89 OR id=16)
SELECT * FROM USERS WHERE username LIKE '%张%' AND id IN (10,89,16)

这样我们在进行范围查询时,就要将一个集合中的值,作为参数动态添加进来。

这样我们将如何进行参数的传递?

在 QueryVo 中加入一个 List 集合用于封装参数

/**
* <p>Description: 查询的条件</p>
*/
public class QueryVo implements Serializable {
    private List<Integer> ids;
    public List<Integer> getIds() {
        return ids;
    }
    public void setIds(List<Integer> ids) {
        this.ids = ids;
   }
}

持久层 Dao 接口

/**
* 根据 id 集合查询用户
* @param vo
* @return
*/
List<User> findInIds(QueryVo vo);

持久层 Dao 映射配置

<!-- 查询所有用户在 id 的集合之中 -->
<select id="findInIds" resultType="user" parameterType="queryvo">
	<!-- select * from user where id in (1,2,3,4,5); -->
	<include refid="defaultSql"></include>
	<where>
		<if test="ids != null and ids.size() > 0">
			<foreach collection="ids" open="id in ( " close=")" item="uid" separator=",">
				#{uid}
			</foreach>
		</if>
	</where>
</select>

SQL 语句:

select 字段 from user where id in (?)

<foreach>标签用于遍历集合,它的属性:

  • collection:代表要遍历的集合元素,注意编写时不要写#{}

  • open:代表语句的开始部分

  • close:代表结束部分

  • item:代表遍历集合的每个元素,生成的变量名

  • sperator:代表分隔符

1.3.3.1.编写测试方法

@Test
public void testFindInIds() {
    QueryVo vo = new QueryVo();
    List<Integer> ids = new ArrayList<Integer>();
    ids.add(41);
    ids.add(42);
    ids.add(43);
    ids.add(46);
    ids.add(57);
    vo.setIds(ids);
    //6.执行操作
    List<User> users = userDao.findInIds(vo);
    for(User user : users) {
        System.out.println(user);
    }
}

Mybatis 中简化编写的 SQL 片段 sql冗余

Sql 中可将重复的 sql 提取出来,使用时用 include 引用即可,最终达到 sql 重用的目的。

1 定义代码片段

<!-- 抽取重复的语句代码片段 -->
<sql id="defaultSql">
select * from user
</sql>

2 引用代码片段

<!-- 配置查询所有操作 -->
<select id="findAll" resultType="user">
	<include refid="defaultSql"></include>
</select>

<!-- 根据 id 查询 -->
<select id="findById" resultType="UsEr" parameterType="int">
	<include refid="defaultSql"></include>
	where id = #{uid}
</select>
发布了41 篇原创文章 · 获赞 1 · 访问量 833

猜你喜欢

转载自blog.csdn.net/DreamCloud714/article/details/104596253
今日推荐