在编译阶段,就可以确定的SQL语句称为静态SQL;在程序运行阶段,根据条件不同才能确定下来的SQL叫动态SQL。如:学生表数据查询时,查询条件有年龄、姓名、专业、班级等,SQL语句条件根据当前的使用场景可能是这些条件的任意组合。Mybaits提供了一种基于OGNL(对象导航图语言)的表达式来完成动态SQL,极大方便了动态sql编程。
掌握基于OGNL表达式实现动态SQL的使用
以查询学生信息为例,学习if、choose(when、otherwise)、where、trim、set、forEach、bind等元素的使用。
| 字段名称 | 字段代码 | 数据类型 | 备注 |
| 学号 | sno | integer | 主键自增 |
| 学生姓名 | student_name | varchar(50) | |
| 年龄 | student_age | integer |
@Data
public class Student {
private Integer sno;
private String studentName;
private Integer studentAge;
}
public interface StudentDao {
List<StudentEntity> getStudentByCondition(Map<String,Object> param);
List<StudentEntity> getStudentByCondition2(Map<String,Object> param);
int UpdateStudentById(StudentEntity student);
int insertStudent(StudentEntity student);
int insertBatch(@Param("students") List<StudentEntity> students);
List<StudentEntity> getStudentByBind(StudentEntity student);
}
<select id="getStudentByCondition" resultType="com.bjwl.pojo7.StudentEntity">
select * from tb_student where 1=1
<if test="name !=null and name !=''">
and student_name like concat('%',#{name},'%')
if>
<if test="age !=null and age !=''">
and student_age =#{age}
if>
select>
测试代码如下所示
public void testIf() throws IOException {
SqlSession sqlSession = BatisUtils.getSqlSessionFactory().openSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
Map<String,Object> map = new HashMap<>();
map.put("name","张");
map.put("age",null);
List<StudentEntity> students = dao.getStudentByCondition(map);
for (StudentEntity student:students){
System.out.println(student.toString());
}
}
运行结果如下

<select id="getStudentByCondition2" resultMap="com.bjwl.pojo7.StudentEntity">
select * from tb_student where 1=1
<choose>
<when test="name !=null and name !=''">
and student_name like concat('%',#{name},'%')
when>
<when test="age !=null and age !=''">
and student_age =#{age}
when>
<otherwise>
and student_name = '王小丫'
otherwise>
choose>
select>
测试代码如下:
public void testChoose() throws IOException {
SqlSession sqlSession = BatisUtils.getSqlSessionFactory().openSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
Map<String,Object> map = new HashMap<>();
/*map.put("name","王");
map.put("age",18);*/
/*屏蔽map中的name项试试 比较和两条if语句的区别*/
List<StudentEntity> students = dao.getStudentByCondition2(map);
for (StudentEntity student:students){
System.out.println(student.toString());
}
}
运行结果如下:

<select id="getStudentByCondition3" resultType="com.bjwl.pojo7.StudentEntity">
select * from tb_student
<where>
<if test="sname !=null and sname !=''">
and student_name like concat('%',#{sname},'%')
if>
<if test="age !=null and age !=''">
and student_age =#{age}
if>
where>
select>
<insert id="insertStudent">
insert into tb_student
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="studentName != null">
student_name,
if>
<if test="studentAge != null">
student_age
if>
trim>
<trim prefix="values(" suffix=")" suffixOverrides=",">
<if test="studentName != null">
#{studentName},
if>
<if test="studentAge != null">
#{studentAge}
if>
trim>
insert>
Trim元素的有prefix、prefixOverrides、suffix、suffixOverrides四个属性,prefix开头添加一个,prefixOverrides开头去掉一个,suffix结尾添加一个,suffixOverrides结尾去掉一个,如代码的第3、12行,增加前缀和后缀,去掉多余的逗号。
测试代码如下
public void testTrim2() throws IOException {
SqlSession sqlSession = BatisUtils.getSqlSessionFactory().openSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
StudentEntity student = new StudentEntity();
student.setStudentName(null);
student.setStudentAge(30);
dao.insertStudent(student);
sqlSession.commit();
/*去掉age的赋值,试试 查看sql语句,是不是没有了“,”*/
/* List students = dao.getStudentByCondition3("任我行",null);*/
List<StudentEntity> students = dao.getStudentByCondition3(null,30);
for (StudentEntity stu:students){
System.out.println(stu.toString());
}
}
运行结果

<update id="UpdateStudentById">
update tb_student
<set>
<if test="studentName!=null">
student_name=#{studentName},
if>
<if test="studentAge!=null">
student_age=#{studentAge},
if>
set>
where sno=#{sno}
update>
省略测试类和执行结果
<insert id="insertBatch">
insert into tb_student(student_name,student_age)
values
<foreach collection="students" item="student" index="index" separator=",">
(#{student.studentName},#{student.studentAge})
foreach>
insert>
测试代码如下:
public void testExecutorTypeBatch() throws IOException {
SqlSession sqlSession = BatisUtils.getSqlSessionFactory().openSession(ExecutorType.BATCH);
StudentDao dao = sqlSession.getMapper(StudentDao.class);
List<StudentEntity> students = new ArrayList<>();
for (int i = 0; i <5 ; i++) {
StudentEntity student=new StudentEntity();
student.setStudentName("王大锤");
student.setStudentAge(18);
students.add(student);
}
dao.insertBatch(students);
sqlSession.commit();
sqlSession.close();
}
运行界面如下图所示

<select id="getStudentByBind" resultType="com.bjwl.pojo7.StudentEntity" >
<bind name="name" value="'%'+studentName"/>
select * from tb_student where student_name like #{name}
select>
测试代码如下
public void testBind() throws IOException {
SqlSession sqlSession = BatisUtils.getSqlSessionFactory().openSession(ExecutorType.BATCH);
StudentDao dao = sqlSession.getMapper(StudentDao.class);
StudentEntity student = new StudentEntity();
student.setStudentName("小凡");
List<StudentEntity> stus = dao.getStudentByBind(student);
for (StudentEntity stu : stus) {
System.out.println(stu.toString());
}
sqlSession.close();
}
运行结果如下:
