本节课开始学习mybatis 动态sql,
动态SQL是MyBatis的强大特性之一。如果你使用过JDBC或其它类似的框架,你应该能理解根据不同条件拼接SQL语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态SQL,可以彻底摆脱这种痛苦。
1.学会使用 if+where 进行多条件查询
2.学会使用 if+trim 进行多条件查询
if 标签 配合 test 属性 使用, 当test条件成立时 做if标签内的内容
where 元素只会在子元素返回任何内容的情况下才插入“WHERE"”子句。而且,若子句的开头为“AND"或"OR,where元素也会将它们去除。
实现功能:
根据 姓名及电话号码进行查询,
(1)如果姓名及电话号码都为空 则查询全部
(2)如果姓名为空,电话号码不为空 则按照电话号码进行模糊查询
(3)如果姓名不为空,电话号码为空 则按照姓名进行模糊查询
(4)如果姓名及电话号码都不为空 则按照姓名及电话号码进行模糊查询
老程序员在使用以上操作时, 都是做if判断拼接sql, 但在mybatis 中 我们使用 if+where标签即可
具体操作步骤如下 :
1. 修改StudentMapper.java 增加方法
/** * 按照姓名及电话查询 * @param name * @param phone * @return */ List<Student> query(String name,String phone);
2.修改SudentMapper.xml 增加select标签
<select id="query" resultType="student"> select * from student <where> <if test="param1 !=null and param1!=''"> and sname like concat('%',#{param1},'%') </if> <if test="param2 !=null and param2!=''"> and phone like concat('%',#{param2},'%') </if> </where> </select>
3. 编写测试类
(1) 传递 姓名与电话号码都为空
? ?
@Test public void testQuery() throws IOException { //获得SqlSession SqlSession session = sqlSessionFactory.openSession(); StudentMapper mapper = session.getMapper(StudentMapper.class); List<Student> list = mapper.query("",""); list.forEach((e)->System.out.println(e)); }
运行结果:
(2) 姓名 传递 凯, 电话为空
@Test public void testQuery() throws IOException { //获得SqlSession SqlSession session = sqlSessionFactory.openSession(); StudentMapper mapper = session.getMapper(StudentMapper.class); List<Student> list = mapper.query("凯",""); list.forEach((e)->System.out.println(e)); }
运行结果
(3)姓名为空,电话包含52
@Test public void testQuery() throws IOException { //获得SqlSession SqlSession session = sqlSessionFactory.openSession(); StudentMapper mapper = session.getMapper(StudentMapper.class); List<Student> list = mapper.query("","52"); list.forEach((e)->System.out.println(e)); }
运行结果
(4) 姓名 凯, 电话 52
@Test public void testQuery() throws IOException { //获得SqlSession SqlSession session = sqlSessionFactory.openSession(); StudentMapper mapper = session.getMapper(StudentMapper.class); List<Student> list = mapper.query("凯","52"); list.forEach((e)->System.out.println(e)); }
运行结果
总结: where 标签 若子句的开头为“AND"或"OR,where元素也会将它们去除。
? 建议:? 每个 where 子句 以and或or 开头?
?
<trim>标签的属性:
? prefix(前缀)
? suffix(后缀)
? suffixOverrides(前缀覆盖):表示整个语句块要去除掉的前缀
? prefixOverrides(后缀覆盖):表示整个语句块要去除掉的后缀
?
实现功能:
根据 姓名及电话号码进行查询,
(1)如果姓名及电话号码都为空 则查询全部
(2)如果姓名为空,电话号码不为空 则按照电话号码进行模糊查询
(3)如果姓名不为空,电话号码为空 则按照姓名进行模糊查询
(4)如果姓名及电话号码都不为空 则按照姓名及电话号码进行模糊查询
?
还是 实现之前的功能, 只需要 修改 StudentMapper.xml 即可
<select id="query" resultType="student"> select * from student <trim prefix="where" prefixOverrides="and"> <if test="param1 !=null and param1!=''"> and sname like concat('%',#{param1},'%') </if> <if test="param2 !=null and param2!=''"> and phone like concat('%',#{param2},'%') </if> </trim> </select>
?直接运行测试类
说明:? 当 trim 子句 不成立时, trim 什么也不做, 即 sql 为?select * from student
当 trim 子句成立时,?select * from student where 条件1=值 and 条件2=值
if+where? 可以用 if+trim 来代替, 无论哪种用法 都可以实现对应功能