文章插图
其中:
- address_id 存储的是 Address 实体的主键;
- pay_id 存储的事 Pay 实体的主键;
其中,插入数据的sql如下:
Hibernate: insert into address (detail) values (?)
Hibernate: insert into pay_info (order_id, price) values (?, ?)
Hibernate: insert into order_info (address_id, pay_id, status, total_price, total_selling_price, user_id) values (?, ?, ?, ?, ?, ?)
3.1.2. 单向一对多实体定义如下:
// 聚合根实体@Entity@Table(name = "order_info")public class Order{@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;// 添加 @OneToMany 注解@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)// 指定多端的关联列(如果不指定,会使用第三张表来保存关系@JoinColumn(name = "order_id")private List<OrderItem> orderItems = new ArrayList<>();// 忽略其他属性}// OrderItem 实现@Entity@Table(name = "order_item")public class OrderItem {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;// 忽略其他属性}插入记录后,表数据如下:order 表数据:

文章插图
order+item表数据:

文章插图
其中 order_item 表中的 order_id 指向 order_info 表的主键 。
3.2. 继承关系继承是面向对象编程的核心特性,但这一特性确与数据库的关系模型产生巨大阻抗 。
JPA 中提供了三种继承模型,包括:
- 单表继承策略(SINGLE_TABLE) 。父类实体和子类实体共用一张数据库表,在表中通过一列辨别字段来区别不同类别的实体;
- Joined 策略(JOINED) 。父类和子类分别对应一张表,父类对应的表中只有父类自己的字段,子类对应的表中中有自己的字段和父类的主键字段,两者间通过 Join 方式来处理关联;
- 每个实体一个表策略(TABLE_PER_CLASS) 。每个实体对应一个表,会生成多张表,父类对应的表只有自己的字段 。子类对应的表中除了有自己特有的字段外,也有父类所有的字段 。
在优惠计算过程中,需要根据不同的配置策略对当前用户进行验证,以判断用户是否能够享受优惠,常见的验证策略有:
- 只有特定用户才能享受 。
- 只有男士或女士才能享受 。
- 只有VIP特定等级才能享受 。
- 未来还有很多

文章插图
那接下来便是将这些实现类存储到数据库,然后在方便的查询出来 。
3.2.1. 单表继承
单表继承非常简单,也最为实用,数据库表只有一张,通过一列辨别字段来区别不同类别的实体 。它的使用涉及几个关键注解:
- @Inheritance(strategy = InheritanceType.SINGLE_TABLE),添加在父类实体,用于说明当前使用的是 单表策略;
- @DiscriminatorColumn(name="区分类型存放的列名"),添加在父类实体,用于说明使用哪个列来区分具体类型;
- @DiscriminatorValue(value = https://www.isolves.com/it/cxkf/bk/2023-09-11/"当前类型的标识") 添加到子类实体上,用于说明当前子类的具体类型;
// 父类@Entity// 单表表名@Table(name = "activity_matcher")// 当前策略为单表策略@Inheritance(strategy = InheritanceType.SINGLE_TABLE)// activity_type 列用于存储对应的类型@DiscriminatorColumn(name = "activity_type")@Datapublic abstract class BaseActivityMatcher implements ActivityMatcher {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;private ActivityMatcherStatus status = ActivityMatcherStatus.ENABLE;}// SpecifyUserMatcher 实现类@Entity// 使用 SpecifyUser 作为标记@DiscriminatorValue("SpecifyUser")public class SpecifyUserMatcherextends BaseActivityMatcherimplements ActivityMatcher {// 省略属性和方法}// SexMatcher 实现类@Entity// 使用 Sex 作为标记@DiscriminatorValue("Sex")public class SexMatcherextends BaseActivityMatcherimplements ActivityMatcher {// 省略属性和方法}@Entity// 使用 VipLevel 作为标记@DiscriminatorValue("VipLevel")public class VipLevelMatcherextends BaseActivityMatcherimplements ActivityMatcher {// 省略属性和方法}
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 解密MongoDB的数据分片策略与负载均衡:构建可伸缩的数据库
- 深度解密大模型的“军火商”,向量数据库的八大技术方向!
- 解密成功程序员的秘密武器
- 解密《穿普拉达的女王》,突破刻板印象,绽放女性职场之光
- 无头浏览器解密:全面了解这个神秘的工具
- 企业服务器数据库中了_locked勒索病毒怎么解密,_locked勒索病毒简介与防护
- OpenAI API新功能解密:成本大幅下降,体验感飙升
- DDD实战 - Repository模式的妙用
- 为什么从 MVC 到 DDD,架构的本质是什么?
- DDD 中关于应用架构的那些事
