三、Mybatis 第三节

一、动态sql

1.1 sql片段

在书写sql语句的查询时,不推荐大家用’ * ‘号 建议大家把想要查询出来的列都写出。具体的写法如下:

(1)写sql标签 (2)在sql语句中引入sql片段

1.2 set标签

这个配合if标签一起用,一般在用于修改语句。如果传递的参数值为null,那么应该不用修改该列的值

set可以帮助我们生成关键字 set 并且可以去除最后的一个逗号


测试代码如下:我们传的一个参数为一个student实体类,里面的属性有name,age,cid和一个Class(自定义的)类的Class,我们只需要关系 我们要用到的name,age,cid即可

我们需要修改的值为name,age,cid 这些都不为空 那么动态sql语句就应该变成:

 可以发现,set标签会自动帮我们去除最后cid处的逗号。

1.3 foreach标签

        循环标签,可以帮助我们处理一些动态的批量任务,例如批量添加,批量查询,批量删除等等。我们可以传入一个数组或者一个list集合,然后通过foreach标签将集合内的条件一个一个的放入我们的sql语句从而实现动态的批量删除的处理效果.

foreach标签内的属性:

1.collection:类型 如果你使用的为数组array 如果你使用的为集合 那么就用list

2.item:数组中每个元素赋值的变量名

3.open:以谁开始

4.close:以谁结束

5.separator:分割符

     用到的数据库的表如图。下面给大家举三个例子

        

        (1).根据id批量查询学生信息

        StudentDao:

        StudentMapper:

<resultMap id="stuMap" type="com.wjk.entity.Student">
        <id column="stu_id" property="id"/>
        <result column="stu_name" property="name"/>
        <result column="stu_age" property="age"/>
    </resultMap>

    <sql id="stu">
        stu_id,stu_name,stu_age,cid
    </sql>
<select id="selectByFor" resultType="com.wjk.entity.Student">
        select * from student where stu_id in
        <foreach collection="array" item="forEachIds" separator="," open="(" close=")">
            #{forEachIds}
        </foreach>
    </select>

(2)根据id批量删除

StudentDao:

StudentMapper:

<delete id="deleteByFor">
        delete from student where stu_id in
        <foreach collection="array" item="id" open="(" close=")" separator=",">
            #{id}
        </foreach>
    </delete>

(3) 批量添加学生信息

        这里我们传入的参数可以换成集合类型----List<Student>集合。集合里面装的都是Student对象类型的数据。这样才能将要添加的学生的信息传入sql中      

        StudentDao:

         StudentMapper:注意 我们想要调用list集合内的Student对象的属性,调用的写法应该为Xxx(item) xxx(属性名).同样紫定义对象类型的数组也应该这样调用属性

<insert id="insertByFor">
        insert into student values
        <foreach collection="list" item="stu" separator=",">
            (null ,#{stu.name},#{stu.age},#{stu.cid})
        </foreach>
    </insert>

二、映射文件特殊字符的处理

       在Mapper中写我们的SQL语句中,会遇到一些特殊字符,他会与哦我们的sql代码会产生冲突,例如我们sql中写这样的语句:

 

        可以看到我们的小于号,就是一种特殊字符。那么我们应该如何处理这种问题?

        有两种方法可以解决

第一种:使用转义符。java中有这些特殊字符的转义符

第二种:用<![CDATA[sql语句]]>方法 注意这种方法不能括住我们的标签 (例如include标签),我们可以在需要用到的地方使用这个方法,没必要在整个sql语句都套入在内

三、模糊查询

        模糊查询的sql语句

select * from 表明 where 列名 like '%a%'

有两种方法可以实现这种拼接

(1) 使用字符串函数 完成拼接----- concat(这属于sql基础的知识点)

 

<select id="selectByLike" resultMap="stuMap">
        select <include refid="stu"/>
        from student where stu_name like '%${name}$'
    </select>

(2)使用${}代替。这种方式实际上是字符串的拼接,它并不能防止sql注入问题 ,而我们之前用的#{}就相当于编译,可以防止sql注入问题。所有这种方式不推荐使用,所谓防君子不防小人

    <select id="selectByLike" resultMap="stuMap">
        select <include refid="stu"/> from student where stu_name like '%${name}%'
    </select>

四、联表查询

例子:根据id查询学生信息并包括改学生所在班里的所有信息

需要用的表:我们需要从多的一方来查询一的一方。这里学生表就相当于多的一方,班级表就相当于一的一方

sql语句:

select * from tb_stu s join tb_class c on s.class_id=c.cid where stu_id= xxx

 实现方式一:

        首先在我们的Student实体类中(相当于多的一方)加入我们Class类型(一的一方)的属性

/**
 * Created by Intellij IDEA
 *
 * @author 王俊凯
 * @Date: 2022/6/5 12:39
 * @Version 1.0
 */
package com.wjk.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {

    private Integer id;
    private String name;
    private Integer age;
    private Integer cid;

    private Class aClass;//学生所属的班级

StudentDao:

StudentMapper:重点:resultMap标签内的association标签:表示一的一方。property:表示属性名(就是我们实体类中的Class属性)javaType:表示该属性名对应的数据类型

<resultMap id="all" type="com.wjk.entity.Student">
        <id column="stu_id" property="id"/>
        <result column="stu_name" property="name"/>
        <result column="stu_age" property="age"/>
        <result column="c_id" property="cid"/>
        <association property="aClass" javaType="com.wjk.entity.Class">
            <id column="cid" property="cid"/>
            <result column="cname" property="cname"/>
        </association>
    </resultMap>
    <sql id="allClass">
        stu_id,stu_name,stu_age,s.cid c_id,c.cid,cname
    </sql>

    <select id="selectClassById" resultMap="all">
        select <include refid="allClass"/>
        from student s join class c on s.cid=c.cid where stu_id=#{id}
    </select>

 实现方式二:

        map封装(不推荐这种方式)。用这种方式封装我们查询到的数据,就不需要改动我们的实体类,也不用关心其属性内的映射关系。

        StudentDao:

        StudentMapper:

<select id="selectClassById09" resultType="java.util.Map">
        select <include refid="allClass"/>
        from student s join class c on s.cid=c.cid where stu_id=#{id}
    </select>

 

 需要避免的问题:两个表的列名应该尽量避免相同,如果相同,需要起别名来区别。resultMap中的标签内的column属性应该与你起了别名后的列名相同。Map本身也是无序不重复的,我们的属性名也就是map中的key值也需要保证不能相同。

       体会:使用mybatis我们需要做的事情就是处理好查询到的结果与返回值(一般是你得实体类或实体类组成的集合)的属性相对应(resultMap标签)。其他的内容与我们学习JDBC+Dao整合时大致相同。所以难点就在于将返回的内容处理好,其他的一些包括sql语句标签和动态sql标签都是帮助我们书写sql语句的,基础的sql部分的知识点需要掌握。框架的好处就是帮我们简化流程,不要把他想的很复杂。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值