MyBatis(4)---多表查询

news2024/11/24 15:38:08

多表查询:

一对一:一篇博客对应着一个作者

一对多:一个作者对应着多篇博客

ResultMap和ResultType的区别:

1)字段映射不同:resultType适用于数据库字段名和实体类的名字是相同的,但是假设实体类的名字叫做username,但是数据库的名字是name,这时候数据库字段名和实体类的名字是不一样的,所以我们需要使用ResultMap----字段名不一致的时候进行映射的处理

2)多表查询不同:多表查询适用于ResultMap

指定别名的作用:通常给第二张表的相同字段指定别名

如果说进行连表查询的时候两张表有相同的字段,那么在你不指定别名的情况下,第二张表重复的字段将会被第一张表重复的字段属性所覆盖,如果多张表的两张表的字段全部不一样,那么刺史部设置前缀不会有任何问题

下面我们来进行演示一下一对一多表查询:

1)在上面我们已经完成了多表查询,现在我们在进行创建一张表,叫做blog表(博客表)

我们既然要进行一对一的多表查询,一对一映射,因为一篇博客值对应着一个作者

2)设置前缀的作用:因为我们知道,在实际的工作环境中,我们的博客表和用户表很有可能是存在相同的字段名的,很有可能是说我们的User表里面,有一个唯一的用户身份标识叫做ID,还有一个唯一的博客身份标识也叫做ID,那么这时候我们进行连表查询的时候就会出现严重的问题,所以我们要进行设置一个别名;

3)因为一篇博客对应着唯一的作者,所以我们在博客列表对应的Java代码中,我们要进行设置一个User属性,下面是我们的数据库建表操作和创建实体类,我们还要安装MyBatisX这个插件

 create table blog(
       blogID int primary key auto_increment,
       userID int,
       title varchar(30),
       content varchar(30));
package com.example.demo;
import lombok.Data;
@Data
public class Blog {
    int blogID;
    int userIDl
    String title;
    String content;
    User user;
}

此时我们写一下Java代码:

1)我们写的BlogController里面的代码: 

package com.example.demo.Controller;

import com.example.demo.Blog;
import com.example.demo.Service.BlogService;
import com.example.demo.Service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
@Controller
public class BlogController {
    @Autowired
    BlogService blogService;
   @RequestMapping("/GetAll")
   @ResponseBody
    public List<Blog> GetAll()
    {
        return blogService.GetAll();
    }

}

2)我们写的BlogService里面的代码:

package com.example.demo.Service;
import com.example.demo.Blog;
import com.example.demo.Mapper.BlogMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class BlogService {
    @Autowired
    BlogMapper mapper;
    public List<Blog> GetAll() {
        return mapper.GetAll();
    }
}

3)我们写的BlogMapper接口里面的代码和blogMapper.XML文件里面的代码:

这个是接口里面的代码:
package com.example.demo.Mapper;
import com.example.demo.Blog;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface BlogMapper {
    List<Blog> GetAll();
}
这个是XML文件里面的代码:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD com.example.demo.Mapper1 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.Mapper.BlogMapper">
    <select id="GetAll" resultType="com.example.demo.Blog">
        select * from blog left join user on user.userID=blog.userID;
    </select>
</mapper>

1)我们在这个XML文件里面我们用namespace指定了我们实现接口的位置换句话来说就是实现接口的路径

2)我们用resultType表示了我们要返回的类型,换句话说就是我们数据库表对应的实体类的路径

3)但是我们要注意一下,在整个XML文件里面,我们都没有进行指定User实体类的路径(因为在我们blog类中还有User这样的属性,由于XML文件中没有这样的指定位置,所以我们无法得到User对象,所以我们看到当我们使用浏览器进行访问的时候,我们无法得到user对象

 4)所以我们使用resultType的方法是不行的,我们尝试用一下resultMap

<assocation>标签的用法:

第一个字段property的参数指定的是我们blog表中要进行关联的属性

第二个字段resultMap,表示User表中的resultMap的位置:

第三个参数表示前缀,我们想要查询User对象的所有字段的属性都要加上前缀:

blogMapper.xml文件里面的代码:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD com.example.demo.Mapper1 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.Mapper.BlogMapper">
    <resultMap id="BaseMap" type="com.example.demo.Blog">
