Mybatis 的映射文件中,有些时候业务逻辑复杂时,我们的SQL是动态变化的,而动态sql可以根据不同条件有不同的动态变化。
- 例:查询学生表的信息,条件是姓名、性别、年龄。但是我第二次查询只要姓名、性别。不使用动态sql就需要编写两条sql语句,比较麻烦。动态sql就可以解决这个问题。
if标签:
<where>:
条件标签,替换sql里的WHERE
<if>:
条件判断标签
格式:
<where>:条件标签。如果有动态条件,则使用该标签代替 where 关键字。
<if>:条件判断标签。
<if test=“条件判断”>
查询条件拼接
</if>
配置文件:
<select id="selectCondition" resultType="student" parameterType="student">
SELECT * FROM student
<where>
<if test="id != null">
id = #{id}
</if>
<if test="name != null">
AND name = #{name}
</if>
<if test="age != null">
AND age = #{age}
</if>
</where>
</select>
接口:
//多条件查询
public abstract List<Student> selectCondition(Student stu);
//根据多个id查询
public abstract List<Student> selectByIds(List<Integer> ids);
测试:
// 动态sql查询
@Test
public void selectCondition() throws IOException {
//1.加载核心配置文件
InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
//2.获取SqlSession工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//3.通过工厂对象获取SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession(true);
//4.获取StudentMapper接口的实现类对象
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
Student stu = new Student();
stu.setId(2);
stu.setName("李四");
// stu.setAge(24);
//5.调用实现类的方法,接收结果
List<Student> list = mapper.selectCondition(stu);
//6.处理结果
for (Student student : list) {
System.out.println(student);
}
//7.释放资源
sqlSession.close();
is.close();
}
foreach标签:
循环遍历标签
格式:
<foreach>:循环遍历标签。适用于多个参数或者的关系。
<foreach collection=“”open=“”close=“”item=“”separator=“”>
获取参数
</foreach>
属性:
collection:参数容器类型, (list:集合, array:数组)
open:开始的 SQL 语句
close:结束的 SQL 语句
item:参数变量名
separator:分隔符
配置文件:
<select id="selectByIds" resultType="student" parameterType="list">
SELECT * FROM student
<where>
<foreach collection="list" open="id IN (" close=")" item="id" separator=",">
#{id}
</foreach>
</where>
</select>
测试:
@Test
public void selectByIds() throws IOException {
//1.加载核心配置文件
InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
//2.获取SqlSession工厂对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//3.通过工厂对象获取SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession(true);
//4.获取StudentMapper接口的实现类对象
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
List<Integer> ids = new ArrayList<>();
ids.add(1);
ids.add(2);
ids.add(3);
//5.调用实现类的方法,接收结果
List<Student> list = mapper.selectByIds(ids);
//6.处理结果
for (Student student : list) {
System.out.println(student);
}
//7.释放资源
sqlSession.close();
is.close();
}
SQL片段抽取:
可以将一些重复性的SQL语句进行抽取,达到复用的效果
格式:
<sql>:抽取 SQL 语句标签。
<include>:引入 SQL 片段标签。
<sql id=“片段唯一标识”>抽取的 SQL 语句</sql> <include refid=“片段唯一标识”/>
配置文件:
<!-- 这里是抽取的SQL语句 -->
<sql id="select">SELECT * FROM student </sql>
<select id="selectByIds" resultType="student" parameterType="list">
<include refid="select"/>
<where>
<foreach collection="list" open="id IN (" close=")" item="id" separator=",">
#{id}
</foreach>
</where>
</select>