每种策略保存一条数据后,各个表数据如下:
user_per_class_matcher 如下:

文章插图
sex_per_class_matcher 如下:

文章插图
vip_per_class_matcher 如下:

文章插图
具有以下特点:
- 每个具体的子类对应一张表,表中存储父类和子类的数据;
- 为每个子类生成id,所生成的 id 不重复;
3.2.4. 小节三种策略各具特色,都有最佳应用场景,简单如下:
- 单表策略 。
ß可以使用单表继承策略来减少表的数量;
- Joined 策略 。
- 子类的属性较多,且与父类的属性差别较大;
- 需要一个主表,用于对所有的子类进行管理;
- 每个实体一个表策略 。
- 子类的属性较多,且与父类的属性差别较大;
- 子类过于离散,无需统一管理;
3.3. 立即加载&延迟加载JPA提供了两种加载策略:立即加载和延迟加载 。
- 一对一关联,默认获取策略是立即加载(EAGER),查询一个对象,会把它关联的对象都查出来初始化到属性中;
- 一对多关联,默认获取策略是懒加载(LAZY),即只有在使用到相关联数据时才会查询数据库;
3.3.1. 立即加载
立即加载会在查询主实体类的同时查询它所有关联实体类,并绑定到实体属性上 。立即加载的好处是能够提高查询效率,因为不需要额外的查询操作 。但是,使用立即加载会增加数据库的查询负担,查询出所有关联实体类,会导致查询结果的数据量比较大 。
实体配置如下:
@Entity@Table(name = "order_info")public class Order{@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)@JoinColumn(name = "order_id")private List<OrderItem> orderItems = new ArrayList<>();@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)private Pay pay;@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)private Address address;// 忽略其他属性和方法}测试脚本如下:Order order = this.orderRepository.findById(this.order.getId()).get();Assertions.assertNotNull(order);System.out.println("访问 item");Assertions.assertEquals(3, order.getOrderItems().size());System.out.println("访问 address");Assertions.assertNotNull(order.getAddress().getDetail());System.out.println("访问 pay");Assertions.assertNotNull(order.getPay().getPrice());日志输出如下:Hibernate: select order0_.id as id1_3_0_, order0_.address_id as address_6_3_0_, order0_.pay_id as pay_id7_3_0_, order0_.status as status2_3_0_, order0_.total_price as total_pr3_3_0_, order0_.total_selling_price as total_se4_3_0_, order0_.user_id as user_id5_3_0_, address1_.id as id1_2_1_, address1_.detail as detail2_2_1_, orderitems2_.order_id as order_id6_4_2_, orderitems2_.id as id1_4_2_, orderitems2_.id as id1_4_3_, orderitems2_.price as price2_4_3_, orderitems2_.product_id as product_3_4_3_, orderitems2_.quantity as quantity4_4_3_, orderitems2_.selling_price as selling_5_4_3_, pay3_.id as id1_5_4_, pay3_.price as price2_5_4_ from order_info order0_ left outer join address address1_ on order0_.address_id=address1_.id left outer join order_item orderitems2_ on order0_.id=orderitems2_.order_id left outer join pay_info pay3_ on order0_.pay_id=pay3_.id where order0_.id=?访问 item访问 address访问 pay从日志输出可见:- JPA 使用多张表的join,通过一个复杂的 sql 一次性获取了所有数据;
- 在访问关联实体时,未触发任何加载操作;
推荐阅读
- 解密MongoDB的数据分片策略与负载均衡:构建可伸缩的数据库
- 深度解密大模型的“军火商”,向量数据库的八大技术方向!
- 解密成功程序员的秘密武器
- 解密《穿普拉达的女王》,突破刻板印象,绽放女性职场之光
- 无头浏览器解密:全面了解这个神秘的工具
- 企业服务器数据库中了_locked勒索病毒怎么解密,_locked勒索病毒简介与防护
- OpenAI API新功能解密:成本大幅下降,体验感飙升
- DDD实战 - Repository模式的妙用
- 为什么从 MVC 到 DDD,架构的本质是什么?
- DDD 中关于应用架构的那些事
