JPA实体设计
实体是轻量级的领域对象,因此实体也称为领域模型。
既然属于模型,那么模型应该遵守一些设计规范,设计实体的时候应该注意哪些规范呢?
实体是属于领域模型,那么实体这个模型在多层软件架构中属于那一层呢?
多层架构程序
我们首先用一张图来说明实体在多层软件架构中属于那一层?
<figure class="image"></figure>在一个多层软件架构中,领域模型能够被每一个组件访问。DAO层(Repository)用它来管理数据,展示层(Controller)
用它来将数据转化成JSON,便于前端展示等等。一个问题,Service层用领域模型来做什么呢?
一个重要的原则:
设计实体(领域模型)的时候最重要的是不要以来任何正交的Java API,举例来说,领域模型不应执行数据库操作和JNDI查找。实体(领域模型)最好设计成简单的POJO
设计实体基本原则
- 实体类必须用@Entity注解标注
- 实体类必须有一个public或者protected的无参构造器,也可以有其他构造器
- 实体类必须是顶级类,枚举或者接口不能设计成实体
- 抽象类和具体类都可以设计成实体
- 实体类不能设计成final.实体类的任何方法或者持久化变量都不能是final
- 建议实体类实现序列化接口,尽管不是必须的
- 每一个private或protected属性应该设计Getter/Setter方法
- 实体类支持继承,多态关联和多态查询
- 可以为实体类增加验证功能
好了,请问有什么疑问吗?这里我先提供一些疑问?
是否每个实体属性都需要设计Getter/Setter方法?
实体怎么支持多态查询和多态关联?
什么叫做顶级类?
设计实体属性原则
每一个持久化的属性需要设置setter/getter方法
如果属性需要容器,使用集合接口,而不是具体的实现类
JPA支持的一些属性数据类型:
The persistent fields an entity may be of the following types: Java primitive types
& their wrapper class
, java.lang.String
, java.math.BigInteger
, java.math.BigDecimal
, java.util.Date
, java.util.Calendar
, java.sql.Date
, java.sql.Time
, java.sql.Timestamp
, byte[]
, Byte[]
, char[]
, Character[]
, java.time.LocalDate
, java.time.LocalTime
, java.time.LocalDateTime
, java.time.OffsetTime
, java.time.OffsetDateTime
, and user-defined types that implement the Serializable interface
, enums, entity types, collections of entity types
, embeddable classes, collections of basic and embeddable types.
Avoid using
java.util.Date
. Instead use the classes fromjava.time.*
, such asjava.time.LocalDate
,java.time.LocalTime
, and etc.
这里遇到一个问题,给实体设置时间属性的时候,最好不要用java.util.Date.推荐使用java.time.*至于原因嘛,后续我们会按照上面的注解进行慢慢分析。
实体注解类型
注解属于实体的元数据,基本的注解类型包括属性注解,关系注解,嵌入注解等。比如@Entity , @Table 等,我们后续的学习就是通过使用注解来提高对JPA的认识。