MyBatis进阶(一)—映射

本文介绍MyBatis中的一对一和一对多关联查询方法,包括resultType与resultMap的使用,以及如何通过配置实现延迟加载,提升数据库查询效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一对一查询

resultType实现

Orders类中添加关联用户信息

public class Orders implements Serializable {
    private Integer id;

    private Integer userId;

    private String number;

    private Date createtime;

    private String note;

    //关联用户信息
    private User user;

    //省略getter和setter
}

xml中配置:

<!-- 一对一查询使用reusltType完成
        查询订单关联查询用户信息
     -->
     <select id="findOrderUserList" resultType="orderCustom">
        SELECT
            orders.*, USER .username,
            USER .sex
        FROM
            orders,
            USER
        WHERE
            orders.user_id = USER .id
     </select>

只要在查询的类中关联需要的信息即可。

resultMap实现

xml中配置:

<!-- 一对一查询resultMap 查询订单关联查询用户信息-->
    <resultMap type="orders" id="ordersUserResultMap">
        <id column="id" property="id"/>
        <result column="user_id" property="userId"/>
        <result column="number" property="number"/>
        <result column="createtime" property="createtime"/>
        <result column="note" property="note"/>

        <association property="user" javaType="user">
            <id column="user_id" property="id"/>
            <result column="username" property="username"/>
            <result column="sex" property="sex"/>
        </association>
    </resultMap>


<!-- 一对一查询使用reusltMap完成
        查询订单关联查询用户信息
     -->
     <select id="findOrderUserListResultMap" resultMap="ordersUserResultMap" >
          SELECT 
              orders.*,
              user.username,
              user.sex 
          FROM
              orders,
              USER 
          WHERE orders.user_id = user.id 
     </select>

association:用于对关联信息映射到单个pojo
property:要将关联信息映射到orders的哪个属性中
javaType:关联信息映射到orders的属性的类型,是user的类型

一对多查询

xml中配置

<!-- 一对多    查询订单、用户及订单明细 -->
    <resultMap type="orders" id="orderAndOrderDetails" extends="ordersUserResultMap">
        <collection property="orderdetails" ofType="cn.itcast.mybatis.po.Orderdetail">
            <id column="orderdetail_id" property="id"/>
            <result column="items_num" property="itemsNum"/>
            <result column="items_id" property="itemsId"/>
        </collection>
    </resultMap>

映射订单信息,和用户信息,这里使用继承ordersUserResultMap
映射订单明细信息
property:要将关联信息映射到orders的哪个属性中
ofType:集合中pojo的类型

复杂一对多

<!-- 一对多查询    查询用户及订单明细和商品信息 -->
    <resultMap type="user" id="userOrderDetailResultMap">
        <!-- 用户信息映射 -->
        <id column="user_id" property="id"/>
        <result column="username" property="username"/>
        <result column="sex" property="sex"/>
        <!-- 订单信息 -->
        <collection property="orderlist" ofType="cn.itcast.mybatis.po.Orders">
                <id column="id" property="id"/>
                <result column="user_id" property="userId"/>
                <result column="number" property="number"/>
                <result column="createtime" property="createtime"/>
                <result column="note" property="note"/>
                <!-- 订单明细映射 -->
                <collection property="orderdetails" ofType="cn.itcast.mybatis.po.Orderdetail">
                    <id column="orderdetail_id" property="id"/>
                    <result column="items_num" property="itemsNum"/>
                    <result column="items_id" property="itemsId"/>
                    <!-- 商品信息 -->
                    <association property="items" javaType="cn.itcast.mybatis.po.Items">
                        <id column="item_id" property="id"/>
                        <result column="items_name" property="name"/>
                        <result column="items_detail" property="detail"/>
                    </association>
                </collection>
        </collection>
    </resultMap>

延迟加载

配置mybatis支持延迟加载

<!-- 全局配置参数 -->
    <settings>
        <!-- 延迟加载总开关 -->
        <setting name="lazyLoadingEnabled" value="true" />  
        <!-- 设置按需加载 -->
        <setting name="aggressiveLazyLoading" value="false" />
    </settings>

一对一延迟加载

<!-- 一对一查询延迟加载 的配置 -->
    <resultMap type="orders" id="orderCustomLazyLoading">
        <!-- 完成了订单信息的映射配置 -->
        <!-- id:订单关联用户查询的唯 一 标识 -->
        <id column="id" property="id" />
        <result column="user_id" property="userId" />
        <result column="number" property="number" />
        <result column="createtime" property="createtime" />
        <result column="note" property="note" />

        <association property="user" select="cn.itcast.mybatis.mapper.UserMapper.findUserById" column="user_id">
        </association>
    </resultMap>