<!--1.我们现针对blog表中的自增组件进行设置-->
        <id property="blogID" column="blogID"></id>
<!--2.我们接下来再进行设置普通字段-->
        <result property="userID" column="userID"></result>
        <result property="title" column="title"></result>
        <result property="content" column="content"></result>
<!--3.直接指定User对象的路径-->
        <association property="user" resultMap="com.example.demo.Mapper.UserMapper.BaseMapHH" columnPrefix="u_"></association>
    </resultMap>
    <select id="GetAll" resultMap="BaseMap">
        select blog.*,user.userID as u_userID,user.classID as u_classID,user.password as u_password,user.username as u_username
        from blog left join user on user.userID=blog.userID;
    </select>
</mapper>

我们写的UserMapper.xml里面的代码:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD com.example.demo.Mapper1 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.Mapper.UserMapper">
  <resultMap id="BaseMapHH" type="com.example.demo.User">
<!--先进行设置自增主键-->
    <id column="userID" property="userID"></id>
<!--再进行设置普通字段-->
    <result column="classID" property="classID"></result>
    <result column="username" property="username"></result>
    <result column="password" property="password"></result>
  </resultMap>
</mapper>

我们此时进行创建方法,我们进行返回的是一个List<blog>集合,里面包含了若干个blog,里面都包含了唯一的作者,所以说我们是不能使用resultType会导致我们的自定义的对象没有值

1)resultMap:所以说我们一定要在我们所关联对象的XML文件里面建立一个resultMap,他是不能指定一个resultType,所以说我们要存放管理属性的字典映射

2)别忘了写前缀,如果说我们在进行多表查询的时候两张表出现了相同的字段,如果没设置前缀,那么查询的结果就是错误的,防止多张表出现相同字段查询问题;

现在我们使用一下一对多查询:

1)咱们说上面我们进行多表查询的时候,我们的一篇博客是对应着一个作者,这是一对一的关系,但是从另一个角度来说:我们的一个作者又是对应着多篇博客的,所以我们针对一对多来进行查询;

2)因为一个作者是对应着多篇博客的,所以我们要在user表里面加上一个字段List<blog>

package com.example.demo;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

import java.util.List;

@Setter
@Getter
@ToString
public class User {
    private int ClassID;
    private int userID;
    private String username;
    private String password;
    List<Blog> list;
}

我们可以先写一个SQL语句进行验证一下:

展示代码:

1)我们写的UserController里面的代码: 

package com.example.demo.Controller;
import com.example.demo.Service.UserService;
import com.example.demo.User;
import netscape.security.UserTarget;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.List;
@Controller
public class UserController {
    @Autowired
    UserService userService;
      @RequestMapping("/Get")
      @ResponseBody
     public List<User> GetAll()
     {
         return userService.GetAll();
     }

}

2)咱们的UserService和UserMapper里面的代码如下:

package com.example.demo.Service;
import com.example.demo.Blog;
import com.example.demo.Mapper.UserMapper;
import com.example.demo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserService {
        @Autowired
        private UserMapper mapper;
    public List<User> GetAll() {
        return mapper.GetAll();
    }
}
package com.example.demo.Mapper;
import com.example.demo.Blog;
import com.example.demo.User;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface UserMapper {
    List<User> GetAll();
}

3)咱们的blogXML文件中的代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD com.example.demo.Mapper1 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.Mapper.BlogMapper">
    <resultMap id="BaseMap" type="com.example.demo.Blog">
<!--1.我们现针对blog表中的自增组件进行设置-->
        <id property="blogID" column="blogID"></id>
<!--2.我们接下来再进行设置普通字段-->
        <result property="userID" column="userID"></result>
        <result property="title" column="title"></result>
        <result property="content" column="content"></result>
<!--3.直接指定User对象的路径-->
        <association property="user" resultMap="com.example.demo.Mapper.UserMapper.BaseMap" columnPrefix="u_"></association>
    </resultMap>
    <select id="GetAll" resultMap="BaseMap">
        select blog.*,user.userID as u_userID,user.classID as u_classID,user.password as u_password,user.username as u_username
        from blog left join user on user.userID=blog.userID;
    </select>
</mapper>

