【从零开始学Mybatis笔记(六)】动态sql

通过mybatis提供的各种标签方法实现动态拼接sql。
需求:根据性别和名字查询用户
查询sql:
SELECT id, username, birthday, sex, address FROM user WHERE sex = 1 AND username LIKE '%张%'

If标签

第一步:Mapper.xml文件
UserMapper.xml配置sql,如下:

<!-- 根据条件查询用户 -->
<select id="queryUserByWhere" parameterType="user" resultType="user">
	SELECT id, username, birthday, sex, address FROM `user`
	WHERE sex = #{sex} AND username LIKE
	'%${username}%'
</select>

第二步 Mapper接口

编写Mapper接口,如下图:

第三步 测试方法

@Test
public void testQueryUserByWhere() {
	// mybatis和spring整合,整合之后,交给spring管理
	SqlSession sqlSession = this.sqlSessionFactory.openSession();
	// 创建Mapper接口的动态代理对象,整合之后,交给spring管理
	UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

	// 使用userMapper执行根据条件查询用户
	User user = new User();
	user.setSex("1");
	user.setUsername("张");

	List<User> list = userMapper.queryUserByWhere(user);

	for (User u : list) {
		System.out.println(u);
	}

	// mybatis和spring整合,整合之后,交给spring管理
	sqlSession.close();
}

输出结果

问题
如果注释掉 user.setSex("1"),输出如下图:

测试结果二很显然不合理。
按照之前所学的,要解决这个问题,需要编写多个sql,查询条件越多,需要编写的sql就更多了,显然这样是不靠谱的。

解决方案
使用动态sql的if标签

改造UserMapper.xml,如下:

<!-- 根据条件查询用户 -->
<select id="queryUserByWhere" parameterType="user" resultType="user">
	SELECT id, username, birthday, sex, address FROM `user`
	WHERE 1=1
	<if test="sex != null and sex != ''">
		AND sex = #{sex}
	</if>
	<if test="username != null and username != ''">
		AND username LIKE
		'%${username}%'
	</if>
</select>

注意字符串类型的数据需要要做不等于空字符串校验。

输出结果

如上图所示,测试OK

Where标签

上面的sql还有where 1=1 这样的语句,很麻烦
可以使用where标签进行改造,可以去掉sql语句的前and

改造UserMapper.xml,如下

<!-- 根据条件查询用户 -->
<select id="queryUserByWhere" parameterType="user" resultType="user">
	SELECT id, username, birthday, sex, address FROM `user`
<!-- where标签可以自动添加where,同时处理sql语句中第一个and关键字 -->
	<where>
		<if test="sex != null">
			AND sex = #{sex}
		</if>
		<if test="username != null and username != ''">
			AND username LIKE
			'%${username}%'
		</if>
	</where>
</select>

Sql片段

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

把上面例子中的id, username, birthday, sex, address提取出来,作为sql片段,如下:

<!-- 根据条件查询用户 -->
<select id="queryUserByWhere" parameterType="user" resultType="user">
	<!-- SELECT id, username, birthday, sex, address FROM `user` -->
	<!-- 使用include标签加载sql片段;refid是sql片段id -->
	SELECT <include refid="userFields" /> FROM `user`
	<!-- where标签可以自动添加where关键字,同时处理sql语句中第一个and关键字 -->
	<where>
		<if test="sex != null">
			AND sex = #{sex}
		</if>
		<if test="username != null and username != ''">
			AND username LIKE
			'%${username}%'
		</if>
	</where>
</select>

<!-- 声明sql片段 -->
<sql id="userFields">
	id, username, birthday, sex, address
</sql>

如果要使用别的Mapper.xml配置的sql片段,可以在refid前面加上对应的Mapper.xml的namespace

例如下图

foreach标签

向sql传递数组或List,mybatis使用foreach解析,如下:

根据多个id查询用户信息
查询sql:
SELECT * FROM user WHERE id IN (1,10,24)

1.包装类

第一步 改造QueryVo
如下图在pojo中定义list属性ids存储多个用户id,并添加getter/setter方法

第二步 编写UserMapping.xml

<mapper namespace="com.tyust.mybatis.mapper.UserMapper">

	<select id="selectUserInfoByIds"
		parameterType="com.tyust.mybatis.pojo.QueryVo"
		resultType="com.tyust.mybatis.pojo.User">
		select * from user
		<where>
			<!-- foreach标签,进行遍历 -->
			<!-- collection:遍历的集合,这里是QueryVo的ids属性 -->
			<!-- item:遍历的项目,可以随便写,,但是和后面的#{}里面要一致 -->
			<!-- open:在前面添加的sql片段 -->
			<!-- close:在结尾处添加的sql片段 -->
			<!-- separator:指定遍历的元素之间使用的分隔符 -->
			<foreach collection="idsList" item="item" open="id In ("
				close=")" separator=",">
				#{item}
			</foreach>
		</where>
	</select>
	
</mapper>

第三步 测试

public class MybatisSecondTest {

	public static void main(String[] args) throws Exception {

		InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
		SqlSession sqlSession = sqlSessionFactory.openSession();

		UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

		List<Integer> ids = new ArrayList<Integer>();
		ids.add(16);
		ids.add(22);
		ids.add(24);

		QueryVo vo = new QueryVo();
		vo.setIdsList(ids);

		List<User> list = userMapper.selectUserInfoByIds(vo);

		for (User user : list) {

			System.out.println(user);

		}

	}

}

输出结果

2. List数组

第一步 修改UserMapping.xml

第二步 测试
去除QueryVo代码

输出结果

3. Integer[]数组

第一步 修改UserMapping.xml

第二步 测试

输出结果

posted @ 2020-04-28 11:46  朱李洛克  阅读(193)  评论(0编辑  收藏  举报
// 侧边栏目录 // https://blog-static.cnblogs.com/files/douzujun/marvin.nav.my1502.css