MyBatis(多表查询,动态SQL的使用)

这篇具有很好参考价值的文章主要介绍了MyBatis(多表查询,动态SQL的使用)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

多表查询

 查询文章详情

查询一个用户底下的所有文章

动态SQL的使用

if 标签

trim 标签

 where 标签

set 标签

foreach 标签


多表查询

现在有俩张表,一张是文章表,一张是用户表.如下:

MyBatis(多表查询,动态SQL的使用)

MyBatis(多表查询,动态SQL的使用)

 查询文章详情

我们现在想查询得到一张表,表里面的内容和文章表大多一致,只是要在文章表的基础上添加用户表中的username字段,这就需要多表联查来实现

用户类(用户表的映射)

@Data
public class UserEntity {
    private int id;
    private String username;
    private String password;
    private String photo;
    private LocalDateTime createtime;
    private LocalDateTime updatetime;
    private int state;
}

文章类(文章表的映射)

@Data
public class ArticleInfo {
    private Integer id;
    private String title;
    private String content;
    private LocalDateTime createtime;
    private LocalDateTime updatetime;
    private Integer uid;
    private Integer rcount;
    private int state;
}

文章表拓展(文章表加上用户表中的username字段的表)

public class ArticleInfoVO extends ArticleInfo {
    private String username;

    //Lombok的toString方法默认是不打印父类的属性的,所以这里我们要重写toString方法
    @Override
    public String toString() {
        return "ArticleInfoVO{" +
                "username='" + username + '\'' +
                "} " + super.toString();
    }
}

这里因为Lombok的toString方法默认是不打印父类属性的,所以我们进行了重写(方便后续打印观察结果)

实现mapper接口

@Mapper
public interface ArticleMapper {
    //查询文章详情
    ArticleInfoVO getDetail(@Param("id") Integer id);
}

实现对应的xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.ArticleMapper">
    <select id="getDetail" resultType="com.example.demo.entity.vo.ArticleInfoVO">
        select a.*,u.username from articleinfo a
        left join userinfo u on u.id = a.uid
        where a.id=#{id}
    </select>
</mapper>

单元测试

@SpringBootTest
class ArticleMapperTest {

    @Autowired
    private ArticleMapper articleMapper;
    @Test
    void getDetail() {
        ArticleInfoVO articleInfoVO = articleMapper.getDetail(1);
        System.out.println(articleInfoVO);
    }
}

结果

MyBatis(多表查询,动态SQL的使用)

查询一个用户底下的所有文章

主表依然是文章表,对文章表先插入几条数据

MyBatis(多表查询,动态SQL的使用)

mapper接口

@Mapper
public interface ArticleMapper {
    List<ArticleInfoVO> getArticleByUid(@Param("uid")Integer uid);
}

 xml

  <select id="getArticleByUid" resultType="com.example.demo.entity.vo.ArticleInfoVO">
        select a.*,u.username from articleinfo a
        left join userinfo u on u.id = a.uid
        where a.uid = #{uid}
    </select>

单元测试

   @Test
    void getArticleByUid() {
        Integer uid = 1;
        List<ArticleInfoVO> list = articleMapper.getArticleByUid(uid);
        list.stream().forEach(System.out::println);
    }

结果

MyBatis(多表查询,动态SQL的使用)

动态SQL的使用

动态SQL:允许我们在xml中写一些逻辑判断,来实现sql语句的拼接 

例如,在我们填写表单的时候,一些字段是必须要填的,一些字段是非必须填的,我们要如何实现呢?
难点在于对于一些非必填的字段,我们如何写插入的sql语句,这些字段是写在sql语句中怎么实现,用户填写这个字段的时候要写,不填写这个字段的时候又不需要写.

if 标签

现在要上传用户信息,我们需要传递username,password,photo这个三个字段,这其中username和password是必填的,photo是可填可不填的,我应该如何实现呢?

mapper

int addUser2(UserEntity user);

xml

 <insert id="addUser2">
        insert into userinfo(username,password
        <if test="photo != null">
            ,photo
        </if>
        )values(#{username},#{password}
        <if test="photo != null">
            ,#{photo}
        </if>
        )
    </insert>

if标签必须要有test(判断条件),这里面除了要写到sql语句中的属性,我们可以直接拿到程序中的参数,而写入到sql语句中就需要使用#{},${}等方式获取参数.

单元测试

   @Transactional
    @Test
    void addUser2() {
        String username = "宝宝";
        String password = "123456";
        UserEntity user = new UserEntity();
        user.setUsername(username);
        user.setPassword(password);
        int result = userMapper.addUser2(user);
        System.out.println(result);
    }

结果

MyBatis(多表查询,动态SQL的使用)

可以看到我们传入username和password生成的sql语句就只有这俩个字段

 @Transactional
    @Test
    void addUser2() {
        String username = "宝宝";
        String password = "123456";
        UserEntity user = new UserEntity();
        user.setUsername(username);
        user.setPassword(password);
        user.setPhoto("cat.png");
        int result = userMapper.addUser2(user);
        System.out.println(result);
    }

