栏目分类:
子分类:
返回
终身学习网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
终身学习网 > IT > 软件开发 > 后端开发 > Java

Mybatis-入门教程 第三章 关联关系

Java 更新时间:发布时间: 百科书网 趣学号
Mybatis-入门教程 第三章 关联关系

第一节 概念

第二节 对一

第三节 对多

第四节 分步查询

第五节 延迟加载]

第六节 多对多关联关系需要中间表

文章目录
  • Mybatis-入门教程 第三章 关联关系
  • 第一节 概念
    • 1、关联关系概念说明
    • 2、创建模型
      • ①创建实体类
      • ②创建数据库表插入测试数据
  • 第二节 对一
    • 1、创建OrderMapper接口
    • 2、创建OrderMapper.xml配置文件
    • 3、在Mybatis全局配置文件中注册Mapper配置文件
    • 4、junit测试程序
    • 5、关键词
  • 第三节 对多
    • 1、创建Mapper接口
    • 2、创建CustomerMapper.xml配置文件
    • 3、配置关联关系和SQL语句
    • 4、junit测试
    • 5、关键词
  • 第四节 分步查询
    • 1、概念和需求
    • 2、具体操作
      • ①编写查询Customer的SQL语句
      • ②编写查询Order的SQL语句
      • ③引用SQL语句
      • ④各个要素之间的对应关系
  • 第五节 延迟加载
    • 1、概念
    • 2、配置
    • 3、修改junit测试
    • 4、关键词总结
  • 第六节 多对多关联关系需要中间表
    • 1、如果不使用中间表
    • 2、使用中间表
    • 3、中间表设置主键
      • ①方案一:另外设置一个专门的主键字段
      • ②方案二:使用联合主键

第一节 概念 1、关联关系概念说明
  • 一对一

    夫妻关系,人和身份证号

  • 一对多

    用户和用户的订单,锁和钥匙

  • 多对多

    老师和学生,部门和员工

2、创建模型 ①创建实体类
public class Customer {
    
    private Integer customerId;
    private String customerName;
    private List orderList;// 体现的是对多的关系
public class Order {
    