4)在们的blogMapper.xml中的代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD com.example.demo.Mapper1 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.Mapper.UserMapper">
  <resultMap id="BaseMap" type="com.example.demo.User">
<!--先进行设置自增主键-->
    <id column="userID" property="userID"></id>
<!--再进行设置普通字段-->
    <result column="classID" property="classID"></result>
    <result column="username" property="username"></result>
    <result column="password" property="password"></result>
<!--此时我们进行一对多查询-->
      <collection property="list" resultMap="com.example.demo.Mapper.BlogMapper.BaseMap" columnPrefix="u_"></collection>
  </resultMap>
    <select id="GetAll" resultMap="BaseMap">
        select user.*,blog.blogID as u_blogID,blog.userID as u_userID,blog.title as u_title,blog.content as u_content from user join blog on blog.userID=user.userID;
    </select>
</mapper>

结果:

logging.level.com.example.demo=debug

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

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

相关文章

MyBatis(3)

我们在进行指定ID进行删除的时候还可以加上一个属性:表示要传递的参数的类型是啥 <delete id"Delete" parameterType"java.lang.Integer">delete from user where userID#{userID}</delete> 我们现在先实现一个场景----我们来进行查询一下User…

【毕业设计】大数据共享单车数据分析系统 - python

文章目录0 前言1 项目背景2 项目分析思维导图3 项目分析具体步骤3.1 读取数据3.2 数据分析3.1.1 数据预处理——每日使用量分析3.1.2 连续7天的单日使用分析结论3.1.3 数据预处理——每日不同时间段的使用量分析3.1.4 每日不同时间段使用量分析结论3.1.5 数据预处理——骑行距离…

【C++】智能指针

一、资源的管理 RAII:Resource Acquisition Is Initialization的简称&#xff0c;其翻译过来就是“资源获取即初始化”&#xff0c;即在构造函数中申请分配资源&#xff0c;在析构函数中释放资源&#xff0c;它是C语言中的一种管理资源、避免泄漏的良好方法。 C语言的机制保证…

python快速实现简易超级玛丽小游戏

《超级玛丽》是一款超级马里奥全明星的同人作品&#xff0c;也是任天堂公司出品的著名横版游戏。 《超级马里奥》是一款经典的像素冒险过关游戏。最早在红白机上推出&#xff0c;有多款后续作品&#xff0c;迄今多个版本合共销量已突破4000万套。其中的主角马里奥、路易、碧琪…

[附源码]计算机毕业设计JAVAjsp闲置物品线上交易系统

[附源码]计算机毕业设计JAVAjsp闲置物品线上交易系统 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM …

tensor和numpy相互转换

tensor转成numpy b a.numpy()import torcha torch.arange(5) b a.numpy() print(a) print(type(a)) print(b) print(type(b))numpy转成tensor b torch.tensor(a)import torch import numpy as npa np.ones(5) b torch.tensor(a) print(a) print(type(a)) print(b) prin…

Spring Cloud框架(原生Hoxton版本与Spring Cloud Alibaba)基础入门篇 ---- 搭建环境

springcloud官方文档&#xff08;Hoxton SR5&#xff09;&#xff1a;https://cloud.spring.io/spring-cloud-static/Hoxton.SR5/reference/htmlsingle/ springcloud中文文档&#xff1a;https://www.springcloud.cc/ springcloud中国社区文档&#xff1a;http://docs.springcl…

【C++】栈~~(很详细哦)

在前几天&#xff0c;我们刚一起学过顺序表&#xff0c;链表&#xff08;无头单向不循环&#xff0c;有头双向循环&#xff09;&#xff0c;这两种都属于线性表因为是一系列存储的。而以后的哈希表则是散列表 今天我们看一下栈 目录 1.栈的介绍 2.实现 3.题目 1.栈的介绍 …

mindspore::dataset::GetAffineTransform的输出与cv2的输出不同

在使用C进行推理时用到了函数mindspore::dataset::GetAffineTransform&#xff0c;但是输入相同的数据后&#xff0c;与Python的cv2中的同名函数cv2.getAffineTransform所输出的结果不同。 C Ascend310端测试核心代码 #include <iostream> #include <vector>#…

synchronized 关键字背后的锁升级流程