MyBatis(多表查询,动态SQL的使用) 可以看到同样的代码,我们这次多传入了photo属性,此时生成的sql语句就有username,password,photo字段了

trim 标签

上面这个例子,如果username,password,photo都是非必填的(sql语句中的逗号不好处理),此时就需要<trim>标签了

<trim>标签的属性

prefix: 表示整个语句块,以prefix的值前缀

suffix: 表示整个语句块,以suffix的值后缀

prefixOverrides: 表示整个语句块要去除掉前缀

suffixOverrides: 表示整个语句块要去除掉后缀

现在username,password,photo字段都为非必填,我们要如何实现?

mapper

 int addUser3(UserEntity user);

xml 

<insert id="addUser3">
        insert into userinfo
        <trim prefix="(" suffix=")" suffixOverrides=",">
        <if test="username != null">
            username,
        </if>
        <if test="password != null">
            password,
        </if>
        <if test="photo != null">
            photo
        </if>
        </trim>
        values
        <trim prefix="(" suffix=")" suffixOverrides=",">
        <if test="username != null">
                #{username},
        </if>
        <if test="password != null">
                #{password},
        </if>
        <if test="photo != null">
            #{photo}
        </if>
        </trim>
    </insert>

单元测试

 @Transactional
    @Test
    void addUser3() {
        String username = "白杨";
        String password = "123456";
        UserEntity user = new UserEntity();
        user.setUsername(username);
        user.setPassword(password);
        int result = userMapper.addUser3(user);
        System.out.println(result);
    }

结果

MyBatis(多表查询,动态SQL的使用)

 where 标签

想象一下这种场景:当我们在搜索框输入文章标题的时候,搜索引擎会根据这个标题查询,但是这个标题不是必须填的,我们也可以不输入文章标题只是输入了文章标题,搜索引擎会根据标题查询,我们要如何实现这个功能呢?

例如现在在搜索框可以输入标题或者id,或者什么都不输入

mapper

List<ArticleInfoVO> getListByIdOrTitle(@Param("id")Integer id,@Param("title")String title);

