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

news2024/11/23 19:30:14

目录

多表查询

 查询文章详情

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

动态SQL的使用

if 标签

trim 标签

 where 标签

set 标签

foreach 标签


多表查询

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

 查询文章详情

我们现在想查询得到一张表,表里面的内容和文章表大多一致,只是要在文章表的基础上添加用户表中的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);
    }
}

结果

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

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

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);
    }

结果

动态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);
    }

结果

可以看到我们传入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);
    }

 可以看到同样的代码,我们这次多传入了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);
    }

结果

 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());
    }

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

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

 

此时我们传入了标题"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);
    }

结果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/606222.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

银行从业资格证(初级) 5天零基础拿证攻略【个人经历,亲测】

我的科目&#xff1a;《法律法规》、《个人理财》 方法 直接做真题&#xff0c;做真题错题总结归纳。 教材可买可不买&#xff0c;时间不够可以不看教材。 可以买天一金融的真题汇编&#xff0c;它附赠一个考点整理的小册子。 一定要自己整理知识框架。 看个人习惯选择网上做…

chatgpt赋能python:Python列表中随机抽取6个元素的简单方法

Python列表中随机抽取6个元素的简单方法 在Python编程中&#xff0c;列表是一种常用的数据类型&#xff0c;它允许我们存储和操作一系列数据。有时候&#xff0c;我们需要从列表中随机抽取一些元素&#xff0c;比如从一组名字中随机选择几个人参加抽奖等。本文将介绍如何使用P…

MIT 6.824 lab distributed system 分布式系统

https://youtu.be/cQP8WApzIQQ 概念 为什么需要分布式系统&#xff1f; high performanceparallelism&#xff1a;分布式系统可以实现CPU、内存、硬盘的并行运行fault tolerancephysical&#xff1a;security / isolated 分布式系统的困难 concurrency&#xff1a;各个并行的…

【unity小技巧】使用贝塞尔曲线实现导弹随机攻击敌人,也可以用于拾取物品

文章目录 先看效果代码实现1.导弹代码2.玩家生成导弹代码3.玩家挂载代码4.导弹挂载代码先看效果 代码实现 1.导弹代码 记得配置敌人为enemy标签 using System.Collections; using System.Collections.Generic; using

Nautilus Chain:独特且纯粹的创新型 Layer3

以 Layer3 架构为主要特点的模块化公链 Nautilus Chain 即将在近期上线主网&#xff0c;这也进一步引发了行业关于 Layer3 的讨论。 实际上&#xff0c;在2022年以太坊的创始人 Vitalik 提出了三大目标&#xff1a;Layer2 用于扩展&#xff0c;Layer3 用于定制功能&#xff0c;…

Transformer模型原理—论文精读

文章目录 前言模型架构Encoder和DecoderEncoderDecoder AttentionFFNEmbeddings和Positional EncodingEmbeddingsPositional Encoding 总结 前言 今天来看一下Transformer模型&#xff0c;由Google团队提出&#xff0c;论文名为《Attention Is All You Need》。论文地址。 正如…

Openwrt_XiaoMiR3G路由器_刷入OpenWrt

刷入Openwrt之前请保证小米R3G路由器已经刷入Breed控制台固件。 刷入Breed请参考&#xff1a; Openwrt_XiaoMiR3G路由器_刷入Breed固件 路由器具体配置参考 小米路由器3G参数 - 小米商城 既然要刷入OpwnWrt就需要线编译固件&#xff0c;使用lede的OpenWrt源码编译。 进入 …

K8S集群安装(二)

目录 1 安装说明.... 1 1.1 安装环境.... 1 1.2 生产环境可部署Kubernetes集群的两种方式.... 2 1.3 操作系统初始化配置.... 3 2 安装Docker/kubeadm/kubelet【所有节点】.... 4 2.1 安装Docker. 4 2.2 添加阿里云YUM软件源.... …

《Apollo 智能驾驶进阶课程》

来自 &#xff1a; https://www.bilibili.com/video/BV1G341117NQ/ https://apollo.baidu.com/ 主要学习资源如下&#xff1a; Apollo社区公众号&#xff0c;直接有整个视频教程的微信推文教程&#xff1a;链接一个CSDN博主记录的笔记&#xff1a; https://blog.csdn.net/qq_45…

