Mybatis之关联

这篇具有很好参考价值的文章主要介绍了Mybatis之关联。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、一对多关联

eg:一个用户对应多个订单

建表语句

CREATE TABLE `t_customer` (
	 `customer_id` INT NOT NULL AUTO_INCREMENT, 
	 `customer_name` CHAR(100), 
	 PRIMARY KEY (`customer_id`) 
);
CREATE TABLE `t_order` ( 
	`order_id` INT NOT NULL AUTO_INCREMENT, 
	`order_name` CHAR(100), 
	`customer_id` INT, 
	PRIMARY KEY (`order_id`) 
); 
INSERT INTO `t_customer` (`customer_name`) VALUES ('张三');
INSERT INTO `t_order` (`order_name`, `customer_id`) VALUES ('o1', '1'); 
INSERT INTO `t_order` (`order_name`, `customer_id`) VALUES ('o2', '1'); 
INSERT INTO `t_order` (`order_name`, `customer_id`) VALUES ('o3', '1'); 

关联查询:查询custmoer_id=1的用户的所有订单信息和用户信息

select t_customer.customer_id,customer_name,order_id,order_name from t_customer left JOIN t_order on t_customer.customer_id=t_order.customer_id
where t_customer.customer_id=1

Mybatis之关联,# Mybatis,mybatis,linux,运维

Customer实体类:

@Data
public class Customer {
    private Integer customerId;
    private String customerName;
//一个顾客的所有订单
    private List<Order> orderList;
}

Order实体类:

@Data
public class Order {
    private Integer orderId;
    private String orderName;
    private Integer customerId;

}

mapper接口:

Customer getCustomerWithOrders(Integer customerId);

xml配置文件:

    <resultMap id="CustomerMap" type="Customer">
        <id property="customerId" column="customer_id"></id>
        <result property="customerName" column="customer_name"></result>

        <collection property="orderList" ofType="Order">
            <id property="orderId" column="order_id"></id>
            <result property="orderName" column="order_name"></result>
        </collection>

    </resultMap>

    <select id="getCustomerWithOrders" resultMap="CustomerMap">
        select t_customer.customer_id,customer_name,order_id,order_name from t_customer left JOIN t_order on t_customer.customer_id=t_order.customer_id
        where t_customer.customer_id=#{customerId}
    </select>

测试:

   @Test
    public void test01(){
        Customer customerWithOrders = orderMapper.getCustomerWithOrders(1);
        System.out.println(customerWithOrders);
    }

在“对多”关联关系中,同样有很多配置,但是提炼出来最关键的就是:“collection”和“ofType”

二、对一关联

eg:一个订单对应一个用户

sql语句:查询订单号为1的订单和用户信息

select t_order.* ,t_customer.customer_name from t_order LEFT JOIN t_customer on t_order.customer_id=t_customer.customer_id
where order_id=1;

查询结果:

Mybatis之关联,# Mybatis,mybatis,linux,运维

order实体类新增Customer属性

@Data
public class Order {
    private Integer orderId;
    private String orderName;
    private Integer customerId;
    //对一关系,用户信息
    private Customer customer;
}

mapper接口:

    Order getOrderWithCustomer(Integer orderId);

xml配置文件:

    <resultMap id="OrderMap" type="Order">
        <id property="orderId" column="order_id"></id>
        <result property="orderName" column="order_name"></result>
        <association property="customer" javaType="Customer">
            <id property="customerId" column="customer_id"></id>
            <result property="customerName" column="customer_name"></result>
        </association>
    </resultMap>

    <select id="getOrderWithCustomer" resultMap="OrderMap">
        select t_order.* ,t_customer.customer_name from t_order LEFT JOIN t_customer on t_order.customer_id=t_customer.customer_id
        where order_id=#{orderId};

    </select>

测试:

   @Test
    public  void test02(){
        Order orderWithCustomer = orderMapper.getOrderWithCustomer(1);
        System.out.println(orderWithCustomer);
    }

三、OGNL风格的对一关联

<!--    OGNL风格的对一关联-->
    <select id="getOrderWithCustomer2" resultType="Order">
        select t_order.order_id,t_order.order_name,t_order.customer_id as 'customer.customerId',t_customer.customer_name as 'customer.customerName' from t_order LEFT JOIN t_customer on t_order.customer_id=t_customer.customer_id
        where order_id=#{orderId};
    </select>

注意起别名时,对象属性costomer.customerId要加上引号

四、多对多关联

eg:一本书对应多个种类,一个种类对应多本书

建立中间表将书和种类对应起来

①根据书的id,查询对应的具体信息和所属种类的信息:

mapper接口:

    /**
     * 根据书的id,查询对应的具体信息和所属种类的信息
     * @param bookId
     * @return
     */
    BookEntity selectBookOfCategories(Integer bookId);

