1动态sql
Mybatis 的映射文件中,第一篇文章的 SQL 都是比较简单的,有些时候业务逻辑复杂时,我们的 SQL是动态变化的,此时就需要动态的拼接sql
常用的拼接sql有
- if
- choose (when, otherwise)
- trim (where, set)
- foreach
还是采用01Mybatis入门的user表
1.1动态sql:if和where的使用
业务sql:
SELECT * FROM user where id=? and username=? and password=?
业务场景:当id,username,password任意为空时,还能正常查询数据
userMapper.xml映射文件和userMapper.java接口为
<!-- 已设置别名parameterType采用别名方式-->
<select id="findByCondition" parameterType="user" resultType="user">
select * from user
<where>
<if test="id!=0">
and id=#{id}
</if>
<if test="username!=null">
and username=#{username}
</if>
<if test="password!=null">
and password=#{password}
</if>
</where>
</select>
public List<User> findByCondition(User user);
当where后全部条件为空时,<where>标签封装sql时会自动去掉,sql语句为select * from user;
当id、username、password任意为空是,<if>标签封装sql时,会把and去掉
测试方法为
@Test
public void test01() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession session = sqlSessionFactory.openSession(true);//开启事务 默认是关闭的
UserMapper mapper = session.getMapper(UserMapper.class);
User user = new User();
user.setId(1);
user.setUsername("关羽");//可以去掉任意条件
// user.setPassword("asd");//
List<User> users = mapper.findByCondition(user);
System.out.println(users);
session.close();
}
注释掉password参数时,向数据库传入的参数为
1.2动态sql:foreach的使用
业务sql:select * from user WHERE id in( ? , ? , ? )
业务场景:根据传入id数来查询对应的数据
userMapper.xml映射文件和userMapper.java接口为
public List<User> findByIds(List<Integer> ids);
<select id="findByIds" parameterType="list" resultType="user">
<!-- <include refid="selectUser"></include>-->
select * from user
<where>
<foreach collection="list" open="id in(" close=")" item="id" separator=",">
#{id}
</foreach>
</where>
</select>
• collection:代表要遍历的集合元素,注意编写时不要写#{}
• open:代表语句的开始部分
• close:代表结束部分
• item:代表遍历集合的每个元素,生成的变量名
• sperator:代表分隔符
测试代码为
@Test
public void test02() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession session = sqlSessionFactory.openSession(true);//开启事务 默认是关闭的
UserMapper mapper = session.getMapper(UserMapper.class);
List<Integer> ids = new ArrayList<>();
ids.add(1);
ids.add(2);
ids.add(3);
List<User> byIds = mapper.findByIds(ids);
System.out.println(byIds);
session.close();
}
封装的sql为
1.3动态sql:sql的使用
Sql 中可将重复的 sql 提取出来,使用时用 include 引用即可,最终达到 sql 重用的目的
上述的映射文件可修改为
<!--sql语句抽取-->
<sql id="selectUser">select * from user</sql>
<select id="findByIds" parameterType="list" resultType="user">
<include refid="selectUser"></include>
<where>
<foreach collection="list" open="id in(" close=")" item="id" separator=",">
#{id}
</foreach>
</where>
</select>