[Mybatis]复杂环境下的SQL

🌈有幸相识 ,我是小相。有一个大厂梦,努力奔赴!加油陌生人!🌈
☁️该文章是跟随B站狂神学习Mybatis时的笔记与心得,若与您有用,感谢点赞。文章不免有不足之处,请指出,我会及时改正!

该部分代码位于:mybatis-05-DynamicSQL · xcy.小相/web-Mybatis - 码云 - 开源中国 (gitee.com)

1. 环境搭建

2. 多对一查询

2.1 按照查询嵌套处理

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="top.xcyxiaoxiang.dao.StudentMapper">

    <resultMap id="StudentTeacher" type="Student">
        <result column="id" property="id"/>
        <result column="name" property="name"/>
        <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
    </resultMap>

    <select id="getStudentList" resultMap="StudentTeacher">
        select * from student;
    </select>

    <select id="getTeacher" resultType="Teacher">
        select * from teacher where id=#{id}
    </select>

</mapper>

2.2按照结果嵌套查询(重要)

<select id="getStudentList2" resultMap="StudentTeacher2" >
    select s.id sid,s.name sname,t.name tname
     from student s,teacher t
     where t.id=s.tid;
</select>
<resultMap id="StudentTeacher2" type="Student">
    <result column="sid" property="id"/>
    <result column="sname" property="name"/>
    <association property="teacher" javaType="Teacher">
        <result property="name" column="tname"/>
    </association>
</resultMap>

3. 一对多查询

    // 一对多获取一个老师对应所有学生
    List<Teacher> getStudent(int id);
    <select id="getStudent" resultMap="studentTeacher">
        select t.id tid, t.name tname,s.id sid, s.name sname
        from student s,teacher t
        where t.id=s.tid and t.id=#{id}
    </select>
    <resultMap id="studentTeacher" type="Teacher">
        <result property="id" column="tid"/>
        <result property="name" column="tname"/>
        <collection property="student" ofType="Student">
            <result property="id" column="sid"/>
            <result property="name" column="sname"/>
            <result property="tid" column="tid"/>
        </collection>
    </resultMap>

javaType 用于指定实体类中的属性的类型

ofType用来指定映射到list或集合中的pojo类型,泛型中的约束类型。

4. 动态SQL

4.1 定义

  • 动态 SQL 是 MyBatis 的强大特性之一。
  • 动态SQL就是根据不同的条件产生或执行不同的SQL语句。
  • 动态SQL元素与JSTL类似,包含以下几种元素:
    • if
    • choose(when,otherwise)
    • trim(where ,set)
    • foreach

4.2 环境搭建

  • 数据库表
CREATE TABLE `blog`(
`id` VARCHAR(50) NOT NULL COMMENT '博客id',
`title` VARCHAR(100) NOT NULL COMMENT '博客标题',
`author` VARCHAR(30) NOT NULL COMMENT '博客作者',
`create_time` DATETIME NOT NULL COMMENT '创建时间',
`views` INT(30) NOT NULL COMMENT '浏览量'
)ENGINE=INNODB DEFAULT CHARSET=utf8
  • id工具类
package top.xcyxiaoxiang.units;

import org.junit.Test;
import java.util.UUID;
public class IDUnits {
    public static String getUUID(){
        return  UUID.randomUUID().toString().replace("-","");
    }
}
  • 开启驼峰命名自动映射,即从经典数据库列名 A_COLUMN 映射到经典 Java 属性名 aColumn
<settings>
    <setting name="mapUnderscoreToCamelCase" value="true "/>
</settings>
  • 插入数据
    <insert id="addBlog" parameterType="Blog">
        insert into blog values(#{id},#{title},#{author},#{createTime},#{views})
    </insert>
</mapper>
@Test
public void addBlog(){
    SqlSession sqlSession = MybatisUnits.getSqlSession();
    BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);

    Blog blog = new Blog();
    blog.setId(IDUnits.getUUID());
    blog.setTitle("Mybatis");
    blog.setAuthor("狂神说");
    blog.setCreateTime(new Date());
    blog.setViews(9999);

    mapper.addBlog(blog);

    blog.setId(IDUnits.getUUID());
    blog.setTitle("Java");
    mapper.addBlog(blog);

    blog.setId(IDUnits.getUUID());
    blog.setTitle("Spring");
    mapper.addBlog(blog);

    blog.setId(IDUnits.getUUID());
    blog.setTitle("微服务");
    mapper.addBlog(blog);

    sqlSession.commit();
    sqlSession.close();
}