08 redis经典五种数据类型及底层实现

redis是字典数据库KV键值对是什么 redis 是 key-value 存储系统&#xff0c;其中key类型一般为字符串&#xff0c;value 类型则为redis对象(redisObject)Redis定义了redisObjec结构体来表示string、hash、list、set、zset等数据类型 C语言struct结构体语法简介Redis 中每个对象…

【华为机试】死记硬背没思路?一般人我劝你还是算了吧

大家好&#xff0c;我是哪吒。 五月份之前&#xff0c;如果你参加华为OD机试&#xff0c;收到的应该是2022Q4或2023Q1&#xff0c;这两个都是A卷题。 5月10日之后&#xff0c;很多小伙伴收到的是B卷&#xff0c;那么恭喜你看到本文了&#xff0c;抓紧刷题吧。B卷新题库正在更…

Spring依赖注入解析

目录 依赖注入大致要点 依赖注入大致流程 Bean的预实例化 doGetBean createBean 完备Bean的创建过程 createBeanInstance populateBean 依赖注入大致要点 Spring在Bean实例的创建过程中做了很多精细化控制finishBeanFactoryInitialization方法里面的preInstantiateSing…

【计算机网络复习】第六章 局域网 LAN

局域网&#xff08; LAN&#xff09;概述 LAN的特点 • 覆盖范围小 房间、建筑物、园区范围 • 高传输速率 10Mb/s&#xff5e;1000Mb/s • 低误码率 10-8 &#xff5e; 10-11 • 拓扑&#xff1a;总线型、星形、环形 • 介质&#xff1a;UTP、Fiber、C…

6年测试经验之谈,为什么要做自动化测试?

一、自动化测试 自动化测试是把以人为驱动的测试行为转化为机器执行的一种过程。 个人认为&#xff0c;只要能服务于测试工作&#xff0c;能够帮助我们提升工作效率的&#xff0c;不管是所谓的自动化工具&#xff0c;还是简单的SQL 脚本、批处理脚本&#xff0c;还是自己编写…

智能优化算法:指数分布优化算法-附代码

智能优化算法&#xff1a;指数分布优化算法 文章目录 智能优化算法&#xff1a;指数分布优化算法1.指数分布优化算法1.1种群初始化1.2EDO开发1.3EDO探索 2.实验结果3.参考文献4.Matlab5.python 摘要&#xff1a;指数分布优化算法&#xff08;Exponential distribution optimize…

全新好用的窗口置顶工具WindowTop

打开WindowTop软件&#xff0c;所有已打开的窗口都会在左上角出现一个置顶栏&#xff0c;点击置顶栏的置顶复选框即可置顶窗口或取消窗口。   在WindowTop软件的置顶栏一项里可以自由调整置顶栏的元素&#xff08;包含增删位置&#xff09;。   可改变置顶栏的外观&#x…

剖析ffmpeg视频解码播放:时间戳的处理

一、视频播放基础理论 1.1 视频编码和解码基础 视频编码和解码是视频播放的基础&#xff0c;理解它们的工作原理对于深入理解视频播放至关重要。在这一部分&#xff0c;我们将详细介绍视频编码和解码的基础知识。 视频编码&#xff08;Video Encoding&#xff09;是将原始视…

离散数学_十章-图 ( 5 ):连通性 - 上

&#x1f4f7;10.5 图的连通性 1. 通路1.1 通路1.2 回路1.3 其他术语 2. 无向图的连通性2.1 无向图的连通与不连通2.2 定理2.3 连通分支 3. 图是如何连通的3.1 割点&#xff08; 关节点&#xff09;3.2 割边&#xff08; 桥&#xff09;3.3 不可分割图3.4 &#x1d458;(&#…

Linux内核模块开发 第 5 章

The Linux Kernel Module Programming Guide Peter Jay Salzman, Michael Burian, Ori Pomerantz, Bob Mottram, Jim Huang译 断水客&#xff08;WaterCutter&#xff09; 5 预备知识&#xff08;Preliminaries&#xff09; 5.1 模块的入口函数和出口函数 C 程序通常从 ma…