当前位置: 首页 > news >正文

MyBatis联合查询

文章目录

  • 数据库设计
  • MyBatis 配置
  • MyBatis 映射文件
    • Mapper 接口
  • 总结

数据库设计

建表 SQL

CREATE TABLE user (id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(50) NOT NULL
);CREATE TABLE `order` (id INT PRIMARY KEY AUTO_INCREMENT,user_id INT NOT NULL,order_no VARCHAR(50) NOT NULL,FOREIGN KEY (user_id) REFERENCES user(id)
);CREATE TABLE role (id INT PRIMARY KEY AUTO_INCREMENT,role_name VARCHAR(50) NOT NULL
);CREATE TABLE user_role (user_id INT NOT NULL,role_id INT NOT NULL,PRIMARY KEY (user_id, role_id),FOREIGN KEY (user_id) REFERENCES user(id),FOREIGN KEY (role_id) REFERENCES role(id)
);

插入以下数据:

INSERT INTO user (name) VALUES ('Alice'), ('Bob');
INSERT INTO `order` (user_id, order_no) VALUES (1, 'ORD001'), (1, 'ORD002'), (2, 'ORD003');
INSERT INTO role (role_name) VALUES ('Admin'), ('User');
INSERT INTO user_role (user_id, role_id) VALUES (1, 1), (1, 2), (2, 2);

MyBatis 配置

我们使用 MySQL 数据库,MyBatis 的核心配置文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="com.mysql.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/test_db?useSSL=false"/><property name="username" value="root"/><property name="password" value="123456"/></dataSource></environment></environments><mappers><mapper resource="mapper/UserMapper.xml"/></mappers>
</configuration>

定义 Java 实体类,映射数据库表:

@Data
public class User {private Integer id;private String name;private Order order; // 一对一:用户关联一个订单private List<Order> orders; // 一对多:用户关联多个订单private List<Role> roles; // 多对多:用户关联多个角色
}@Data
public class Order {private Integer id;private Integer userId;private String orderNo;
}@Data
public class Role {private Integer id;private String roleName;
}

MyBatis 映射文件

在 UserMapper.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.mapper.UserMapper"><!-- 一对一 --><resultMap id="UserWithOrderMap" type="com.example.entity.User"><id property="id" column="user_id"/><result property="name" column="user_name"/><association property="order" javaType="com.example.entity.Order"><id property="id" column="order_id"/><result property="userId" column="user_id"/><result property="orderNo" column="order_no"/></association></resultMap><select id="selectUserWithOrder" resultMap="UserWithOrderMap">SELECT *FROM user uLEFT JOIN `order` o ON u.id = o.user_idWHERE u.id = #{id}LIMIT 1</select><!-- 一对多 --><resultMap id="UserWithOrdersMap" type="com.example.entity.User"><id property="id" column="user_id"/><result property="name" column="user_name"/><collection property="orders" ofType="com.example.entity.Order"><id property="id" column="order_id"/><result property="userId" column="user_id"/><result property="orderNo" column="order_no"/></collection></resultMap><select id="selectUserWithOrders" resultMap="UserWithOrdersMap">SELECT *FROM user uLEFT JOIN `order` o ON u.id = o.user_idWHERE u.id = #{id}</select><!-- 多对多 --><resultMap id="UserWithRolesMap" type="com.example.entity.User"><id property="id" column="user_id"/><result property="name" column="user_name"/><collection property="roles" ofType="com.example.entity.Role"><id property="id" column="role_id"/><result property="roleName" column="role_name"/></collection></resultMap><select id="selectUserWithRoles" resultMap="UserWithRolesMap">SELECT *FROM user uLEFT JOIN user_role ur ON u.id = ur.user_idLEFT JOIN role r ON ur.role_id = r.idWHERE u.id = #{id}</select>
</mapper>

Mapper 接口

定义对应的 Mapper 接口:

public interface UserMapper {User selectUserWithOrder(Integer id); // 一对一User selectUserWithOrders(Integer id); // 一对多User selectUserWithRoles(Integer id); // 多对多
}

以下是测试代码,验证查询结果:

public class MyBatisTest {public static void main(String[] args) throws Exception {SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(new FileInputStream("mybatis-config.xml"));try (SqlSession session = factory.openSession()) {UserMapper mapper = session.getMapper(UserMapper.class);// 测试一对一User userWithOrder = mapper.selectUserWithOrder(1);System.out.println(userWithOrder.getName());// 测试一对多User userWithOrders = mapper.selectUserWithOrders(1);System.out.println(userWithOrders.getName());userWithOrders.getOrders().forEach(order -> System.out.println("  - " + order.getOrderNo()));// 测试多对多User userWithRoles = mapper.selectUserWithRoles(1);System.out.println(userWithRoles.getName());userWithRoles.getRoles().forEach(role -> System.out.println("  - " + role.getRoleName()));}}
}

总结

一对一:通过 association 标签,查询用户及其关联的一个订单。
一对多:通过 collection 标签,查询用户及其所有订单,MyBatis 自动将多行订单数据映射到 List。
多对多:通过 collection 标签,查询用户及其所有角色,借助中间表 user_role 实现关联。

http://www.dtcms.com/a/319762.html

相关文章:

  • windows有一个企业微信安装包,脚本执行并安装到d盘。
  • 我的世界Java版1.21.4的Fabric模组开发教程(十七)自定义维度
  • PCL提取平面上的圆形凸台特征
  • WindowsLinux系统 安装 CUDA 和 cuDNN
  • 从库存一盘货到全域智能铺货:巨益科技全渠道平台助力品牌业财一体化升级
  • 电子基石:硬件工程师的器件手册 (九) - DC-DC拓扑:电能转换的魔术师
  • 线上业务突然流量掉 0 ?一次 DNS 污染排查与自救实录
  • Qt中类提升后不显示问题
  • 纷享销客前端实习一面
  • 数据结构(五):顺序循环队列与哈希表
  • 纪念《信号与系统》拉普拉斯变换、Z变换之前内容学完
  • 树莓派Raspberry Pi 烧录
  • TCP/IP 协议中的三次握手和四次挥手-----详解笔记
  • 板块三章节3——NFS 服务器
  • 人工智能2.0时代的人才培养和通识教育
  • 计算机视觉第一课opencv(一)保姆级教学
  • lane_up channel_up
  • mysql8.0.40服务日志时间和linux系统时间不同步问题!
  • 指针——练习
  • 算法 - 贪心算法
  • 计网学习笔记第3章 数据链路层层(灰灰题库)
  • 冷库设备远程监控物联网+省电节能解决方案
  • linux下实现System V消息队列实现任意结构体传输
  • 具身智能,正在翻越三座大山
  • 计算机毕业设计java疫情开放下的新冠信息共享平台 基于Java的社区疫情防控人员流动管理系统 疫情防控期间社区人员动态管理系统
  • 范数的定义、分类与 MATLAB 应用实践
  • 解决React白板应用中的画布内容丢失问题
  • 3363. 最多可收集的水果数目
  • 关键字 - 第二讲
  • Spring AI + Redis:构建高效AI应用缓存方案