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 中,resultMap
和 resultType
是两种不同的方式,用于将数据库查询结果映射到 Java 对象。
resultType
是一个简单的属性,用于指定查询结果应该映射到的 Java 对象类型。MyBatis 会自动将查询结果的每一列映射到 Java 对象的属性上,前提是列名和属性名一致(或者通过别名匹配)。
resultMap
是一个更强大的映射工具,用于定义如何将数据库查询结果映射到 Java 对象。它允许你定义复杂的映射逻辑,包括嵌套对象、集合、自定义映射规则等。