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