Mybatis---多表联合查询(1)

news/2024/11/7 21:18:19/

Mybatis---多表联合查询(1)

  • 前言
  • 测试准备
  • 一、一对一
    • 新建方法
    • 添加关联
    • 测试
  • 二、一对多
    • 新建实体类
    • 添加方法
    • 添加关联
    • 测试

前言

在开发过程中单表查询不能满足项目需求分析功能,对于复杂业务来讲,关联的表有几张,甚至几十张并且表与表之间的关系相当复杂。为了能够实业复杂功能业务,就必须进行多表查询,在mybatis中提供了多表查询的结果时映射标签,可以实现表之间的一对一、一对多、多对多关系映射

测试准备

案例所需数据库脚本

SET FOREIGN_KEY_CHECKS=0;-- ----------------------------
-- Table structure for car
-- ----------------------------
DROP TABLE IF EXISTS `car`;
CREATE TABLE `car` (`cid` int(11) NOT NULL AUTO_INCREMENT,`cname` varchar(20) DEFAULT NULL,`pid` int(11) NOT NULL,PRIMARY KEY (`cid`) USING BTREE,KEY `cp` (`pid`) USING BTREE,CONSTRAINT `car_ibfk_1` FOREIGN KEY (`pid`) REFERENCES `person` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;-- ----------------------------
-- Records of car
-- ----------------------------
INSERT INTO `car` VALUES ('1', '忆柳的购物车', '2');
INSERT INTO `car` VALUES ('2', '梦琪的购物车', '1');
INSERT INTO `car` VALUES ('3', '新柔的购物车', '5');
INSERT INTO `car` VALUES ('4', '慕青的购物车', '3');
INSERT INTO `car` VALUES ('5', '初夏的购物车', '4');-- ----------------------------
-- Table structure for order
-- ----------------------------
DROP TABLE IF EXISTS `order`;
CREATE TABLE `order` (`oid` int(11) NOT NULL AUTO_INCREMENT,`oname` varchar(255) DEFAULT NULL,`pid` int(11) DEFAULT NULL,PRIMARY KEY (`oid`) USING BTREE,KEY `op` (`pid`) USING BTREE,CONSTRAINT `order_ibfk_1` FOREIGN KEY (`pid`) REFERENCES `person` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;-- ----------------------------
-- Records of order
-- ----------------------------
INSERT INTO `order` VALUES ('1', '荣耀MagicBook 2019 14英寸轻薄窄边框', '2');
INSERT INTO `order` VALUES ('2', '小米 (MI)Ruby 2019款 15.6英寸金属轻薄', '1');
INSERT INTO `order` VALUES ('3', '戴尔灵越14 燃 14英寸英特尔酷睿i5轻薄窄边框', '3');
INSERT INTO `order` VALUES ('4', '联想(Lenovo)小新14英寸 锐龙版R5', '4');
INSERT INTO `order` VALUES ('5', '红辣椒7X 4+64GB 学生智能手机', '5');
INSERT INTO `order` VALUES ('6', '荣耀10青春版 幻彩渐变', '1');
INSERT INTO `order` VALUES ('7', 'OPPO K1 全面屏手机', '2');
INSERT INTO `order` VALUES ('8', '卡梵蒂GAVADI 鳄鱼皮钱包', '5');
INSERT INTO `order` VALUES ('9', '七匹狼钱包', '2');
INSERT INTO `order` VALUES ('10', '金利来(Goldlion)男士钱包', '1');-- ----------------------------
-- Table structure for person
-- ----------------------------
DROP TABLE IF EXISTS `person`;
CREATE TABLE `person` (`id` int(11) NOT NULL,`name` varchar(32) DEFAULT NULL,`birthday` date DEFAULT NULL,`address` varchar(32) DEFAULT NULL,PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;-- ----------------------------
-- Records of person
-- ----------------------------
INSERT INTO `person` VALUES ('1', 'ddd', '2019-05-08', '北京市');
INSERT INTO `person` VALUES ('2', '忆柳', '2019-05-14', '天津市');
INSERT INTO `person` VALUES ('3', '慕青', '2018-10-17', '上海市');
INSERT INTO `person` VALUES ('4', '初夏', '2017-04-13', '重庆市');
INSERT INTO `person` VALUES ('5', '新柔', '2018-12-29', '广州市');

实体类:Person、Car

package com.entity;import java.util.Date;
import java.util.List;public class Person {private Integer id;private String name;private Date birthday;private String address;private Car car;//一个用户拥有一个carprivate List<Order> orderList;//一个用户拥有多个订单public Person() {}public Person(Integer id, String name, Date birthday, String address, Car car, List<Order> orderList) {this.id = id;this.name = name;this.birthday = birthday;this.address = address;this.car = car;this.orderList = orderList;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Date getBirthday() {return birthday;}public void setBirthday(Date birthday) {this.birthday = birthday;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}public Car getCar() {return car;}public void setCar(Car car) {this.car = car;}public List<Order> getOrderList() {return orderList;}public void setOrderList(List<Order> orderList) {this.orderList = orderList;}@Overridepublic String toString() {return "Person{" +"id=" + id +", name='" + name + '\'' +", birthday=" + birthday +", address='" + address + '\'' +", car=" + car +", orderList=" + orderList +'}';}
}
package com.entity;public class Car {private Integer cid;private String cname;private Integer  pid;public Car() {}public Car(Integer cid, String cname, Integer pid) {this.cid = cid;this.cname = cname;this.pid = pid;}public Integer getCid() {return cid;}public void setCid(Integer cid) {this.cid = cid;}public String getCname() {return cname;}public void setCname(String cname) {this.cname = cname;}public Integer getPid() {return pid;}public void setPid(Integer pid) {this.pid = pid;}@Overridepublic String toString() {return "Car{" +"cid=" + cid +", cname='" + cname + '\'' +", pid=" + pid +'}';}
}

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration><!-- 别名 --><typeAliases><package name="com.entity"/></typeAliases><!-- environments  多环境配置environment   配置数据源transactionManager     事务管理器dataSource     数据源--><environments default="p1"><environment id="p1"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/mybatis"/><property name="username" value="root"/><property name="password" value="123456"/></dataSource></environment></environments><!-- 注册映射  --><mappers><mapper resource="PersonMapper.xml"/><mapper resource="CarMapper.xml" /></mappers>
</configuration>

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.ujiuye</groupId><artifactId>mybatics</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target></properties><dependencies><!--    数据库驱动 版本不能乱用5.1.47  --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.47</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.4.6</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13</version><scope>test</scope></dependency><!-- lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.10</version></dependency><!-- 日志文件 --><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.12</version></dependency></dependencies>
</project>

目录结构

在这里插入图片描述


一、一对一

什么是一对一?举个栗子:一个用户只能拥有一个购物车

新建方法

分别在PersonMapper接口、CarMapper接口中添加方法

public interface PersonMapper {//显示指定person信息public Person findPersonByName(String name);
}
public interface CarMapper {//根据person id查询购物车信息public Car findCarById(int id);
}

添加关联

在Person实体类中添加Car对象(上面的准备中,其实已经添加)

在这里插入图片描述

在PersonMapper.xml文件中添加关联(resultMap)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.mapper.PersonMapper"><!-- id:resultMap的名字  type:方法返回值类型  autoMapper:自动映射 --><resultMap id="resultMap1" type="com.entity.Person" autoMapping="true"><!-- id标签表示person表的主键  property表示Person类的属性  column表示person表的字段--><id property="id" column="id"></id><!--association:方法返回值是一个对象时使用该标签  property表示Person类的属性javaType表示CarMapper中方法执行后返回值类型   column表示person表的字段当mybatis 执行完 person表的查询操作后,就会自动执行 CarMapper接口中的 findCarById的方法把查询得到的信息封装到person类下的car对象--><association property="car" javaType="car" column="id"select="com.mapper.CarMapper.findCarById"></association></resultMap><!--id:接口中对应的方法名 --><select id="findPersonByName" resultMap="resultMap1">select * from person where name = #{name}</select>
</mapper>

测试

只调用PerMapper中的方法情况下是否能够获取car表中数据

@Testpublic void test1() throws IOException {//读取配置文件InputStream is = Resources.getResourceAsStream("mybatis-config.xml");//根据配置文件构建工厂SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(is);//获取会话SqlSession sqlSession = sessionFactory.openSession();//获取Mapper对象PersonMapper personMapper = sqlSession.getMapper(PersonMapper.class);//执行方法Person person = personMapper.findPersonByName("初夏");System.out.println(person);sqlSession.close();}

car表

在这里插入图片描述

运行结果(我这里使用了log4j日志打印,可能控制台有所不同)

在这里插入图片描述

思路总结:通过name来获得person表中对应的id→person表中的id对应car表中的pid(联表的关键)→通过pid来获得car表中的cname,一对一返回一个对象


二、一对多

什么是一对多?举个栗子:一个用户拥有多个订单

新建实体类

新建一个Order类记录订单

package com.entity;public class Order {private Integer oid;private String oname;private Integer pid;public Order() {}public Order(Integer oid, String oname, Integer pid) {this.oid = oid;this.oname = oname;this.pid = pid;}public Integer getOid() {return oid;}public void setOid(Integer oid) {this.oid = oid;}public String getOname() {return oname;}public void setOname(String oname) {this.oname = oname;}public Integer getPid() {return pid;}public void setPid(Integer pid) {this.pid = pid;}@Overridepublic String toString() {return "Order{" +"oid=" + oid +", oname='" + oname + '\'' +", pid=" + pid +'}';}
}

添加方法

分别在PersonMapper和OrderMapper中添加方法

public Person findPersonByName2(String name);
public interface OrderMapper {//根据person 的 id 查询对应的订单信息public List<Order> findOrderById(int id);}

添加关联

OrderMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.mapper.OrderMapper"><select id="findOrderById" resultType="com.entity.Order">select * from `order` where pid = #{pid}</select>
</mapper>

PersonMapper.xml中添加

<resultMap id="resultMap2" type="person" autoMapping="true"><id column="id" property="id"></id><collection property="orderList" ofType="Order" column="id"select="com.mapper.OrderMapper.findOrderById"  ></collection>
</resultMap>
<select id="findPersonByName2" resultMap="resultMap2">select * from person where name = #{name}
</select>

记得在mybatis-config.xml注册映射

<mapper resource="OrderMapper.xml" />

测试

@Testpublic void test3() throws IOException {InputStream is = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(is);SqlSession sqlSession = sessionFactory.openSession();PersonMapper personMapper = sqlSession.getMapper(PersonMapper.class);Person person = personMapper.findPersonByName2("初夏");List<Order> orderList = person.getOrderList();System.out.println(person);for (Order order : orderList) {System.out.println(order);}sqlSession.close();}

运行结果

在这里插入图片描述

思路总结:通过name来获得person表中对应的id→person表中的id对应order表中的pid(联表的关键)→通过pid来获得car表中的oname,与一对一不同的是一对多返回的是一个对象集合


http://www.ppmy.cn/news/333093.html

相关文章

网络层:IPv4地址

网络层&#xff1a;IPv4地址 笔记来源&#xff1a; 湖科大教书匠&#xff1a;IPv4地址概述 湖科大教书匠&#xff1a;分类编址的IPv4地址 湖科大教书匠&#xff1a;划分子网的IPv4地址 湖科大教书匠&#xff1a;无分类编址的IPv4地址 IPv4地址就是给因特网(Internet)上的每一…

【Spring Boot整合MyBatis教程】

Spring Boot是由Pivotal团队提供的全新框架&#xff0c;其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置&#xff0c;从而使开发人员不再需要定义样板化的配置。通过这种方式&#xff0c;Spring Boot致力于在蓬勃发展的快速应用开发…

清吧音响怎么选?看看这个黄金搭配,跟着买就对了

在筹备清吧的时候&#xff0c;选择音响是一个难题&#xff0c;具体的搭配方案以及选择上有一定的广泛性&#xff0c;具体需要怎么做一个预算和选择呢&#xff1f;下面为大家做一个具体对整个音响设备选择的方案和最值得购买的设备黄金搭配&#xff0c;你会发现一个清吧的音响系…

南卡与JBL蓝牙耳机哪款比较好?数码资深玩家带你深度评测了解

马上到来2023新的一年&#xff0c;不会还有人使用传统有线耳机吧&#xff1f;那你就属最落后的那位了&#xff0c;随着生活水平的提高&#xff0c;科技的快速发展&#xff0c;有线耳机逐渐被真无线蓝牙耳机所取代。现在走在马路上都能看见许多人佩戴着耳机&#xff0c;然而&…

雷神轮胎携手JBL 演绎科技降噪、感受非凡音悦

近日&#xff0c;雷神轮胎与哈曼旗下知名音响品牌JBL进行合作&#xff0c;携手演绎科技降噪&#xff0c;致力于为广大车主带来更舒适愉悦的驾乘体验。 雷神轮胎作为一个中高端黑科技静音轮胎品牌&#xff0c;此次与全球久负盛名的专业扬声器生产商JBL强强联合&#xff0c;围绕…

记录 | 将Word生成的静态网页部署到Github Page

任务描述 使用Word, 可以直接获得 一个静态的网页XXX.html和对应的文件夹XXX.files问题&#xff1a;如何将它托管在github上&#xff1f; 步骤 使用github pages进行托管和发布 步骤1&#xff1a;创建仓库 创建一个新的GitHub仓库&#xff1a;访问 https://github.com 并使用…

【C++/嵌入式笔试面试八股】二、15.虚拟内存 | 外设管理

虚拟内存 MMU 相关见Linux内核 62.局部性原理你知道吗?各自是什么? 主要分为时间局部性和空间局部性。 时间局部性:如果执行了程序中的某条指令,那么不久后这条指令很有可能再次执行;如果某个数据被访问过,不久之后该数据很可能再次被访问。(因为程序中存在大量的循环) …

【SQL】数据筛选过滤(初级)

对于SQL数据库&#xff0c;我们可以通过select和where组合来实现特定数据的搜索和过滤。 1、读取表test_table中的所有数据&#xff0c;可以用*来筛选&#xff1a; select * from test_table;2、读取表test_table中的所有数据&#xff0c;并根据price做升序排序 select * fr…