一、MyBatis 映射文件 SQL 深入
1. 动态 SQL 之 if 标签
动态sql常用于根据条件拼接查询语句。
1.1 UserMapper 接口方法
java
package com.qcby.mapper;
import java.util.List;
import cnom.qcby.domain.User;
public interface UserMapper {
// 条件查询
public List<User> findByWhere(User user);
}
1.2 UserMapper.xml 配置(使用 if 标签)
java
<select id="findByWhere" parameterType="com.qcby.domain.User" resultType="com.qcby.domain.User">
select * from user where 1 = 1
<if test="username != null and username != ''">
and username like #{username}
</if>
<if test="sex != null and sex != ''">
and sex = #{sex}
</if>
</select>
1.3 测试方法
java
@Test
public void testFindByWhere() throws IOException {
// 先加载主配置文件,加载到输入流中
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
// 创建SqlSessionFactory对象,创建SqlSession对象
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
// 创建SqlSession对象
SqlSession session = factory.openSession();
User user = new User();
user.setUsername("%熊%");
user.setSex("女");
// 条件查询
UserMapper mapper = session.getMapper(UserMapper.class);
List<User> list = mapper.findByWhere(user);
for (User user1 : list) {
System.out.println(user1);
}
// 关闭资源
session.close();
inputStream.close();
}
2. 动态 SQL 之 where 标签
<where>标签可以自动处理 SQL 拼接时多余的 AND 或 OR 关键字,并去掉多余的 where 1=1。
2.1 UserMapper.xml
java
<!-- 使用 where 标签,更优雅的条件查询 -->
<select id="findByWhere" parameterType="com.qcby.domain.User" resultType="com.qcby.domain.User">
select * from user
<where>
<if test="username != null and username != ''">
and username like #{username}
</if>
<if test="sex != null and sex != ''">
and sex = #{sex}
</if>
</where>
</select>
3. 动态 SQL 之 foreach 标签
<foreach> 标签用于遍历集合(如 List、数组),常用于构建 IN 语句或批量 OR 条件。
3.1 需求一:构建 id = 1 or id = 2 or id = 3 这样的查询
在 User 类中添加 List<Integer> ids 属性及 getter/setter。
java
public class User implements Serializable{
private static final long serialVersionUID = 525400707336671154L;
// 主键
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
// 定义ids属性,用来存储所有的id
private List<Integer> ids;
// 提供get和set方法
在UserMapper接口中添加方法
java
public List<User> findByIds(User user);
UserMapper.xml 配置
java
<!-- foreach 实现 or 拼接 -->
<select id="findByIds" parameterType="com.qcby.domain.User" resultType="com.qcby.domain.User">
select * from user
<where>
<foreach collection="ids" open="id = " separator="or id = " item="i">
#{i}
</foreach>
</where>
</select>
编写测试方法
java
@Test
public void testFindByIds() throws IOException {
// 先加载主配置文件,加载到输入流中
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
// 创建SqlSessionFactory对象,创建SqlSession对象
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
// 创建SqlSession对象
SqlSession session = factory.openSession();
User user = new User();
List<Integer> ids = new ArrayList<>();
ids.add(1);
ids.add(2);
ids.add(3);
user.setIds(ids);
// 条件查询
UserMapper mapper = session.getMapper(UserMapper.class);
List<User> list = mapper.findByIds(user);
for (User user1 : list) {
System.out.println(user1);
}
// 关闭资源
session.close();
inputStream.close();
}
3.2 需求二:构建 id in (1,2,3) 这样的查询
UserMapper.xml 配置
java
<!-- foreach 实现 IN 查询 -->
<select id="findByIds" parameterType="com.qcby.domain.User" resultType="com.qcby.domain.User">
select * from user
<where>
<foreach collection="ids" open="id in ( " separator="," close=")" item="i">
#{i}
</foreach>
</where>
</select>
4. 提取公共的 SQL 语句
使用 <sql> 和 <include> 标签可以定义并重用公共的 SQL 片段。
java
<!-- 定义公共 SQL -->
<sql id="findAllSql">
select * from user
</sql>
<!-- 使用公共 SQL -->
<select id="findAll" resultType="com.qcby.domain.User">
<include refid="findAllSql" />
</select>