xml

   <select id="getListByIdOrTitle" resultType="com.example.demo.entity.vo.ArticleInfoVO">
        select * from articleinfo
        <where>
            <if test="id!=null and id>0">
                id = #{id}
            </if>
            <if test="title!=null">
                and title like concat('%',#{title},'%')
            </if>
        </where>
    </select>

使用了where标签好处:1.如果我们什么都没传,where后面的判断语句都为Null,此时where标签会自动帮我们去掉where.2.当我们只传了一部分,where标签会自动帮我们去掉前缀and

单元测试

  @Test
    void getListByIdOrTitle() {
        List<ArticleInfoVO> list = articleMapper.getListByIdOrTitle(null,null);
        System.out.println(list.size());
    }

MyBatis(多表查询,动态SQL的使用)

此时我们什么都没传,生成的sql语句没有where

 @Test
    void getListByIdOrTitle() {
        List<ArticleInfoVO> list = articleMapper.getListByIdOrTitle(null,"C语言");
        System.out.println(list.size());
    }

 MyBatis(多表查询,动态SQL的使用)

此时我们传入了标题"C语言",这时生成的sql就有了where判断语句, 且自动帮我们去掉了and

set 标签

和where标签很像,当我set标签里面有信息,生成的sql语句就会生成set去修改内容(set会自动帮我们去掉最后一个","),如果set标签里面没有信息,生成的sql语句就没有set

foreach 标签

<foreach>标签允许我们传入一个集合

<foreach>标签属性

collection: 绑定方法参数中的集合,如List,Set,Map或数组对象

item:遍历时的每一个对象

open:语句块开头字符串

close:语句块结束字符串

separator:每次遍历之间间隔的字符串

利用foreach标签来进行批量删除

mapper

// 根据文章id集合批量删除文章
    int deleteByIdList(@Param("idList")List<Integer> idList);

xml

<delete id="deleteByIdList">
        delete from articleinfo
        where id in
        <foreach collection="idList" item="id" open="(" close=")" separator="," >
            #{id}
        </foreach>
    </delete>

单元测试

    @Transactional
    @Test
    void deleteByIdList() {
        List<Integer> idList = new ArrayList<>();
        idList.add(1);
        idList.add(2);
        idList.add(3);
        int result = articleMapper.deleteByIdList(idList);
        System.out.println(result);
    }

结果

MyBatis(多表查询,动态SQL的使用)文章来源地址https://www.toymoban.com/news/detail-495696.html

到了这里,关于MyBatis(多表查询,动态SQL的使用)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • SQL语句 - 多表查询使用详细介绍

    例如我们有一张员工表和部门表, 员工表有6条数据, 部门表表有4条数据 : 使用多表查询, 查询员工表和部门表两张表 : 此时查询到的结果会有24条数据, 为什么会这样呢 ? 笛卡尔积:有A, B两个集合, 取A, B集合所有组合情况(4*6=24); 我们多表查询, 更多的是消除这些无效的数据 例

    2024年01月16日
    浏览(39)
  • MyBatis动态SQL、模糊查询与结果映射

    目录 前言 一、MyBatis动态SQL 1.动态SQL是什么 2.动态SQL的作用 3.常用动态SQL元素 1. where + if 元素 2. set + if 元素 3. choose + when + otherwise 元素 4. 自定义 trim 元素  1. 自定义 trim 元素改写上面的 where + if 语句 2. 自定义 trim 元素改写上面的 set + if 语句 5. foreach 元素 6.SQL片段重用 二、

    2024年02月11日
    浏览(29)
  • Mybatis 动态SQL条件查询(注释和XML方式都有)

    需求 : 根据用户的输入情况进行条件查询 新建了一个 userInfo2Mapper 接口,然后写下如下代码,声明 selectByCondition 这个方法 我们先用XML的方式实现 在resources 中创建 Userinfo2XMLMapper.xml 文件  将 Userinfo2XMLMapper.xml 文件中的 namespace 进行修改,改为 userInfo2Mapper 接口中的第一行 package 的

    2024年01月22日
    浏览(31)
  • Springboot 封装整活 Mybatis 动态查询条件SQL自动组装拼接

    ps:最近在参与3100保卫战,战况很激烈,刚刚打完仗,来更新一下之前写了一半的博客。 该篇针对日常写查询的时候,那些动态条件sql 做个简单的封装,自动生成(抛砖引玉,搞个小玩具,不喜勿喷)。 来看看我们平时写那些查询,基本上都要写的一些动态sql:   一个字段

    2024年02月12日
    浏览(20)
  • MyBatis进阶:掌握MyBatis动态SQL与模糊查询、结果映射,让你在面试中脱颖而出!!

    目录 一、引言 二、MyBatis动态SQL 2.1.if元素使用 2.2.foreach元素使用 三、MyBatis模糊查询 ①使用#{字段名} ②使用${字段名} ③使用concat{\\\'%\\\',#{字段名},\\\'%\\\'} 总结 四、MyBatis结果映射 4.1.案例演示 4.1.1.resultType进行结果映射 4.1.2.resultMap进行结果映射 在当今的软件开发环境中,数据库的使

    2024年02月11日
    浏览(37)
  • Mybatis——多表查询

    目录 一、简介 二、业务环境的准备 2.1、准备工作: 2.2、SQL 三、一对一和一对多 Sql语句: POJO  OrderMapper OrderMapper.xml  Test测试类 运行结果 MyBatis 是一个优秀的持久层框架,它提供了强大的支持来执行数据库操作,包括多表查询。多表查询是指从多个数据库表中检索数据的过

    2024年02月02日
    浏览(39)
  • MyBatis多表查询

    目录 1. 多表关系回顾 2. 一对一查询 2.1 一对一多表查询方式一:基于标签进行手动结果映射封装  2.2 一对一多表查询方式二 - 通过标签来封装属性中所关联的对象 3. 一对多查询 4. 多对多查询 在项目开发当中一对一关系的表不常见,因为一对一关系的两张表通常会合并为一

    2024年02月10日
    浏览(24)
  • Springboot 自定义 Mybatis拦截器,实现 动态查询条件SQL自动组装拼接(玩具)

    ps:最近在参与3100保卫战,战况很激烈,刚刚打完仗,来更新一下之前写了一半的博客。 该篇针对日常写查询的时候,那些动态条件sql 做个简单的封装,自动生成(抛砖引玉,搞个小玩具,不喜勿喷)。 来看看我们平时写那些查询,基本上都要写的一些动态sql:   一个字段

    2024年02月12日
    浏览(39)
  • MySQL基础篇补充 | 多表查询中使用SQL99实现7种JOIN操作、SQL99语法新特性

    目录 一:多表查询中使用SQL99实现7种JOIN操作  二:SQL99语法新特性 1. 自然连接Natural 2. USING连接 在多表查询中,除了遇到最多的内连接、左外连接和右外连接,还有其它的连接方式;接下来就聊聊其它的连接方式,如下图:  ​​​​​​ 并且在正式讲解之前,需要先了解

    2024年02月03日
    浏览(33)
  • MyBatis多表查询和注解开发

    一对一查询的模型 用户表和订单表的关系为, 一个用户有多个订单,一个订单只从属于一个用户 一对一查询的需求:查询一个订单,与此同时查询出该订单所属的用户 一对一查询的语句 对应的sql语句: 查询的结果如下: 创建Order和User实体 创建OrderMapper接口 配置OrderMappe

    2024年02月04日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包