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

embedded/2024/11/25 16:08:16/

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 mapperPUBLIC "-//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 departmentCreatedAtFROM users uLEFT JOIN departments d ON u.department_id = d.idWHERE 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 departmentCreatedAtFROM users uLEFT 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 mapperPUBLIC "-//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 orderCreatedAtFROM users uLEFT JOIN orders o ON u.id = o.user_idWHERE 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 orderCreatedAtFROM users uLEFT 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 mapperPUBLIC "-//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 roleCreatedAtFROM users uLEFT JOIN user_roles ur ON u.id = ur.user_idLEFT JOIN roles r ON ur.role_id = r.idWHERE u.id = #{id}</select><!-- 查询所有用户及其角色 --><select id="selectAllUsersWithRoles" resultMap="UserAndRolesResultMap">SELECT u.*, r.id AS roleId, r.name, r.created_at AS roleCreatedAtFROM users uLEFT JOIN user_roles ur ON u.id = ur.user_idLEFT 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 对象。它允许你定义复杂的映射逻辑,包括嵌套对象、集合、自定义映射规则等。


http://www.ppmy.cn/embedded/140421.html

相关文章

使用Python 在Excel中创建和取消数据分组 - 详解

目录 使用工具 Python在Excel中创建行和列分组 Python在Excel中创建嵌套分组 Python获取Excel中的行和列的大纲级别 Python展开或折叠Excel中的分组 Python在Excel中创建分类汇总 Python取消Excel中的行和列分组 Excel中的分组是一种通过添加层级结构将相邻行或列组织在…

使用线程局部存储解决ffmpeg中多实例调用下自定义日志回调问题

1 问题描述 最近在封装一个库&#xff0c;调用方传入一个URL及对应的回调后就开始执行ffmpeg拉流硬解码硬件格式转换&#xff0c;并将得到的数据帧通过回调传递给调用方&#xff1b;除了数据帧回调外&#xff0c;还有日志回调用来传递一些调试信息。 因为该封装库可能被一个进…

Elasticsearch面试内容整理-高级特性

Elasticsearch 提供了一系列高级特性,这些特性可以极大地增强其搜索、分析和管理能力,使得它在大数据场景中表现出色。以下是 Elasticsearch 的一些重要高级特性: 近实时搜索(Near Real-Time Search) Elasticsearch 的一个关键特性是 近实时搜索(NRT),这意味着数据写入…

Java 8 常用特性 (JDK1.8)

Oracle 于 2014 发布了 Java8&#xff08;jdk1.8&#xff09;&#xff0c;诸多原因使它成为目前市场上使用最多的 jdk 版本。虽然发布距今已将近 7 年&#xff0c;但很多程序员对其新特性还是不够了解 为了不脱离队伍太远&#xff0c;还是有必要对这些新特性做一些总结梳理。它…

Jdk1.8新特性

新增的类以及常用的方法 在Java的java.util.concurrent包中&#xff0c;除了之前提到的并发工具类外&#xff0c;还有一些新增的类以及它们常用的方法。以下是一些例子&#xff1a; 新增的类 ‌CompletableFuture‌&#xff1a; CompletableFuture是Java 8中引入的一个类&a…

SQL递归查询树结构语法

对于树形结构数据&#xff0c;经常会有递归查询的需求&#xff0c;语法如下&#xff1a; 注意替换sql中的表名和id入参 mysql WITH RECURSIVE node_cte (id, parent_id) AS (SELECT id, parent_id FROM my_table -- 表名&#xff0c;换成要查询的名称WHERE id :id -- 根节点…

二分法(折半法)查找【有动图】

二分法&#xff0c;也叫做折半法&#xff0c;就是一种通过有序表的中间元素与目标元素进行对比&#xff0c;根据大小关系排除一半元素&#xff0c;然后继续在剩余的一半中进行查找&#xff0c;重复这个过程直至找到目标值或者确定目标值不存在。 我们从结论往回推&#xff0c;…

Java中的关键字 native

Java中的关键字 native 在Java中&#xff0c;native 关键字用于声明本地方法&#xff0c;即由非Java语言&#xff08;如C、C&#xff09;编写的方法。这些本地方法可以通过Java调用&#xff0c;以便访问底层操作系统、硬件资源或遗留代码库。使用 native 关键字的主要目的是让…