sql查询之拼接外表或该表不存在的数据,简化多表联查的操作
  OZvmQgWagkrp 2023年11月12日 28 0

(内容)

1.引言

最近写项目时,用到了多表联查的知识点,我需要传article类和web_user类的username的参数

  • 这是我的三个表
-- MySQL dump 10.13  Distrib 8.0.26, for Win64 (x86_64)
--
-- Host: 127.0.0.1    Database: web
-- ------------------------------------------------------
-- Server version	8.0.26

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!50503 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

--
-- Table structure for table `user_article`
--

DROP TABLE IF EXISTS `user_article`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `user_article` (
  `id` bigint NOT NULL COMMENT 'id',
  `article_id` bigint NOT NULL COMMENT '文章id',
  `author_id` bigint NOT NULL COMMENT '作者id',
  `type` bigint DEFAULT NULL COMMENT '文章标签',
  `group_id` bigint DEFAULT NULL COMMENT '文章分组',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `user_article`
--

LOCK TABLES `user_article` WRITE;
/*!40000 ALTER TABLE `user_article` DISABLE KEYS */;
/*!40000 ALTER TABLE `user_article` ENABLE KEYS */;
UNLOCK TABLES;

--
-- Table structure for table `web_article`
--

DROP TABLE IF EXISTS `web_article`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `web_article` (
  `id` bigint NOT NULL COMMENT '博客id',
  `title` varchar(50) NOT NULL COMMENT '标题',
  `info` text COMMENT '文章简介',
  `content` longtext NOT NULL COMMENT '正文',
  `total_words` int DEFAULT NULL COMMENT '文章总字数',
  `create_date` datetime NOT NULL COMMENT '创建时间',
  `view` int DEFAULT NULL COMMENT '文章浏览量',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COMMENT='博客';
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `web_article`
--

LOCK TABLES `web_article` WRITE;
/*!40000 ALTER TABLE `web_article` DISABLE KEYS */;
INSERT INTO `web_article` VALUES (1653740781612978177,'啥大打算',NULL,'# 支持markdown文档',NULL,'2023-05-03 20:38:22',NULL),(1653766667221577729,'史蒂芬霍金刚好看到就是',NULL,'# 支持markdown文档asdasd',NULL,'2023-05-03 22:21:14',NULL),(1653766693687635969,'啊是哒是哒是哒',NULL,'# 支持markdown文档',NULL,'2023-05-03 22:21:20',NULL),(1653766713212121090,'大叔大叔大叔大叔',NULL,'# 支持markdown文档',NULL,'2023-05-03 22:21:25',NULL),(1653766731813859329,'啊是哒是哒',NULL,'# 支持markdown文档',NULL,'2023-05-03 22:21:29',NULL),(1653766752982511618,'爱是大叔大叔大叔',NULL,'# 支持markdown文档',NULL,'2023-05-03 22:21:34',NULL),(1653766772939010050,'爱是大叔大叔大叔',NULL,'# 支持markdown文档',NULL,'2023-05-03 22:21:39',NULL),(1653766809265876994,'好的公司规定韩国人特意',NULL,'# 支持markdown文档',NULL,'2023-05-03 22:21:48',NULL),(1654070565345886210,'深路着定',NULL,'in veniam',NULL,'2023-05-04 18:28:48',NULL),(1654070788596105217,'深路着定',NULL,'in veniam',NULL,'2023-05-04 18:29:42',NULL),(1654070960851951617,'深路着定',NULL,'in veniam',NULL,'2023-05-04 18:30:23',NULL),(1654074839522013185,'深路着定',NULL,'in veniam',NULL,'2023-05-04 18:45:47',NULL);
/*!40000 ALTER TABLE `web_article` ENABLE KEYS */;
UNLOCK TABLES;

--
-- Table structure for table `web_user`
--

DROP TABLE IF EXISTS `web_user`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `web_user` (
  `id` bigint NOT NULL COMMENT 'id',
  `username` varchar(50) NOT NULL COMMENT '账号',
  `password` varchar(50) DEFAULT NULL COMMENT '密码',
  `is_admin` tinyint DEFAULT NULL COMMENT '是否为超级管理员',
  `email` varchar(50) DEFAULT NULL COMMENT '邮箱',
  `tel` bigint DEFAULT NULL COMMENT '电话',
  `real_name` varchar(50) DEFAULT NULL COMMENT '真实姓名',
  `remarks` text COMMENT '备注'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COMMENT='用户';
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `web_user`
--

LOCK TABLES `web_user` WRITE;
/*!40000 ALTER TABLE `web_user` DISABLE KEYS */;
INSERT INTO `web_user` VALUES (1,'admin','admin',1,NULL,NULL,NULL,NULL);
/*!40000 ALTER TABLE `web_user` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

-- Dump completed on 2023-05-04 18:53:28



  • 结果示例,用了三表联查

sql语句简单示例

select *, (select username from web_user where id = 1) author
from web_article
where title like concat('%', '大叔', '%');

在mapper映射的xml文件里如果不用我一会在正文中提到的方法,本来要写这么多

<resultMap id="ArticleResultMap" type="article">
        <result property="author" column="username"></result>
</resultMap>

<select id="selectByAnything" resultMap="ArticleResultMap">
        select web_article.*, username
        from web_article,
             web_user,
             user_article
        where title like concat('%', #{search}, '%')
          and web_article.id = user_article.article_id
          and user_article.author_id = web_user.id
          and web_article.id in (select article_id from user_article where author_id = #{id})
          and web_user.id = #{id}
    </select>

下面是用了”硬拼“之后的代码,根本不用web_user这个表,还有给字段起个别名就不用再写自定义映射了,不容易乱

<select id="selectByAnything" resultType="article">
        select web_article.*, (select username from web_user where id = #{id}) author
        from web_article,
             user_article
        where title like concat('%', #{search}, '%')
          and web_article.id = user_article.article_id
          and web_article.id in (select article_id from user_article where author_id = #{id})

    </select>

第一个代码块的结果: 在这里插入图片描述

  • 查询语句使用一个子查询来添加文章的作者名字。子查询选择“web_user”表中与给定作者 ID 相对应的用户名,并将其命名为“author”,查询语句的结果集将包含“web_article”表中符合条件的记录,以及一个名为“author”的额外列,其中包含给定作者 ID 的作者名字。
  • 在指定要检索的列的列表和要检索数据的来源的表或视图的名称的地方,即select后边,from前边加上了不属于web_article而属于web_user的author列

2.正文

再来看一个例子

select 1 = 1, 1 = 2
from web_user;

查询结果 在这里插入图片描述 这条 SQL 查询语句将在执行时返回一个结果集,该结果集将包含两个布尔值,分别表示“1等于1”和“2等于1”的结果,在这种情况下,查询语句没有任何实际的业务逻辑或数据检索功能,它只是简单地比较两个布尔值,并返回结果,我称之为“硬拼

所以上边引言的例子,其实也使用了我称之为“”硬拼“的方法


因为在引言中的例子的这个语句select web_article.*, (select username from web_user where id = #{id}) author,将username这个列命名为author 所以补充一点:mybatis中若字段名和实体类中的属性名不一致,但是字段名符合数据库的规则(使用_),实体类中的属性名符合Java的规则(使用驼峰),此时也可通过以下这种方式处理字段名和实体类中的属性的映射关系

==可以通过为字段起别名的方式,保证和实体类中的属性名保持一致,就不需要resultMap设置自定义映射了==


总结:==在多表查询中,如果只需要查询其中一个表的部分数据,可以在select之后,from之前加一个子查询,从而简化多表查询的操作,不容易混乱,为字段起别名可以处理字段名和实体类中的属性的映射关系==

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月12日 0

暂无评论

推荐阅读
  xaeiTka4h8LY   2024年05月31日   36   0   0 MySQL索引
  xaeiTka4h8LY   2024年05月31日   46   0   0 MySQLSQL
  xaeiTka4h8LY   2024年05月31日   30   0   0 字段MySQL
  xaeiTka4h8LY   2024年05月31日   41   0   0 MySQL数据库
  xaeiTka4h8LY   2024年05月17日   52   0   0 数据库JavaSQL
  xaeiTka4h8LY   2024年05月17日   47   0   0 MySQLgithub
  xaeiTka4h8LY   2024年05月17日   51   0   0 数据库SQL
  xaeiTka4h8LY   2024年05月17日   38   0   0 MySQL数据库
OZvmQgWagkrp