<!-- 一对一查询延迟加载    开始只查询订单,对用户信息进行延迟加载 -->
     <select id="findOrderUserListLazyLoading" resultMap="orderCustomLazyLoading">
         SELECT 
            orders.*
         FROM
            orders
     </select>

一对多延迟加载

一对多延迟加载的方法同一对一延迟加载,在collection标签中配置select内容。

resultType、resultMap、延迟加载使用场景总结

延迟加载:
延迟加载实现的方法多种多样,在只查询单表就可以满足需求,为了提高数据库查询性能使用延迟加载,再查询关联信息。

mybatis提供延迟加载的功能用于service层。

  • resultType:
    作用:
    将查询结果按照SQL列名POJO属性名一致性映射到POJO中。
    场合:
    常见一些明细记录的展示,将关联查询信息全部展示在页面时,此时可直接使用resultType将每一条记录映射到pojo中,在前端页面遍历list(list中是pojo)即可。

  • resultMap:
    使用association和collection完成一对一和一对多高级映射。
    association:
    作用:
    将关联查询信息映射到一个pojo类中。
    场合:
    为了方便获取关联信息可以使用association将关联订单映射为pojo,比如:查询订单及关联用户信息。
    collection:
    作用:
    将关联查询信息映射到一个list集合中。
    场合:
    为了方便获取关联信息可以使用collection将关联信息映射到list集合中,比如:查询用户权限范围模块和功能,可使用collection将模块和功能列表映射到list中。

### MyBatis 的高级用法与技巧 #### 1. 动态 SQL 动态 SQL 是 MyBatis 中非常强大的功能之,允许开发者根据条件构建灵活的 SQL 查询语句。通过 `<if>`、`<choose>`、`<when>` `<otherwise>` 等标签可以实现复杂的查询逻辑。 ```xml <select id="findActiveBlogWithTitleLike" resultType="Blog"> SELECT * FROM BLOG WHERE state = 1 <if test="title != null"> AND title like #{title} </if> </select> ``` 此方法能够显著减少硬编码 SQL 并提高代码可维护性[^3]。 #### 2. 缓存机制 MyBatis 提供了级缓存(Session 级别)二级缓存(Mapper 级别)。合理利用缓存可以有效降低数据库访问频率并提升性能。 - **级缓存**: 默认开启,在同个 SqlSession 范围内生效。 - **二级缓存**: 需要手动启用,并在 Mapper 文件中声明 `cache` 或者引入第三方缓存框架如 EhCache。 ```xml <mapper namespace="com.example.mapper.BlogMapper"> <!-- 启用二级缓存 --> <cache/> <select id="getBlogById" parameterType="int" resultType="Blog"> SELECT * FROM Blog WHERE id = #{id} </select> </mapper> ``` 注意:当启用了二级缓存时,应确保数据致性问题得到妥善处理[^3]。 #### 3. 插件开发 MyBatis 支持自定义插件来拦截执行链中的某些操作,比如日志记录、性能监控或者分页支持。官方推荐使用的 PageHelper 就是个典型的例子。 配置方式如下: ```xml <!--mybatis-config.xml 中添加插件 --> <plugins> <plugin interceptor="com.github.pagehelper.PageInterceptor"> <property name="helperDialect" value="mysql"/> </plugin> </plugins> ``` 此外还可以编写自己的插件类继承 `org.apache.ibatis.plugin.Interceptor` 接口完成特定需求[^3]。 #### 4. 结果映射复杂关系 对于存在关联表的情况,可以通过嵌套结果集的方式简化对象之间的映射过程。 假设有个博客及其作者的关系模型,则可以在 XML 映射文件里这样写: ```xml <resultMap id="blogResultMap" type="Blog"> <association property="author" javaType="Author"> <id column="author_id" property="id"/> <result column="username" property="name"/> </association> </resultMap> <select id="selectBlogWithAuthor" resultMap="blogResultMap"> SELECT b.*, a.id AS author_id, a.username FROM blog b LEFT JOIN author a ON b.author_id = a.id </select> ``` 这种方法使得即使面对多层嵌套的数据结构也变得清晰易懂。 #### 5. 使用注解替代XML 如果不喜欢基于 XML 的配置风格,也可以采用纯 Java 注解的方式来定义SQL语句。这种方式更加紧凑直观但可能牺牲部分灵活性。 例如下面这段代码实现了同样的效果: ```java @Select("SELECT * FROM users WHERE username=#{username}") User findUserByUsername(@Param("username") String userName); ``` 不过需要注意的是并非所有的特性都能完全由注解决定,因此实际项目中通常会混合使用两者。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值