动态SQL: SQL的内容是变化的,可以根据条件获取到不同的SQL语句。
主要是Where部门发生变化。
动态sql的实现,使用的是mybatis提供的标签,
动态sql之if
<if test=“使用参数java对象的属性值作为判断的条件 ,语法 属性 = xxx值”
当test的值为true的时候,会将sql片段拼接到起坐在的SQL语句中。
Mapper文件:
<select id="selectStudentByName" resultType="com.bipt.domain.Student">
select * from student
where
<if test="name != null and name !=''">
name = #{name}
</if>
<if test="age>0">
and age > #{age}
</if>
动态SQL之where
标签存在一个比较麻烦的地方:需要在where中手工添加1=1子句,因为,若where后的所有天剑均为false,而where后又没有1=1子句,则sql中就会只剩下一个空的where,sql出错,所以会在where后加上真子句1=1,以防止这种情况的发生。但当数据量很大时,会严重影响查询效率
使用标签,在有查询条件时,可以自动添加上where子句;没有查询条件是,不会添加where子句。需要注意的是,第一个标签中的sql片段,可以不包含and,不过写上and也不错,系统会将多余的and去掉,但其他的中SQL片段的and必须写上,否则sql拼接会出错。
总结: 用来包含多个if,当一个if生效,则自动添加where关键字,去掉多余的and,or
Mapper:
<select id="selectStudentWhere" resultType="com.bipt.domain.Student">
select * from student
<where>
<if test="name != null and name !=''">
name = #{name}
</if>
<if test="age>0">
or age > #{age}
</if>
</where>
动态SQL之forecah
标签用于实现对于数组与集合的遍历。对其使用,需注意:
- collection表示要遍历的集合类型
- open、close、separator为对遍历内容进行sql拼接
主要用在sql 的in语句中的。
例如 : 查询学生是1001,1002,1003.
sql语句: select * from student where in (1001,1002,1003)
使用java中的循环完成SQL语句的拼接
ArrayList<Integer> list = new ArrayList<>();
list.add(1001);
list.add(1002);
list.add(1003);
//String sql1 = "select * from student where id in (1001,1002,1003)";
String sql = "select * from student where id in";
StringBuilder Builder = new StringBuilder();
int init = 0;
int len = list.size();
Builder.append("(");
for (Integer i : list) {
Builder.append(i).append(",");
}
Builder.deleteCharAt(Builder.length()-1);
Builder.append(")");
sql = sql + Builder.toString();
System.out.println(sql);
foereach传入普通数组
dao接口:
List<Student> selectForeachOne(List<Integer> idlist);
Mapper文件:
<select id="selectForeachOne" resultType="com.bipt.domain.Student">
select *
from student where id in
<foreach collection="list" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</select>
collection: 表示接口中的方法的参数的类型,如果是数组使用array,如果是list集合使用list
item:自定义的,表示数组和集合的成员变量。
open:循环开始的字符
close: 循环结束时的字符
separate : 集合成员之间的分隔符
测试代码:
SqlSession sqlSession = MyBatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
ArrayList<Integer> list = new ArrayList<>();
list.add(1001);
list.add(1002);
list.add(1003);
List<Student> students = dao.selectForeachOne(list);
for (Student student : students) {
System.out.println(student);
}
sqlSession.close();
foreach传入对象数组
dao接口:
List<Student> selectForeachTwo(List<Student> stulist);
Mapper文件:
<select id="selectForeachTwo" resultType="com.bipt.domain.Student">
select *
from student where id in
<foreach collection="list" item="stu" open="(" close=")" separator=",">
#{stu.id}
</foreach>
</select>
测试代码:
SqlSession sqlSession = MyBatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
ArrayList<Student> list = new ArrayList<>();
Student student1 = new Student();
student1.setId(1001);
list.add(student1);
Student student2 = new Student();
student2.setId(1003);
list.add(student2);
List<Student> students = dao.selectForeachTwo(list);
for (Student student : students) {
System.out.println(student);
}
sqlSession.close();
动态SQL之代码片段
标签用于定义SQL片段,一遍其他SQL标签复用。而其他标签使用该SQL片段,需要使用子标签。该标签可以定义sql语句汇总的任何部分,所以子变迁可以放在动态sql 的任何位置。
步骤:
- 先定义 sql语句,表明,字段等
- 再使用,
dao接口:
List<Student> selectForeachTwo(List<Student> stulist);
Mapper文件:
<sql id="selectallstu">select * from student</sql>
<select id="selectForeachTwo" resultType="com.bipt.domain.Student">
<include refid="selectallstu"/> where id in
<foreach collection="list" item="stu" open="(" close=")" separator=",">
#{stu.id}
</foreach>
</select>
测试代码:
SqlSession sqlSession = MyBatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
ArrayList<Student> list = new ArrayList<>();
Student student1 = new Student();
student1.setId(1001);
list.add(student1);
Student student2 = new Student();
student2.setId(1003);
list.add(student2);
List<Student> students = dao.selectForeachTwo(list);
for (Student student : students) {
System.out.println(student);
}
sqlSession.close();