Mybatis——一对一映射

 一对一映射

预置条件

在某网络购物系统中,一个用户只能拥有一个购物车,用户与购物车的关系可以设计为一对一关系

数据库表结构(唯一外键关联) 

 

创建两个实体类和映射接口 

 

package org.example.demo;

import lombok.Data;

import java.util.List;

@Data
public class User {
    private Integer userId;
    private String userName;
    private String password;
    private Cart cart;
    private List<Order> orderList;
}
package org.example.demo;

import lombok.Data;

@Data
public class Cart {
    private Integer cartId;
    private double price;
}
实现根据用户id查询出所有用户信息,包括该用户的购物车信息 
package org.example.mapper;

import org.example.demo.User;

import java.util.List;

public interface UserMapper {

    User findUserAndCartByUserId(Integer userId);
}
 MyBatis中处理一对一关联关系的方法有四种
使用自动映射处理一对一关系

使用自动映射处理一对一关系,也就是通过别名自动将值匹配到对应的字段上 

<?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="org.example.mapper.UserMapper">
    <select id="findUserAndCartByUserId" resultType="com.mybatis.entity.User">
        select
            *
        from t_user u
        inner join t_cart c on u.user_id = c.user_id
        where u.user_id = #{userId};
    </select>
</mapper>

复杂的属性映射时,可以多层嵌套,比如将cart表中的cart_id字段映射到Cart.id属性上 

使用resultMap配置一对一映射

使用这种方式同自动映射方式相似之处为,Cart中的属性配置部分使用了”Cart.”前缀

<?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="org.example.mapper.UserMapper"> 
    <resultMap id="userMap" type="org.example.demo.User">
        <id property="userId" column="user_id"/>
        <result property="userName" column="user_name"/>
        <result property="password" column="password"/>
        <result property="cart.cartId" column="cart_id"/>
        <result property="cart.price" column="price"/>
    </resultMap>   
    <select id="findUserAndCartByUserId" resultMap="userMap">
        select
            *
        from t_user u
        inner join t_cart c on u.user_id = c.user_id
        where u.user_id = #{userId};
    </select>
</mapper>
使用association元素配置一对一映射

association元素用于和一个复杂的类型进行关联

association元素包含以下属性

property:对应实体类中的属性名,必填项

javaType:属性对应的java类型,可选项

resultMap:可以直接使用现有的resultMap,而不需要在这里配置,可选项

    <resultMap id="userMap" type="org.example.demo.User">
        <id property="userId" column="user_id"/>
        <result property="userName" column="user_name"/>
        <result property="password" column="password"/>
        <association property="cart">
            <id property="cartId" column="cart_id"/>
            <result property="price" column="price"/>
        </association>
    </resultMap>
    <select id="selectUserById" resultMap="userMap">
        select * from t_user where user_id = #{userId};
    </select>
association元素的嵌套查询

association元素的嵌套查询常用的属性如下

select:另一个查询映射的statement id,MyBatis会额外执行这个查询获取嵌套对象

column:列名,将主查询中列的结果作为嵌套查询的参数,column=“{prop1=col1,prop2=col2}”,其中prop1和prop2将作为嵌套查询的参数

fetchType:数据加载方式,可选值为lazy和eager,分别为延迟加载和积极加载,会覆盖全局的lazyLoadingEnable配置

    <resultMap id="userMap" type="org.example.demo.User">
        <id property="userId" column="user_id"/>
        <result property="userName" column="user_name"/>
        <result property="password" column="password"/>
        <association property="cart" column="user_id" select="findCartbyUserId"
        fetchType="lazy"/>
    </resultMap>

    <resultMap id="cartMap" type="org.example.demo.Cart">
        <id property="cartId" column="cart_id"/>
        <result property="price" column="price"/>
    </resultMap>
    
    <select id="findUserAndCartByUserId" resultMap="userMap">
        select * from t_suer u where user_id = #{user_id};
    </select>
    <select id="findCartbyUserId" resultMap="cartMap">
        select * from t_cart c where c.user_id = #{user_id};
    </select>

嵌套查询会多执行SQL,当查询N条数据时,就会出现N+1次查询问题

为了解决N+1次查询问题,可以设置延迟加载策略,将association元素的fetchType属性设置为lazy 

设置为延迟加载的对象,默认情况下,当调用该对象的equals、hashCode、toString、clone方法时,就会加载该对象的全部数据

对比四种方式

前面的三种方式都属于“关联的嵌套结果映射“,即通过一次SQL查询根据表或指定的属性映射到不同的对象中

最后一种方式属于“关联的嵌套查询”,利用简单的SQL语句,通过多次查询得到想要的结果,可实现延迟加载效果

 

 

 

相关推荐

  1. MyBatis输出映射

    2024-04-03 08:00:02       15 阅读
  2. mybatis一对一,一对多,字段重复

    2024-04-03 08:00:02       12 阅读
  3. Mybatis配置-映射器(mappers)

    2024-04-03 08:00:02       37 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-03 08:00:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-03 08:00:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-03 08:00:02       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-03 08:00:02       20 阅读

热门阅读

  1. OCRmyPDF:全能PDF光学字符识别工具及其Python集成

    2024-04-03 08:00:02       9 阅读
  2. Docker in Docker原理与实战

    2024-04-03 08:00:02       9 阅读
  3. 第四章:Minikube生命周期管理命令

    2024-04-03 08:00:02       11 阅读
  4. springboot + mybatis支持多数据库

    2024-04-03 08:00:02       14 阅读
  5. 【Python进阶(五)】——模块搜索及工作目录

    2024-04-03 08:00:02       12 阅读
  6. Quill文档(四):使用Parchment克隆Medium

    2024-04-03 08:00:02       11 阅读
  7. 如何在 Ubuntu 12.04 上添加交换空间

    2024-04-03 08:00:02       12 阅读
  8. 抖音小程序中跳转页面怎么写?

    2024-04-03 08:00:02       20 阅读