Mybatis入门三(动态sql、if、choose、where、trim、set、foreach等)

动态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---
...
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值