文章目录前言一、基本特点二、加锁过程总结前言 博主个人社区&#xff1a;开发与算法学习社区 博主个人主页&#xff1a;Killing Vibe的博客 欢迎大家加入&#xff0c;一起交流学习~~ 一、基本特点 结合多线程锁的策略, 我们就可以总结出, Synchronized 具有以下特性(只考虑 J…

基于51单片机的智能台灯设计

一.硬件方案 本文介绍了一种基于PWM调光的智能台灯设计。把单片机技术和PWM调光技术结合起来实现台灯光强的调节。即在不改变PWM方波周期的前提下&#xff0c;利用单片机控制PWM的占空比&#xff0c;从而来改变电压的大小实现灯光亮度的调节。 当人体在台灯的范围内且环…

linux驱动设备节点失踪之迷雾围城

前言 参考文章&#xff1a;无法生成设备节点 最后证实&#xff1a;是bootargs配置错误导致的&#xff0c;不过中间发现也是可以通过mdev -s间接解决的&#xff0c;算是学习经验吧。 misc驱动框架是linux内核驱动中最简单实用的框架了。记录一下今天调试misc驱动的问题。misc驱动…

笔试强训48天——day19

文章目录一. 单选1.二分查找的时间复杂度&#xff08;&#xff09;2. 有一个单向链表中有一个A、B两个相邻元素&#xff0c;有一个指针p指向元素A&#xff0c;现将一个指针r指向的S元素要插入3. 双向链表中有两个指针域,llink和rlink分别指向前驱和后继,设p指向链表中的一个结点…

spark底层原理理解--高级进阶

概念概念理解和解释备注窄依赖窄依赖指1个父RDD分区数据只被1个子RDD的分区使用&#xff0c;即一对一或多对一的关系。 分为两种映射情况&#xff1a;一个父RDD的分区对应于一个子RDD的分区&#xff0c;或者多个父RDD的分区对应于一个子RDD的分区。 1个子RDD的分区对应于1个父R…

深入理解JS作用域链与执行上下文

变量提升&#xff1a; 变量提升&#xff08; hoisting &#xff09;。 我可恨的 var 关键字&#xff1a; 你读完下面内容就会明白标题的含义&#xff0c;先来一段超级简单的代码&#xff1a; <script type"text/javascript">var str Hello JavaScript hoi…

【K8S】初探Kubernetes

文章目录什么是容器编排什么是KubernetesK8s 和 Docker 之间的关系Kubernetes的整体架构Master 里的组件构成Work Node 里的组件构成总结K8s 组件工作流程结束语什么是容器编排 在《Docker 进阶指南&#xff08;下&#xff09;- 使用Docker Compose编排多个容器》文章当中&…

文件缓冲区

本期介绍&#x1f356; 主要介绍&#xff1a;什么是文件缓冲区&#xff0c;文件缓冲区存在的意义是什么&#xff0c;文件缓冲区的证明&#x1f440;。 一、什么是文件缓冲区 每一个正在使用的文件&#xff0c;操作系统都会为其在内存中开辟一块区域&#xff0c;称之为&#xff…

【数据结构】带头双向链表的简单实现

目录前言链表的实现List.hList.c**ListCreate()****LTInit()****ListPushBack()****ListPopBack()****ListPrint()****ListPushFront()****ListPopFront()****ListFind()****ListInsert()****ListErase()**ListErase()test.c前言 该篇博客主要讲解了带头双向链表的实现和一些细…

Cadence Allegro DXF结构图的导入详细教程

很多消费类板卡的结构都是异形的&#xff0c;由专业的CAD结构工程师对其进行精准的设计&#xff0c;PCB布线工程师可以根据结构工程师提供的2D图&#xff08;DWG或DXF格式&#xff09;进行精准的导入操作&#xff0c;在PCB中定义板型结构。 同时&#xff0c;对于一些工控板或者…

Ajax--跨域与JSONP--案例-淘宝搜索

要实现的UI效果 获取用户输入的搜索关键词 为了获取到用户每次按下键盘输入的内容&#xff0c;需要监听输入框的 keyup 事件&#xff0c;示例代码如下&#xff1a; // 监听文本框的 keyup 事件$(#ipt).on(keyup, function() {// 获取用户输入的内容var keywords $(this).val…