    private Integer orderId;
    private String orderName;
    private Customer customer;// 体现的是对一的关系

双向关联关系:双方都能够引用到对方

Customer中能够引用Order

Order中能够引用Customer

在双向关联关系中使用toString()等方法时注意避免无限死循环。

单向关联关系:双方中只有一方能够引用到对方

Customer中没有引用Order

Order中引用了Customer

②创建数据库表插入测试数据
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 ('c01');
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'); 

实际开发时,一般在开发过程中,不给数据库表设置外键约束。

原因是避免调试不方便。

一般是功能开发完成,再加外键约束检查是否有bug。

[

第二节 对一 1、创建OrderMapper接口
public interface OrderMapper {
    
    Order selectOrderWithCustomer(Integer orderId);
    
}
2、创建OrderMapper.xml配置文件





    
    
    

    
    
    
    
        
        
        
    





    SELECT c.customer_id,c.customer_name,o.order_id,o.order_name
    FROM t_customer c
    LEFT JOIN t_order o
    ON c.customer_id=o.customer_id
    WHERe c.customer_id=#{customerId}

4、junit测试
@Test
public void testRelationshipToMulti() {
    SqlSession session = factory.openSession();
    CustomerMapper customerMapper = session.getMapper(CustomerMapper.class);
    
    // 查询Customer对象同时将关联的Order集合查询出来
    Customer customer = customerMapper.selectCustomerWithOrderList(1);
    
    System.out.println("customer.getCustomerId() = " + customer.getCustomerId());
    System.out.println("customer.getCustomerName() = " + customer.getCustomerName());
    
    List orderList = customer.getOrderList();
    for (Order order : orderList) {
        System.out.println("order = " + order);
    }
    
    session.close();
}
5、关键词

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

第四节 分步查询 1、概念和需求

为了实现延迟加载,对Customer和Order的查询必须分开,分成两步来做,才能够实现。为此,我们需要单独查询Order,也就是需要在Mapper配置文件中,单独编写查询Order集合数据的SQL语句。

2、具体操作 ①编写查询Customer的SQL语句


    select order_id,order_name from t_order where customer_id=#{customer_id}

③引用SQL语句





如果Mapper接口中的抽象方法没有改变,那么juni测试也不变。执行结果如下:

DEBUG 11-30 11:10:05,796 ==>  Preparing: select customer_id,customer_name from t_customer where customer_id=?   (BaseJdbcLogger.java:145) 
DEBUG 11-30 11:10:05,866 ==> Parameters: 1(Integer)  (BaseJdbcLogger.java:145) 
DEBUG 11-30 11:10:05,889 ====>  Preparing: select order_id,order_name from t_order where customer_id=?   (BaseJdbcLogger.java:145) 
DEBUG 11-30 11:10:05,890 ====> Parameters: 1(Integer)  (BaseJdbcLogger.java:145) 
DEBUG 11-30 11:10:05,895 <====      Total: 3  (BaseJdbcLogger.java:145) 
DEBUG 11-30 11:10:05,896 <==      Total: 1  (BaseJdbcLogger.java:145) 
customer = c01
order = Order{orderId=1, orderName='o1'}
order = Order{orderId=2, orderName='o2'}
order = Order{orderId=3, orderName='o3'}
④各个要素之间的对应关系

第五节 延迟加载 1、概念

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

例如:对Customer进行1000次查询中,其中只有15次会用到Order的集合数据,那么就在需要使用时才去查询能够大幅度节约内存空间。

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

2、配置

在Mybatis全局配置文件中配置settings



    
    
    

    
    

官方文档中对aggressiveLazyLoading属性的解释:

When enabled, an object with lazy loaded properties will be loaded entirely upon a call to any of the lazy properties.Otherwise, each property is loaded on demand.

3、修改junit测试
@Test
public void testSelectCustomerWithOrderList() throws InterruptedException {
    SqlSession session = sessionFactory.openSession();
    
    CustomerMapper mapper = session.getMapper(CustomerMapper.class);
    
    Customer customer = mapper.selectCustomerWithOrderList(1);
    
    // 这里必须只打印“customerId或customerName”这样已经加载的属性才能看到延迟加载的效果
    // 这里如果打印Customer对象整体则看不到效果
    System.out.println("customer = " + customer.getCustomerName());
    
    // 先指定具体的时间单位,然后再让线程睡一会儿
    TimeUnit.SECONDS.sleep(5);
    
    List orderList = customer.getOrderList();
    
    for (Order order : orderList) {
        System.out.println("order = " + order);
    }
    
    session.commit();
    session.close();
}

效果:刚开始先查询Customer本身,需要用到OrderList的时候才发送SQL语句去查询

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'}
4、关键词总结

我们是在“对多”关系中举例说明延迟加载的,在“对一”中配置方式基本一样。

关联关系配置项关键词所在配置文件
对一association标签/javaType属性Mapper配置文件中的resultMap
对多collection标签/ofType属性Mapper配置文件中的resultMap
对一分步association标签/select属性Mapper配置文件中的resultMap
对多分步collection标签/select属性Mapper配置文件中的resultMap
延迟加载lazyLoadingEnabled设置为true
aggressiveLazyLoading设置为false
Mybatis全局配置文件中的settings
第六节 多对多关联关系需要中间表 1、如果不使用中间表

在某一个表中,使用一个字段保存多个“外键”值,这将导致无法使用SQL语句进行关联查询。

2、使用中间表

这样就可以使用SQL进行关联查询了。只是有可能需要三张表进行关联。

3、中间表设置主键 ①方案一:另外设置一个专门的主键字段

②方案二:使用联合主键

使用联合主键时,只要多个字段的组合不重复即可,单个字段内部是可以重复的。

|

转载请注明:文章转载自 www.051e.com
本文地址:http://www.051e.com/it/957419.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 ©2023-2025 051e.com

ICP备案号:京ICP备12030808号