xml配置文件:

    <resultMap id="BookMap" type="BookEntity">
        <id property="id" column="book_id"></id>
        <result property="name" column="name"></result>
        <collection property="categoryEntityList" ofType="CategoryEntity">
            <id property="categoryId" column="category_id"></id>
            <result property="categoryName" column="category_name"></result>
        </collection>
    </resultMap>

    <select id="selectBookOfCategories" resultMap="BookMap">
        select book_id,category.category_id,category_name,name
        from books,category,category_book
        WHERE books.id=category_book.book_id
          and category_book.category_id=category.category_id
          and books.id=#{value}
    </select>

②根据种类的id,查询所有对应书的信息

mapper接口:

  CategoryEntity getCategory(Integer id);

xml配置文件

   <resultMap id="CategoryMap" type="CategoryEntity">
        <id property="categoryId" column="category_id"></id>
        <result property="categoryName" column="category_name"></result>
        <collection property="bookEntityList" ofType="BookEntity">
            <id property="id" column="book_id"></id>
            <result property="name" column="name"></result>
        </collection>
    </resultMap>
    <select id="getCategory" resultMap="CategoryMap">
        SELECT name,category.category_id ,category_name,book_id
        from  books,category,category_book
        WHERE books.id=category_book.book_id
          and category_book.category_id=category.category_id
          and category.category_id=#{value};
    </select>

五、分步查询

①分步查询对多关联

根据id查询顾客=>设置resultMap=>collection中的select指定OrderMapper.xml中的根据顾客id查询所有订单的select语句=>column指定传参(顾客id)

CustomerMapper.xml

<resultMap id="CustomerMap" type="Customer">
    <id property="customerId" column="customer_id"></id>
    <result property="customerName" column="customer_name"></result>
    <collection property="orderList" select="com.iflytek.mapper.OrderMapper.selectOrderListById" column="customer_id"></collection>
</resultMap>

<select id="getOrderListByCustomerId" resultMap="CustomerMap">
    select * from t_customer where customer_id=#{id}
</select>

OrderMapper.xml

<select id="selectOrderListById" resultMap="OrderMap0">
    select * from t_order where customer_id=#{value}
</select>
<resultMap id="OrderMap0" type="Order">
    <id property="orderId" column="order_id"></id>
    <result property="orderName" column="order_name"></result>
</resultMap>

关系总览:

Mybatis之关联,# Mybatis,mybatis,linux,运维

②分步查询对一关联

OrderMapper.xml

根据订单id查询订单具体信息=>association标签中的select指定CustomerMapper.xml中的根据customer_id查询顾客信息的slecect语句=>column指定传参customer_id

    <resultMap id="OrderMap2" type="Order">
        <id property="orderId" column="order_id"></id>
        <result property="orderName" column="order_name"></result>
        <association property="customer" select="com.iflytek.mapper.CustomerMapper.getCustomerById" column="customer_id">
        </association>
    </resultMap>
    

    <select id="getOrderAndCustomer" resultMap="OrderMap2">
        select * from t_order where order_id=#{orderId}
    </select>

CustomerMapper.xml

根据用户id查询用户具体信息

    <resultMap id="CustomerMap0" type="Customer">
        <id property="customerId" column="customer_id"></id>
        <result property="customerName" column="customer_name"></result>
    </resultMap>

<select id="getCustomerById" resultMap="CustomerMap0">
    select * from t_customer where customer_id=#{value}
</select>

关系总览:

Mybatis之关联,# Mybatis,mybatis,linux,运维

六、延迟加载

查询到Customer的时候,不一定会使用Order的List集合数据。如果Order的集合数据始终没有使用,那么这部分数据占用的内存就浪费了。对此,我们希望不一定会被用到的数据,能够在需要使用的时候再去查询。

延迟加载的概念:对于实体类关联的属性到需要使用时才查询。也叫懒加载。

yml配置文件中开启懒加载

mybatis:
  configuration:
    #开启懒加载
    lazy-loading-enabled: true

测试:

@Test
public void testSelectCustomerWithOrderList() throws InterruptedException {

    //对多关联
    Customer customer = mapper.selectCustomerWithOrderList(1);
    
    // 这里必须只打印“customerId或customerName”这样已经加载的属性才能看到延迟加载的效果
    // 这里如果打印Customer对象整体则看不到效果
    System.out.println("customer = " + customer.getCustomerName());
    
    // 先指定具体的时间单位,然后再让线程睡一会儿
    TimeUnit.SECONDS.sleep(5);
    
    List<Order> orderList = customer.getOrderList();
    
    for (Order order : orderList) {
        System.out.println("order = " + order);
    }
}

效果:刚开始先查询Customer本身,需要用到OrderList的时候才发送SQL语句去查询文章来源地址https://www.toymoban.com/news/detail-814805.html

