当前位置: 首页>编程语言>正文

springbean延迟加载 spring延迟加载原理

Java 程序代码与数据库交互越低越好,避免浪费资源。Mybatis提供了一种延迟加载机制,类似懒加载,在此之前,使用了这么久的 Mybatis,第一次了解到这个概念。

然后仔细学了一遍,怎么说呢,在实际项目中使用还是有一些限制。首先就是麻烦,本来一条sql能完成的查询,要分开写。其次联查两个表倒是可以用,当联查三个表时,说实话还没搞懂怎么用。最后我觉得这是个伪需求,查出来的字段一定是需要用的,不然为什么要查它。

但是不妨碍学习。本篇通过实际案例的方式来理解和学习这种使用方法。

现在有两个表,对应的实体类如下:

客户(Customer)

public class Customer {
private Long id;
private String name;
private List orders;
}

订单(Order)

public class Order {
private Long id;
private String name;
private Customer customer;
}

这两者是一对多的关系,按照这种模型,数据库建表,t_customer 为主表,t_order 为从表。t_customer 的主键是 t_order 的外键。

然后分别建了两个对应表

CREATE TABLE `t_customer` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(11) DEFAULT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `t_order` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(11) DEFAULT NULL,
`cid` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `cid` (`cid`),
CONSTRAINT `t_order_ibfk_1` FOREIGN KEY (`cid`) REFERENCES `t_customer` (`id`)
);

然后分别加了数据进去

然后我创建了两组 mapper,分别是 OrderRepository、OrderRepository.xml

public interface OrderRepository {
public Order findById(Long id);
}
select * from t_order where id = #{id};
CustomerRepository、CustomerRepository.xml
public interface CustomerRepository {
public Customer findById(Long id);
}
select * from t_customer where id = #{id};

然后在 config 中注册这两个 mapper.xml

因为我将 xml 放到 java 代码包下,并不是 resources ,所以还需要在 pom文件配置如下代码,不然会找不到 mapper.xml文件的

src/main/java
**/*.xml

然后在全局配置文件中配上打印 SQL 语句 ,不然控制台不知道java代码和数据库交互查询了几次。

在运行如下代码,进行测试

InputStream inputStream = App.class.getClassLoader().getResourceAsStream("config.xml");
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
OrderRepository orderRepository = sqlSession.getMapper(OrderRepository.class);
Order order = orderRepository.findById(1L);
System.out.println(order.getName());

从图中可以看到,确实执行查询了两条 SQL ,虽然我使用的是第一次查询的数据,也就是只要查询 Order表就行。现在开启延迟加载,这样如果没使用 Consumer 表中的数据,则不会去查询。

测试结果图如下

从上图可看出,查询次数已经变成只查询 t_order 表。现在修改测试代码,使用第二个表 t_consumer 中的数据

System.out.println(order.getCustomer().getName());

从上图结果可以看出,查询两次。

正如我前面所说呢,这功能实际使用中很鸡肋,看不到使用场景。毕竟,如果不需要某个数据,查询时就不当作查询字段了。或者直接联表查询也行,联表时也只会执行一次查询。

select o.id oid,o.name oname,c.id cid ,c.name cname from t_order o
join t_customer c on o.cid = c.id where o.id = 1;

以上代码笔记内容来自付费专栏:案例上手 Spring 全家桶

PS:并没有透露关键内容,纯粹是零碎笔记。


https://www.xamrdz.com/lan/5qj1923481.html

相关文章: