MyBatis 的多对一,一对多以及多对多的增删改查的xml映射语句

1. 多对一(Many-to-One)

表结构
  • users

    • id (INT, 主键)
    • username (VARCHAR)
    • password (VARCHAR)
    • email (VARCHAR)
    • department_id (INT, 外键)
    • created_at (TIMESTAMP)
  • departments

    • id (INT, 主键)
    • name (VARCHAR)
    • created_at (TIMESTAMP)
实体类
public class User {
    private int id;
    private String username;
    private String password;
    private String email;
    private Department department;
    private Timestamp createdAt;

    // Getters and Setters
}

public class Department {
    private int id;
    private String name;
    private Timestamp createdAt;

    // Getters and Setters
}
映射文件 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">

  <!-- 插入用户 -->
  <insert id="insertUser" parameterType="com.example.entity.User">
    INSERT INTO users (username, password, email, department_id, created_at) 
    VALUES (#{username}, #{password}, #{email}, #{department.id}, NOW())
  </insert>

  <!-- 更新用户信息 -->
  <update id="updateUser" parameterType="com.example.entity.User">
    UPDATE users 
    SET username = #{username}, 
        password = #{password}, 
        email = #{email}, 
        department_id = #{department.id} 
    WHERE id = #{id}
  </update>

  <!-- 删除用户 -->
  <delete id="deleteUser" parameterType="int">
    DELETE FROM users WHERE id = #{id}
  </delete>

  <!-- 根据ID查询用户及其部门 -->
  <select id="selectUserByIdWithDepartment" resultMap="UserAndDepartmentResultMap">
    SELECT u.*, d.id AS departmentId, d.name, d.created_at AS departmentCreatedAt
    FROM users u
    LEFT JOIN departments d ON u.department_id = d.id
    WHERE u.id = #{id}
  </select>
  <!-- 在 MyBatis 中,parameterType 是可选的。如果你只有一个参数传递给 SQL 语句,MyBatis 会自动推断参数类型。因此,即使不显式指定 parameterType,MyBatis 也能正确处理参数。 -->
  <!-- 查询所有用户及其部门 -->
  <select id="selectAllUsersWithDepartment" resultMap="UserAndDepartmentResultMap">
    SELECT u.*, d.id AS departmentId, d.name, d.created_at AS departmentCreatedAt
    FROM users u
    LEFT JOIN departments d ON u.department_id = d.id
  </select>

  <!-- 嵌套结果映射 -->
  <resultMap id="UserAndDepartmentResultMap" type="com.example.entity.User">
    <id property="id" column="id"/>
    <result property="username" column="username"/>
    <result property="password" column="password"/>
    <result property="email" column="email"/>
    <result property="createdAt" column="created_at"/>
    <association property="department" javaType="com.example.entity.Department">
      <id property="id" column="departmentId"/>
      <result property="name" column="name"/>
      <result property="createdAt" column="departmentCreatedAt"/>
    </association>
  </resultMap>

</mapper>

详细解释

    多对一(Many-to-One)
  • insertUser:插入用户信息。department_id 是外键,指向 departments 表的 id
  • updateUser:更新用户信息。department_id 可以更改。
  • deleteUser:删除用户。
  • selectUserByIdWithDepartment:根据用户ID查询用户及其部门。使用 LEFT JOIN 将 users 表和 departments 表连接起来。
  • selectAllUsersWithDepartment:查询所有用户及其部门。
  • resultMap:定义了 User 对象及其 department 属性的映射关系。使用 <association> 标签来映射单个对象。

2. 一对多(One-to-Many)

表结构
  • users

    • id (INT, 主键)
    • username (VARCHAR)
    • password (VARCHAR)
    • email (VARCHAR)
    • created_at (TIMESTAMP)
  • orders

    • id (INT, 主键)
    • user_id (INT, 外键)
    • product_name (VARCHAR)
    • quantity (INT)
    • price (DECIMAL)
    • created_at (TIMESTAMP)
实体类
public class User {
    private int id;
    private String username;
    private String password;
    private String email;
    private Timestamp createdAt;
    private List<Order> orders;

    // Getters and Setters
}

public class Order {
    private int id;
    private int userId;
    private String productName;
    private int quantity;
    private BigDecimal price;
    private Timestamp createdAt;

    // Getters and Setters
}
映射文件 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">

  <!-- 插入用户 -->
  <insert id="insertUser" parameterType="com.example.entity.User">
    INSERT INTO users (username, password, email, created_at) 
    VALUES (#{username}, #{password}, #{email}, NOW())
  </insert>

  <!-- 插入订单 -->
  <insert id="insertOrder" parameterType="com.example.entity.Order">
    INSERT INTO orders (user_id, product_name, quantity, price, created_at) 
    VALUES (#{userId}, #{productName}, #{quantity}, #{price}, NOW())
  </insert>

  <!-- 更新用户信息 -->
  <update id="updateUser" parameterType="com.example.entity.User">
    UPDATE users 
    SET username = #{username}, 
        password = #{password}, 
        email = #{email} 
    WHERE id = #{id}
  </update>

  <!-- 更新订单信息 -->
  <update id="updateOrder" parameterType="com.example.entity.Order">
    UPDATE orders 
    SET product_name = #{productName}, 
        quantity = #{quantity}, 
        price = #{price} 
    WHERE id = #{id}
  </update>

  <!-- 删除用户 -->
  <delete id="deleteUser" parameterType="int">
    DELETE FROM users WHERE id = #{id}
  </delete>

  <!-- 删除订单 -->
  <delete id="deleteOrder" parameterType="int">
    DELETE FROM orders WHERE id = #{id}
  </delete>
  <!-- 在 MyBatis 中,parameterType 是可选的。如果你只有一个参数传递给 SQL 语句,MyBatis 会自动推断参数类型。因此,即使不显式指定 parameterType,MyBatis 也能正确处理参数。 -->
  <!-- 根据ID查询用户及其订单 -->
  <select id="selectUserByIdWithOrders" resultMap="UserAndOrdersResultMap">
    SELECT u.*, o.id AS orderId, o.product_name, o.quantity, o.price, o.created_at AS orderCreatedAt
    FROM users u
    LEFT JOIN orders o ON u.id = o.user_id
    WHERE u.id = #{id}
  </select>

  <!-- 查询所有用户及其订单 -->
  <select id="selectAllUsersWithOrders" resultMap="UserAndOrdersResultMap">
    SELECT u.*, o.id AS orderId, o.product_name, o.quantity, o.price, o.created_at AS orderCreatedAt
    FROM users u
    LEFT JOIN orders o ON u.id = o.user_id
  </select>

  <!-- 嵌套结果映射 -->
  <resultMap id="UserAndOrdersResultMap" type="com.example.entity.User">
    <id property="id" column="id"/>
    <result property="username" column="username"/>
    <result property="password" column="password"/>
    <result property="email" column="email"/>
    <result property="createdAt" column="created_at"/>
    <collection property="orders" ofType="com.example.entity.Order">
      <id property="id" column="orderId"/>
      <result property="userId" column="id"/>
      <result property="productName" column="product_name"/>
      <result property="quantity" column="quantity"/>
      <result property="price" column="price"/>
      <result property="createdAt" column="orderCreatedAt"/>
    </collection>
  </resultMap>

</mapper>

详细解释

    一对多(One-to-Many)
  • insertUser:插入用户信息。
  • insertOrder:插入订单信息。user_id 是外键,指向 users 表的 id
  • updateUser:更新用户信息。
  • updateOrder:更新订单信息。
  • deleteUser:删除用户。
  • deleteOrder:删除订单。
  • selectUserByIdWithOrders:根据用户ID查询用户及其订单。使用 LEFT JOIN 将 users 表和 orders 表连接起来。
  • selectAllUsersWithOrders:查询所有用户及其订单。
  • resultMap:定义了 User 对象及其 orders 列表的映射关系。使用 <collection> 标签来映射集合属性。

3. 多对多(Many-to-Many)

表结构
  • users

    • id (INT, 主键)
    • username (VARCHAR)
    • password (VARCHAR)
    • email (VARCHAR)
    • created_at (TIMESTAMP)
  • roles

    • id (INT, 主键)
    • name (VARCHAR)
    • created_at (TIMESTAMP)
  • user_roles

    • user_id (INT, 外键)
    • role_id (INT, 外键)
实体类
public class User {
    private int id;
    private String username;
    private String password;
    private String email;
    private Timestamp createdAt;
    private List<Role> roles;

    // Getters and Setters
}

public class Role {
    private int id;
    private String name;
    private Timestamp createdAt;

    // Getters and Setters
}
映射文件 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">

  <!-- 插入用户 -->
  <insert id="insertUser" parameterType="com.example.entity.User">
    INSERT INTO users (username, password, email, created_at) 
    VALUES (#{username}, #{password}, #{email}, NOW())
  </insert>

  <!-- 插入角色 -->
  <insert id="insertRole" parameterType="com.example.entity.Role">
    INSERT INTO roles (name, created_at) 
    VALUES (#{name}, NOW())
  </insert>

  <!-- 插入用户角色关系 -->
  <insert id="insertUserRole" parameterType="map">
    INSERT INTO user_roles (user_id, role_id) 
    VALUES (#{userId}, #{roleId})
  </insert>

  <!-- 更新用户信息 -->
  <update id="updateUser" parameterType="com.example.entity.User">
    UPDATE users 
    SET username = #{username}, 
        password = #{password}, 
        email = #{email} 
    WHERE id = #{id}
  </update>

  <!-- 更新角色信息 -->
  <update id="updateRole" parameterType="com.example.entity.Role">
    UPDATE roles 
    SET name = #{name} 
    WHERE id = #{id}
  </update>

  <!-- 删除用户 -->
  <delete id="deleteUser" parameterType="int">
    DELETE FROM users WHERE id = #{id}
  </delete>

  <!-- 删除角色 -->
  <delete id="deleteRole" parameterType="int">
    DELETE FROM roles WHERE id = #{id}
  </delete>

  <!-- 删除用户角色关系 -->
  <delete id="deleteUserRole" parameterType="map">
    DELETE FROM user_roles 
    WHERE user_id = #{userId} 
      AND role_id = #{roleId}
  </delete>
  <!-- 在 MyBatis 中,parameterType 是可选的。如果你只有一个参数传递给 SQL 语句,MyBatis 会自动推断参数类型。因此,即使不显式指定 parameterType,MyBatis 也能正确处理参数。 -->
  <!-- 根据ID查询用户及其角色 -->
  <select id="selectUserByIdWithRoles" resultMap="UserAndRolesResultMap">
    SELECT u.*, r.id AS roleId, r.name, r.created_at AS roleCreatedAt
    FROM users u
    LEFT JOIN user_roles ur ON u.id = ur.user_id
    LEFT JOIN roles r ON ur.role_id = r.id
    WHERE u.id = #{id}
  </select>

  <!-- 查询所有用户及其角色 -->
  <select id="selectAllUsersWithRoles" resultMap="UserAndRolesResultMap">
    SELECT u.*, r.id AS roleId, r.name, r.created_at AS roleCreatedAt
    FROM users u
    LEFT JOIN user_roles ur ON u.id = ur.user_id
    LEFT JOIN roles r ON ur.role_id = r.id
  </select>

  <!-- 嵌套结果映射 -->
  <resultMap id="UserAndRolesResultMap" type="com.example.entity.User">
    <id property="id" column="id"/>
    <result property="username" column="username"/>
    <result property="password" column="password"/>
    <result property="email" column="email"/>
    <result property="createdAt" column="created_at"/>
    <collection property="roles" ofType="com.example.entity.Role">
      <id property="id" column="roleId"/>
      <result property="name" column="name"/>
      <result property="createdAt" column="roleCreatedAt"/>
    </collection>
  </resultMap>

</mapper>

详细解释

    多对多(Many-to-Many)
  • insertUser:插入用户信息。
  • insertRole:插入角色信息。
  • insertUserRole:插入用户角色关系。user_id 和 role_id 分别是外键,指向 users 表和 roles 表的 id
  • updateUser:更新用户信息。
  • updateRole:更新角色信息。
  • deleteUser:删除用户。
  • deleteRole:删除角色。
  • deleteUserRole:删除用户角色关系。
  • selectUserByIdWithRoles:根据用户ID查询用户及其角色。使用 LEFT JOIN 将 users 表、user_roles 表和 roles 表连接起来。
  • selectAllUsersWithRoles:查询所有用户及其角色。
  • resultMap:定义了 User 对象及其 roles 列表的映射关系。使用 <collection> 标签来映射集合属性。

配置文件

要使上述映射文件生效,你需要在 MyBatis 的配置文件(如 mybatis-config.xml)中引用它:

<configuration>
  <mappers>
    <mapper resource="mappers/UserMapper.xml"/>
  </mappers>
</configuration>

接口定义

UserMapper.java 接口中定义相应的方法:

package com.example.mapper;

import com.example.entity.User;
import com.example.entity.Role;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.util.List;
import java.util.Map;

@Mapper
public interface UserMapper {

  void insertUser(User user);
  void insertRole(Role role);
  void insertUserRole(@Param("userId") int userId, @Param("roleId") int roleId);

  void updateUser(User user);
  void updateRole(Role role);

  void deleteUser(int id);
  void deleteRole(int id);
  void deleteUserRole(@Param("userId") int userId, @Param("roleId") int roleId);

  User selectUserByIdWithDepartment(int id);
  List<User> selectAllUsersWithDepartment();

  User selectUserByIdWithOrders(int id);
  List<User> selectAllUsersWithOrders();

  User selectUserByIdWithRoles(int id);
  List<User> selectAllUsersWithRoles();
}

示例调用

在你的服务层或控制器中,可以通过 UserMapper 接口调用这些方法:

@Autowired
private UserMapper userMapper;

public void createUserAndRole() {
  User user = new User();
  user.setUsername("john_doe");
  user.setPassword("secret");
  user.setEmail("john@example.com");
  userMapper.insertUser(user);

  Role role = new Role();
  role.setName("Admin");
  userMapper.insertRole(role);

  userMapper.insertUserRole(user.getId(), role.getId());
}

public List<User> getUsersWithRoles() {
  return userMapper.selectAllUsersWithRoles();
}

注意事项:

         在 MyBatis 中,resultMapresultType 是两种不同的方式,用于将数据库查询结果映射到 Java 对象。

          resultType 是一个简单的属性,用于指定查询结果应该映射到的 Java 对象类型。MyBatis 会自动将查询结果的每一列映射到 Java 对象的属性上,前提是列名和属性名一致(或者通过别名匹配)。

           resultMap 是一个更强大的映射工具,用于定义如何将数据库查询结果映射到 Java 对象。它允许你定义复杂的映射逻辑,包括嵌套对象、集合、自定义映射规则等。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

H.265流媒体播放器EasyPlayer.js播放器提示MSE不支持H.265解码可能的原因

随着人工智能和机器学习技术的应用&#xff0c;流媒体播放器将变得更加智能&#xff0c;能够根据用户行为和偏好提供个性化的内容推荐。总体而言&#xff0c;流媒体播放器的未来发展将更加注重技术创新和用户互动&#xff0c;以适应不断变化的市场需求和技术进步。 提示MSE不支…

MySQL原理简介—6.简单的生产优化案例

大纲 1.MySQL日志的顺序写和数据文件的随机读指标 2.Linux存储系统软件层原理及IO调度优化原理 3.数据库服务器使用的RAID存储架构介绍 4.数据库Too many connections故障定位 1.MySQL日志的顺序写和数据文件的随机读指标 (1)磁盘随机读操作 (2)磁盘顺序写操作 (1)磁盘随…

svn 崩溃、 cleanup失败 怎么办

在使用svn的过程中&#xff0c;可能出现整个svn崩溃&#xff0c; 例如cleanup 失败的情况&#xff0c;类似于 这时可以下载本贴资源文件并解压。 或者直接访问网站 SQLite Download Page 进行下载 解压后得到 sqlite3.exe 放到发生问题的svn根目录的.svn路径下 右键呼出pow…

前后端分离,解决vue+axios跨域和proxyTable不生效等问题

看到我这篇文章前可能你以前看过很多类似的文章。至少我是这样的&#xff0c;因为一直没有很好的解决问题。 正文 当我们通过webstorm等IDE开发工具启动项目的时候&#xff0c;通过命令控制台可以观察到启动项目的命令 如下&#xff1a; webpack-dev-server --inline --prog…

在win10环境部署opengauss数据库(包含各种可能遇到的问题解决)

适用于windows环境下通过docker desktop实现opengauss部署&#xff0c;请审题。 文章目录 前言一、部署适合deskdocker的环境二、安装opengauss数据库1.配置docker镜像源2.拉取镜像源 总结 前言 注意事项&#xff1a;后面docker拉取镜像源最好电脑有科学上网工具如果没有科学上…

Java开发经验——Spring Test 常见错误

摘要 本文详细介绍了Java开发中Spring Test的常见错误和解决方案。文章首先概述了Spring中进行单元测试的多种方法&#xff0c;包括使用JUnit和Spring Boot Test进行集成测试&#xff0c;以及Mockito进行单元测试。接着&#xff0c;文章分析了Spring资源文件扫描不到的问题&am…

2024年亚太地区数学建模大赛D题-探索量子加速人工智能的前沿领域

量子计算在解决复杂问题和处理大规模数据集方面具有巨大的潜力&#xff0c;远远超过了经典计算机的能力。当与人工智能&#xff08;AI&#xff09;集成时&#xff0c;量子计算可以带来革命性的突破。它的并行处理能力能够在更短的时间内解决更复杂的问题&#xff0c;这对优化和…

基于 RBF 神经网络整定的 PID 控制

基于 RBF 神经网络整定的 PID 控制 是结合了传统 PID 控制和 RBF&#xff08;径向基函数&#xff09;神经网络的自适应控制方法。在这种方法中&#xff0c;RBF 神经网络用于自适应地调整 PID 控制器的增益&#xff08;比例增益 KpK_pKp​&#xff0c;积分增益 KiK_iKi​ 和微分…

空间注意力网络的性能优化与多维评估

在本文中&#xff0c;首先分析空间注意力网络&#xff08;Spatial Attention Neural Network&#xff09;在五个不同数据集上的训练结果。这些数据集包括Daily_and_Sports_Activities、WISDM、UCI-HAR、PAMAP2和OPPORTUNITY。通过对比这些结果&#xff0c;我们可以深入理解空间…

Linux——1_系统的延迟任务及定时任务

系统的延迟任务及定时任务 在系统中我们的维护工作大多数时在服务器行对闲置时进行 我们需要用延迟任务来解决自动进行的一次性的维护 延迟任务时一次性的&#xff0c;不会重复执行 当延迟任务产生输出后&#xff0c;这些输出会以邮件的形式发送给延迟任务发起者 在RHEL9中…

【数据结构】—— 线索二叉树

引入 我们现在提倡节约型杜会&#xff0c; 一切都应该节约为本。对待我们的程序当然也不例外&#xff0c;能不浪费的时间或空间&#xff0c;都应该考虑节省。我们再观察团下图的二叉树&#xff08;链式存储结构)&#xff0c;会发现指针域并不是都充分的利用了&#xff0c;有许…

NVR管理平台EasyNVR多个NVR同时管理:全方位安防监控视频融合云平台方案

EasyNVR是基于端-边-云一体化架构的安防监控视频融合云平台&#xff0c;具有简单轻量的部署方式与多样的功能&#xff0c;支持多种协议&#xff08;如GB28181、RTSP、Onvif、RTMP&#xff09;和设备类型&#xff08;IPC、NVR等&#xff09;&#xff0c;提供视频直播、录像、回放…

虚幻引擎---初识篇

一、学习途径 虚幻引擎官方文档&#xff1a;https://dev.epicgames.com/documentation/zh-cn/unreal-engine/unreal-engine-5-5-documentation虚幻引擎在线学习平台&#xff1a;https://dev.epicgames.com/community/unreal-engine/learning哔哩哔哩&#xff1a;https://www.b…

汽车HiL测试:利用TS-GNSS模拟器掌握硬件性能的仿真艺术

一、汽车HiL测试的概念 硬件在环&#xff08;Hardware-in-the-Loop&#xff0c;简称HiL&#xff09;仿真测试&#xff0c;是模型基于设计&#xff08;Model-Based Design&#xff0c;简称MBD&#xff09;验证流程中的一个关键环节。该步骤至关重要&#xff0c;因为它整合了实际…

C++编程库与框架实战——sqlite3数据库

一,SQLite数据库简介 SQLite是可以实现类似于关系型数据库中各种操作的事务性SQL数据库引擎。 SQLite可以为应用程序提供存储于本地的嵌入式数据库,帮助应用程序实现轻量级的数据存储。 SQLite是一个库文件,并不是单独的进程,它可以静态或动态链接到C++应用程序中,然后…

STM32F10x 定时器

使用定时器实现&#xff1a;B5 E5的开关 添加相关的.h路径文件 添加相关的.c配置文件 led.h文件 用于声明LED函数 #ifndef __LED_H //没有定义__LED_H #define __LED_H //就定义__LED_H #define LED1_ON GPIO_ResetBits(GPIOB,GPIO_Pin_5) #defi…

PyQt6+pyqtgraph折线图绘制显示

1、实现效果 2、环境&#xff1a; 确认已经安装pyqtgraph的模块&#xff0c;如果没有安装&#xff0c;使用命令安装&#xff1a; pip install pyqtgraph 3、代码实现&#xff1a; 绘制折线函数&#xff1a; import sys import random from PySide6.QtWidgets import QAppl…

Linux---ps命令

​​​​​​Linux ps 命令 | 菜鸟教程 (runoob.com) process status 用于显示进程的状态 USER: 用户名&#xff0c;运行此进程的用户名。PID: 进程ID&#xff08;Process ID&#xff09;&#xff0c;每个进程的唯一标识号%CPU: 进程当前使用的CPU百分比%MEM: 进程当前使用的…

高新技术行业中的知识管理:关键性、挑战、策略及工具应用

知识管理的关键性 在瞬息万变的信息时代&#xff0c;知识已成为高新技术行业的核心竞争要素。知识管理&#xff0c;这一旨在高效组织、整合并应用企业内外部知识资源的管理策略&#xff0c;对于推动高新技术企业的持续创新与发展至关重要。它不仅能够激发研发团队的创造力&…

IDEA 2024安装指南(含安装包以及使用说明 cannot collect jvm options 问题 四)

汉化 setting 中选择插件 完成 安装出现问题 1.可能是因为之前下载过的idea&#xff0c;找到连接中 文件&#xff0c;卸载即可。