高级java每日一道面试题-2025年01月25日-框架篇[Mybatis篇]-MyBatis实现一对一有几种方式?具体怎么操作的?

如果有遗漏,评论区告诉我进行补充

面试官: MyBatis实现一对一有几种方式?具体怎么操作的?

我回答:

1. 使用XML配置文件实现一对一关系

主表和从表的设计

假设我们有两个实体:PersonAddress,其中 Person 表包含一个 address_id 字段,指向 Address 表的主键。

CREATE TABLE Address (
    id INT PRIMARY KEY,
    street VARCHAR(255),
    city VARCHAR(255)
);

CREATE TABLE Person (
    id INT PRIMARY KEY,
    name VARCHAR(255),
    address_id INT,
    FOREIGN KEY (address_id) REFERENCES Address(id)
);
创建实体类
public class Address {
    private Integer id;
    private String street;
    private String city;
    // getters and setters
}

public class Person {
    private Integer id;
    private String name;
    private Address address;
    // getters and setters
}
编写Mapper XML文件

在XML配置文件中,使用 标签来定义一对一的关系。

<mapper namespace="com.example.mapper.PersonMapper">
    <resultMap id="PersonResultMap" type="Person">
        <id property="id" column="id" />
        <result property="name" column="name" />
        
        <association property="address" column="address_id" 
            javaType="Address" 
            select="selectAddressById" />
    resultMap>

    <select id="selectPersonById" resultMap="PersonResultMap" parameterType="int">
        SELECT * FROM Person WHERE id = #{id}
    select>

    <select id="selectAddressById" resultType="Address" parameterType="int">
        SELECT * FROM Address WHERE id = #{id}
    select>
mapper>

这里, 标签通过 select 属性指定一个子查询方法 selectAddressById 来加载关联的 Address 对象。

2. 使用注解实现一对一关系

创建实体类并使用注解
import org.apache.ibatis.annotations.*;

public class Address {
    private Integer id;
    private String street;
    private String city;
    // getters and setters
}

public interface AddressMapper {
    @Select("SELECT * FROM Address WHERE id = #{id}")
    @Results({
        @Result(property = "id", column = "id"),
        @Result(property = "street", column = "street"),
        @Result(property = "city", column = "city")
    })
    Address selectAddressById(Integer id);
}

public class Person {
    private Integer id;
    private String name;
    private Address address;
    // getters and setters
}

@Mapper
public interface PersonMapper {
    @Select("SELECT * FROM Person WHERE id = #{id}")
    @Results({
        @Result(property = "id", column = "id"),
        @Result(property = "name", column = "name"),
        @Result(property = "address", column = "address_id", one = @One(select = "selectAddressById"))
    })
    Person selectPersonById(Integer id);
}

在这个例子中,@One 注解用于映射一对一的关系,通过 select 属性指定一个子查询方法 selectAddressById 来根据 address_id 加载相关的 Address 对象。

注意事项

  • 延迟加载(Lazy Loading):可以通过设置 fetchType=FetchType.LAZY 来启用延迟加载,这意味着只有在访问关联对象的属性时才会执行子查询。

  • 缓存:对于频繁访问的数据,可以考虑使用 MyBatis 的缓存机制来提高性能。

  • 事务管理:确保数据库操作在适当的事务管理下进行,以避免数据不一致问题。

通过上述两种方式——XML配置和注解配置——可以根据项目需求和个人偏好灵活地实现一对一关系映射。每种方法都有其适用场景,理解它们的区别有助于更好地设计持久层架构。无论是选择XML还是注解的方式,都需要注意细节如延迟加载、缓存策略以及事务管理等,以保证应用的最佳性能和稳定性。

你可能感兴趣的:(java每日一道面试题,java,mybatis,association标签,事务管理)