通过mybatis提供的各种标签方法实现动态拼接sql。
为什么用if标签?
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接口
List<User> queryUserByWhere(User user);
测试方法
测试方法:
@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”),那么输出的结果为空,因为我们的where中必须同时去匹配sex与username如果我们想通过其中任意一个查询数据库结果,那么又需要分别添加两个SQL语句代码,那么如果有多个条件呢?是不是每次都要重新添加,显然之前这种方式是不靠谱的,因为引入动态sql的if标签可以解决此问题。
使用if标签
注意:字符串类型的数据需要要做不等于空字符串校验。
and放在sex或者username的前面是合法的,如果前面没有条件会自动把and去掉,如果放在条件后面不会自动去掉,可能造成异常!
where 1=1是sql语句条件逻辑判断表达式,由于1=1成立,恒为真,该表达式1=1将始终返回”真”。
改造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>
Where标签
上面的sql还有where 1=1 这样的语句,很麻烦
可以使用where标签进行改造
改造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片段,如下:
注意:申明用sql标签使用用include和里面的refid属性
<!-- 根据条件查询用户 -->
<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)
QueryVo类:
如下图在pojo中定义list属性ids存储多个用户id,并添加getter/setter方法
package com.itheima.mybatis.pojo;import java.io.Serializable;
import java.util.List;
/*** new Message* @author lx**/
public class QueryVo implements Serializable {/*** */private static final long serialVersionUID = 1L;//private User user;List<Integer> idsList;Integer[] ids;public List<Integer> getIdsList() {return idsList;}public void setIdsList(List<Integer> idsList) {this.idsList = idsList;}public Integer[] getIds() {return ids;}public void setIds(Integer[] ids) {this.ids = ids;}public User getUser() {return user;}public void setUser(User user) {this.user = user;}}
Mapper.xml文件
UserMapper.xml添加sql,如下:
<!-- 根据ids查询用户 -->
<select id="queryUserByIds" parameterType="queryVo" resultType="user">SELECT * FROM `user`<where><!-- foreach标签,进行遍历 --><!-- collection:遍历的集合,这里是QueryVo的ids属性 --><!-- item:遍历的项目,可以随便写,,但是和后面的#{}里面要一致 --><!-- open:在前面添加的sql片段 --><!-- close:在结尾处添加的sql片段 --><!-- separator:指定遍历的元素之间使用的分隔符 --><foreach collection="ids" item="item" open="id IN (" close=")"separator=",">#{item}</foreach></where>
</select>
测试方法:
@Test
public void testQueryUserByIds() {// mybatis和spring整合,整合之后,交给spring管理SqlSession sqlSession = this.sqlSessionFactory.openSession();// 创建Mapper接口的动态代理对象,整合之后,交给spring管理UserMapper userMapper = sqlSession.getMapper(UserMapper.class);// 使用userMapper执行根据条件查询用户QueryVo queryVo = new QueryVo();List<Integer> ids = new ArrayList<>();ids.add(1);ids.add(10);ids.add(24);queryVo.setIds(ids);List<User> list = userMapper.queryUserByIds(queryVo);for (User u : list) {System.out.println(u);}// mybatis和spring整合,整合之后,交给spring管理sqlSession.close();
}