1.什么是动态SQL?
动态 SQL,通过 MyBatis 提供的各种标签对条件作出判断以实现动态拼接SQL 语句。这里的条件判断使用的表达式为 OGNL 表达式。常用的动态 SQL标签有<if>、<where>、<choose/>、<foreach>等。MyBatis 的动态 SQL 语句,与 JSTL 中的语句非常相似。
动态 SQL,主要用于解决查询条件不确定的情况:在程序运行期间,根据用户提交的查询条件进行查询。提交的查询条件不同,执行的 SQL 语句不同。若将每种可能的情况均逐一列出,对所有条件进行排列组合,将会出现大量的SQL 语句。此时,可使用动态 SQL 来解决这样的问题。
2.动态SQl-定义代码片段
动态SQL代码片段,是使用<sql>标签来定义SQL片段,以便其SQL标签重复使用。其他标签使用SQL片段,只需要使用<include/>子标签。该<sql/>标签可以定义 SQL 语句中的任何部分,所以<include/>子标签可以放在动态 SQL 的任何位置。 现说代码片段是为了后面的使用。下面来说说代码:
在StudentDao.xml文件里。
<!-- 定义代码片段--> <sql id="selectStudent"> select * from student </sql> <sql id="selectStudentList"> id,name,email,age </sql> <!--使用定义代码片段--> <select id="selectdai" resultType="com.liuhaiyang.domain.Student"> <include refid="selectStudent"></include> </select>
test测试类
@Test//能够单次执 public void testSelectdai() { SqlSession session = MybatisUtils.getSqlSession(); StudentDao dao = session.getMapper(StudentDao.class); List<Student> stu = dao.selectdai(); stu.forEach(s -> System.out.println("查询结果====>" + s)); //关闭sqlsession session.close(); }
结果截图:
3.动态SQl-if
对于该标签的执行,当 test 的值为 true 时,会将其包含的 SQL 片断拼接到其所在的 SQL 语句中。
语法:<if test=”条件”> sql 语句的部分 </if>代码:StudentDao接口:
//if List<Student> selectif(Student student);
studentDao.xml文件
<!-- if 一般和where配套使用 test :使用对象的属性值作为条件 --> <select id="selectif" resultType="com.liuhaiyang.domain.Student"> select * from student where name=#{name} <if test="name!=null and name!=''"> and name=#{name} <!-- 在着添加or和上面写id>0的原因 防止本条件不符合,执行下面代码导致多一个or--> </if> <if test="age>0"> or age=#{age} <!-- 当使用两个以上的if时,需要添加or或者and--> </if> </select>
test测试类:
@Test//能够单次执 public void testSelectif() { SqlSession session = MybatisUtils.getSqlSession(); StudentDao dao = session.getMapper(StudentDao.class); Student student = new Student(); student.setAge(22); student.setName("张三"); // student.setEmail("liuhaiyang@qq.com"); List<Student> stu = dao.selectif(student); stu.forEach(s -> System.out.println("查询结果====>" + s)); //关闭sqlsession session.close(); }
结果截图:
4.动态SQl-where
<if/>标签的中存在一个比较麻烦的地方:需要在 where 后手工添加 1=1的子句。因为,若 where 后的所有<if/>条件均为 false,而 where 后若又没有 1=1 子句,则 SQL 中就会只剩下一个空的 where,SQL 出错。所以,在where 后,需要添加永为真子句 1=1,以防止这种情况的发生。但当数据量很大时,会严重影响查询效率。
使用<where/>标签,在有查询条件时,可以自动添加上 where 子句;没有查询条件时,不会添加 where 子句。需要注意的是,第一个<if/>标签中的SQL 片断,可以不包含 and。不过,写上 and 也不错,系统会将多出的 and去掉。但其它<if/>中 SQL 片断的 and,必须要求写上。否则 SQL 语句将拼接出错。
语法:<where> 其他动态 sql </where>。下面是代码StudentDao接口类:
//where List<Student> selectwhere(Student student);
StudentDao.xml文件
<!-- where 一般和if配套使用 < 表示< --> <select id="selectwhere" resultType="com.liuhaiyang.domain.Student"> <include refid="selectStudent" /> <where> <if test="name!=null and name!=''"> or name=#{name} <!-- 在着添加or和上面写id>0的原因 防止本条件不符合,执行下面代码导致多一个or--> </if> <if test="age>0"> or age=#{age} <!-- 当使用两个以上的if时,需要添加or或者and--> </if> </where> </select>
测试类
@Test public void testSelectwhere(){ SqlSession session=MybatisUtils.getSqlSession(); StudentDao dao=session.getMapper(StudentDao.class); Student stu=new Student(); stu.setAge(20); stu.setName("刘海洋"); // stu.setName(null); List<Student> student=dao.selectwhere(stu); student.forEach(s-> System.out.println(s)); session.close(); }
结果截图: