动态sql作用:动态sql就相当于是在拼接SQL语句。
动态sql常用的标签:
if
choose(when otherwise)
trim where set
foreach
实体类属性:
private int stuId;
private String name;
private String email;
private String phone;
private int teaId;
配置文件中添加类型别名:
<typeAliases>
<typeAlias type="org.pojo.Student" alias="Stu"/><!--这个是本次要使用的-->
<package name="edu.pojo"/>
</typeAliases>
1.IF:通过IF来判断是否需要拼接剩余的sql语句
<select id="selectStu" resultType="Stu" parameterType="Stu">
select * from student where tea_id=#{teaId}
<if test="name!=null"><!--判断条件,如果设置了name属性,就是执行-->
and name=#{name}
</if>
</select>
执行这条sql语句时,传入的参数是对象类型,通过这个对象中的tea_id参数和name参数来查询符合条件的一行或多行。不能通过在接口中方法的重载来实现动态sql。
接口中:
public List<Student> selectStu(Student student);
main方法中部分代码:
Student student=new Student();
student.setTeaId(2);//根据老师的id来查询学生
List<Student> list=studentMapper.selectStu(student);
for(Student stu:list)
{
System.out.println(stu);
}
因为没有设置student中的name属性,String类型的默认中是null,因此在xml文件中的if条件不成立。所有在执行是不会添加后半段sql。
运行结果:
Student{stuId=4, name='lisi', email='yz_ahha@qq.com', phone='1522921920x', teaId=2}
Student{stuId=5, name='swj', email='swj@163.com', phone='132016562xx', teaId=2}
Student{stuId=6, name='mmq', email='123@qq.com', phone='136987456', teaId=2}
Student{stuId=7, name='lfl', email='456@163.com', phone='178888880', teaId=2}
在参数student中设置name属性:
Student student=new Student();
student.setTeaId(2);//设置teaId
student.setName("swj");//设置name
List<Student> list=studentMapper.selectStu(student);//根据teaId和name属性来查询
for(Student stu:list)
{
System.out.println(stu);
}
运行结果:
Student{stuId=5, name='swj', email='swj@163.com', phone='132016562xx', teaId=2}
2.CHOOSE:类似于java中的switch-case语句。首先看数据库的查询结果
mysql> select * from student where tea_id=2;
+--------+--------+----------------+-------------+--------+
| stu_id | name | email | phone | tea_id |
+--------+--------+----------------+-------------+--------+
| 4 | lisi | yz_ahha@qq.com | 1522921920x | 2 |
| 5 | swj | swj@163.com | 132016562xx | 2 |
| 6 | mmq | 123@qq.com | 136987456 | 2 |
| 7 | lfl | 456@163.com | 178888880 | 2 |
| 9 | 静静 | haha@126.com | 1522921920x | 2 |
+--------+--------+----------------+-------------+--------+
5 rows in set (0.00 sec)
xml中的sql语句:
<select id="selectStuChoose" resultType="Stu">
select * from student where tea_id=2
<choose><!--类似于switch-->
<when test="name!=null"><!--类似于case-->
and name=#{name}
</when>
<when test="phone!=null">
and phone=#{phone}
</when>
<when test="email!=null">
and email=#{email}
</when>
<otherwise>
limit 0,2
</otherwise>
</choose>
</select>
如果设置了多个属性,则相应的sql也会被拼接上。类似于没有break的switch-case。
Student student=new Student();
student.setPhone("1522921920x");
//student.setName("静静");
List<Student> list=studentMapper.selectStuChoose(student);
for(Student stu:list)
{
System.out.println(stu);
}
只设置一个电话属性时查出两条数据:
Student{stuId=4, name='lisi', email='yz_ahha@qq.com', phone='1522921920x', teaId=2}
Student{stuId=9, name='静静', email='haha@126.com', phone='1522921920x', teaId=2}
如果取消设置姓名的注释,则在choose中会执行两条。查询结果如下:
Student{stuId=9, name='静静', email='haha@126.com', phone='1522921920x', teaId=2}
如果两条设置属性的语句都被注释,则会执行otherwise中的sql。在tea_id等于2的查询结果集中显示前两条数据。
Student{stuId=4, name='lisi', email='yz_ahha@qq.com', phone='1522921920x', teaId=2}
Student{stuId=5, name='swj', email='swj@163.com', phone='132016562xx', teaId=2}
3.WHERE:
<select id="selectStuWhere" resultType="Stu">
select * from student
<where>
<if test="teaId!=0">
tea_id=#{teaId}
</if>
<if test="name!=null">
and name=#{name}
</if>
<if test="stuId!=0"><!--int类型默认值为0-->
and stu_id=#{stuId}
</if>
</where>
</select>
如果三个条件中有一个条件成立,就会在sql语句中插入where子句;如果第一个条件没有成立,后面的条件有成立的,where标签会自动去除and
可以通过trim标签来定制和where元素一样的功能:
<select id="selectStuWhere" resultType="Stu">
select * from student
<trim prefix="where" prefixOverrides="and">
<if test="teaId!=0">
tea_id=#{teaId}
</if>
<if test="name!=null">
and name=#{name}
</if>
<if test="stuId!=0"><!--int类型默认值为0-->
and stu_id=#{stuId}
</if>
</trim>
</select>
当有一个条件成立时,插入前缀where;如果第一个不成立,后面有成立的,会去除and
SET:
在数据库中插入一条数据,接下来修改此条记录
mysql> insert into student values(10,'dabaicai','baicai@qq.com','110',2);
现在要修改这条记录:
<update id="updateStu" parameterType="Stu">
update student
<set>
<if test="name!=null">name=#{name},</if>
<if test="email!=null">email=#{email},</if>
<if test="phone!=null">phone=#{phone},</if>
<if test="teaId!=0">tea_id=#{teaId}</if>
</set>
where stu_id=#{stuId}
</update>
当有一个if成立时,会插入set子句,如果最后一个if不成立时,会自动去除后面的,
。
main方法:
Student student=new Student();
student.setStuId(10);//要修改id为10的信息
student.setName("xiaobai");//只修该名字
student.setPhone("120");
studentMapper.updateStu(student);
sqlSession.commit();
注意:增加、删除、修改时要加commit。否则不会执行。
同理,也可以通过trim来定制和set元素一样的功能。
<update id="updateStu" parameterType="Stu">
update student
<trim prefix="set" suffixOverrides=",">
<if test="name!=null">name=#{name},</if>
<if test="email!=null">email=#{email},</if>
<if test="phone!=null">phone=#{phone},</if>
<if test="teaId!=0">tea_id=#{teaId},</if>
</trim>
where stu_id=#{stuId}
</update>
如果if中有一个成立,则会自动加上set子句。回去除最后一个,
。
4.FOREACH:传入的参数是一个list,在sql中遍历这个list,拼接成sql。 如以下的查询语句:
<select id="selectStuByIdUseForeach" resultType="Stu">
select * from student where stu_id in
<foreach collection="list" open="(" separator="," close=")"
item="item" index="index">
#{item}
</foreach>
</select>
对应的接口:
public List<Student> selectStuByIdUseForeach(List list);
main方法:
List list=new ArrayList(5);
list.add(1);
list.add(4);
list.add(7);
List<Student> listStu=studentMapper.selectStuByIdUseForeach(list);//查询id为1、4、7的信息
for(Student stu:listStu)
{
System.out.println(stu);
}
运行结果:
Student{stuId=1, name='张三', email='asdu@163.com', phone='1354641', teaId=3}
Student{stuId=4, name='lisi', email='yz_ahha@qq.com', phone='1522921920x', teaId=2}
Student{stuId=7, name='lfl', email='456@163.com', phone='178888880', teaId=2}
插入多条数据时,也可以用foreach。foreach可以遍历所有可以叠底的对象。可以迭代的对象有集合和数组。foreach和for的区别。
插入多条数据:
<insert id="insertStuUseForeach">
insert into student(name,email,phone,tea_id) values
<foreach collection="array" item="stu" separator=",">
(#{stu.name},#{stu.email},#{stu.phone},#{stu.teaId})
</foreach>
</insert>
接口中:
public void insertStuUseForeach(Student[] stus);
main方法中:
Student[] stus=new Student[3];
stus[0]=new Student("XiaoYang","xiao@126.com","1837619xxx4",3);
stus[1]=new Student("DaTou","Da@qq.com","183xx19xxx4",2);
stus[2]=new Student("XiaoWang","XiaoWa@126.com","185xx619xxx4",1);
studentMapper.insertStuUseForeach(stus);
sqlSession.commit();//提交事务一定要加,不然不会执行
注意:collection属性的值为传入的数据结构的类型,而不是参数名。第一次运行时给其赋值为stus
。报了参数未找到的错误。collection可以赋的值有list、set、array、map等。
| 上一篇 |
---The End---
| ... |
本文深入解析MyBatis框架中的动态SQL技术,包括if、choose、trim、foreach等标签的使用方法,以及如何通过这些标签实现灵活的SQL语句拼接,提高数据库操作效率。
2287

被折叠的 条评论
为什么被折叠?