DEBUG 11-30 11:25:31,127 ==>  Preparing: select customer_id,customer_name from t_customer where customer_id=?   (BaseJdbcLogger.java:145) 
DEBUG 11-30 11:25:31,193 ==> Parameters: 1(Integer)  (BaseJdbcLogger.java:145) 
DEBUG 11-30 11:25:31,314 <==      Total: 1  (BaseJdbcLogger.java:145) 
customer = c01
DEBUG 11-30 11:25:36,316 ==>  Preparing: select order_id,order_name from t_order where customer_id=?   (BaseJdbcLogger.java:145) 
DEBUG 11-30 11:25:36,316 ==> Parameters: 1(Integer)  (BaseJdbcLogger.java:145) 
DEBUG 11-30 11:25:36,321 <==      Total: 3  (BaseJdbcLogger.java:145) 
order = Order{orderId=1, orderName='o1'}
order = Order{orderId=2, orderName='o2'}
order = Order{orderId=3, orderName='o3'}

到了这里,关于Mybatis之关联的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • MyBatis:关联查询

    在 MyBatis:配置文件 文章中,最后介绍了可以使用 select 标签的 resultMap 属性实现关联查询,下面简单示例 首先,先创建 association_role 和 association_user 两张数据表,并建立关联关系 表结构如图: 表信息如图: 在创建 association_user 表时需要添加 associat

    2024年02月05日
    浏览(40)
  • MyBatis关联映射相关习题

    一、单选题 1、下列属性中,不属于association元素属性的是()。 A、property B、select C、ofType D、autoMapping 正确答案:C ofType是collection元素特有的属性 2、下列关于foreach元素的collection属性的说法正确的是()。 A、collection属性可有可无 B、collection属性值在任何情况下的取值都是

    2023年04月27日
    浏览(74)
  • Mybatis关联查询【附实战案例】

    目录 相关导读 一、Mybatis一对一关联查询 1. 新增持久层接口方法 2. 新增映射文件对应的标签

    2023年04月17日
    浏览(63)
  • 认识Mybatis的关联关系映射,灵活关联表对象之间的关系

    目录      一、概述 ( 1 )  介绍 ( 2 )  关联关系映射 ( 3 ) 关联讲述 二、一对一关联映射 2.1 数据库创建 2.2 配置文件  2.3 代码生成 2.4 编写测试 三、一对多关联映射 四 、多对多关联映射 给我们带来的收获 关联关系映射是指在数据库中,通过定义 表之间的关联关系 ,将多

    2024年02月11日
    浏览(47)
  • MyBatis中的关联关系以及多表连接

    目录 一对一 一对多 多对多 关联关系总结 一对一 一张表的一条记录对应查询到另一张表的一条记录,重要的是实体中的一个对象也要包含另一个对象 实例,一个乘客查询到一本护照 实体类 dao层 mapper语句 测试层 一对多 mapper语句 实体类 dao层 测试层 多对多 dao层 测试层 m

    2024年02月13日
    浏览(37)
  • MyBatis注解开发---实现自定义映射关系和关联查询

    目录 相关导读 一、使用注解实现自定义映射关系 1. 编写注解方法 2. 编写测试方法

    2023年04月09日
    浏览(44)
  • MyBatis关联查询实战:一对一与一对多详细解析

    MyBatis是一款强大的持久层框架,提供了多种方式来处理关联查询,其中包括一对一和一对多的情况。在本文中,我们将深入探讨这两种关联查询的实现方式,并通过具体的示例代码进行详细解释。 实现一对一关联查询的方式有多种,其中包括嵌套查询(Nested Queries)和结果集

    2024年01月19日
    浏览(73)
  • spring boot集成mybatis-plus——Mybatis Plus 多表联查(包含分页关联查询,图文讲解)...

     更新时间 2023-01-03 21:41:38 大家好,我是小哈。 本小节中,我们将学习如何通过 Mybatis Plus 实现 多表关联查询 ,以及 分页关联查询 。 本文以 查询用户所下订单 ,来演示 Mybatis Plus 的关联查询,数据库表除了前面小节中已经定义好的用户表外,再额外创建一张订单表,然后

    2024年02月01日
    浏览(94)
  • mybatis-plus 多表关联条件分页查询

    此处以一对多,条件分页查询为例: 主表 明细表 0.请求dto 1.Controller 层: 注:我的项目中进行了service 读写分类配置,实际使用中,直接使用mybatis-plus中的 IUserService 对应的接口就行。 2.service 层 service impl实现层: 3.mapper 层 4.mapper.xml层 5.测试: 结果body: Q:todo page 分页会把

    2024年02月12日
    浏览(48)
  • MyBatis 的关联关系配置 一对多,一对一,多对多 关系的映射处理

    目录 一.关联关系配置的好处  二. 导入数据库表:  三.    一对多关系:--    一个订单对应多个订单项        四.一对一关系:---一个订单项对应一个订单 五.多对多关系(两个一对多)          MyBatis是一个Java持久化框架,可以 通过XML或注解的方式 将对象与数据库

    2024年02月11日
    浏览(64)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包