4.3 if元素

通过if语句来判断参数的值,从而选择性的添加语句。例如:当title为空,author不为空时,语句为select* from blog where 1=1 and author=#{autor}

<select id="getBlogIf" parameterType="map" resultType="Blog">
    select * from blog where 1=1
    <if test="title!=null">
        and title=#{title}
    </if>
    <if test="author!=null">
        and author=#{author}
    </if>
</select>

4.4 choose元素

类似java中的switch语句,给定有限个数的条件来进行判断(when),并指定默认情况(otherwise)。

  • choose
    • when
    • otherwise
<select id="getBlogChoose" parameterType="map" resultType="Blog">
    select * from blog
    <choose>
        <when test="title!=null">
            where title=#{title}
        </when>
        <when test="author!=null">
            where author=#{author}
        </when>
        <when test="title!=null and author!=null">
            where title=#{title} and author=#{author}
        </when>

        <otherwise>
            where 1=1
        </otherwise>
    </choose>
</select>

4.5 where元素

可以观察到,在if元素中我们在where后添加了1=1,这样做的原因是为了防止当所有条件都不满足时产生错误语句(select * from blog where)或(select * from blog where and author=#{author})。

mybatis给我们提供了更为简便智能的方式:where元素。where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若第一个子句的开头为 “AND” 或 “OR”,where 元素也会自动将它们去除,例如:当title!=null and author=null时sql语句为``。

<select id="getBlogWhere" parameterType="map" resultType="Blog">
    select * from blog
    <where>
        <if test="title!=null">
            and title=#{title}
        </if>
        <if test="author!=null">
            and author=#{author}
        </if>
    </where>
</select>

因此,4.4中的语句可以改为:

<select id="getBlogChoose" parameterType="map" resultType="Blog">
    select * from blog
    <where>
        <choose>
            <when test="title!=null">
                title=#{title}
            </when>
            <when test="author!=null">
                author=#{author}
            </when>
            <when test="title!=null and author!=null">
                title=#{title} and author=#{author}
            </when>
        </choose>    
    </where>
</select>

4.6 set元素

类似于where元素,对于更新时,set 元素可以用于动态包含需要更新的列,忽略其它不更新的列。set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号。

<select id="updateBlogSet" resultType="Blog" parameterType="map">
    update blog
    <set>
        <if test="author!=null">
            author=#{author},
        </if>
        <if test="views!=null">
            views=#{views},
        </if>
    </set>
    where id=#{id}
</select>

4.7 trim元素

where 元素等价的自定义 trim 元素为:

<trim prefix="WHERE" prefixOverrides="AND |OR "></trim>

set 元素等价的自定义 trim 元素:

<trim prefix="SET" suffixOverrides=","></trim>

4.8 SQL片段

即将一些重复性sql语句通过SQL元素进行包装,并通过id进行唯一标识。通过<include>元素在多处进行调用,实现代码的复用。

如下方代码,

<select id="getBlogIf" parameterType="map" resultType="Blog">
    select * from blog where 1=1
    <if test="title!=null">
        and title=#{title}
    </if>
    <if test="author!=null">
        and author=#{author}
    </if>
</select>

<select id="getBlogWhere" parameterType="map" resultType="Blog">
    select * from blog
    <where>
        <if test="title!=null">
            and title=#{title}
        </if>
        <if test="author!=null">
            and author=#{author}
        </if>
    </where>
</select>

可以替换为:

<select id="getBlogIf" parameterType="map" resultType="Blog">
    select * from blog where 1=1
    <include refid="if"/>
</select>
<select id="getBlogWhere" parameterType="map" resultType="Blog">
    select * from blog
    <where>
        <include refid="if"/>
    </where>
</select>

    <sql id="if">
        <if test="title!=null">
            and title=#{title}
        </if>
        <if test="author!=null">
            and author=#{author}
        </if>
    </sql>

4.9 foreach

动态 SQL 的另一个常见使用场景是对集合进行遍历(尤其是在构建 IN 条件语句的时候)。通过map传入ids参数,遍历ids或多个元素。比如:

<select id="getBlogForeach" parameterType="map" resultType="Blog">
    select * from blog
    <where>
        id in
        <foreach collection="ids" item="id" open="(" separator="," close=")">
            #{id}
        </foreach>
    </where>
</select>

的执行语句之一为:select * from blog where id in (1,2,3)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值