JPA
2020-08-18 本文已影响0人
aiingstan
Relations
@ManyToMany
@ManyToOne
关系需要通过 Owner
方来维护。
比如一个人有多个手机号码,这里 Person
和 Mobile
就是 @OneToMany
关系,Person
是 Ower
Index and Constraint
唯一约束
@Table(indexes = {@index(name = "unique_user", columnList = "email", unique = true)})
...
另外,在可能触发异常的位置,需要捕获 ConstraintViolationException
延迟加载错误
session.load
Transactional
忽略掉某些属性?
日期和时间
对应
通常来说尽量使用 java.time
包中的类来表示
MySQL
对应到 Java
,以及典型应用场景:
-
datetime
-Instant
, Created Date -
date
-LocalDate
, Birthday
字段存储的问题
通常来说,在数据库中存储的日期、时间会使用 UTC
比较正确。不过在有些场景下,可能希望去存储一个时间的“字面值” (wall clock time),例如班车时刻表、会议时间等等。当然,这样做有个必要的条件是要同时存储一个能够表示时区的上下文。例如可以从用户的设置获取用户所设定的区域、时区。(那更新时区设置的时候,相应的时刻表、会议时间表的时间也需要同步更新)
具体实现层面,在实体类中使用 LocalTime
类型来定义字段,并定义 columnDefinitionType
为 varchar(8)
。
另外,为了避免 JPA
在获取数据库记录的时候自动根据服务器时间转换时区,有一种方法是自己定义 Converter
@Converter(autoApply = true)
public class LocalTimeJpaConverter implements AttributeConverter<LocalTime, String> {
@Override
public String convertToDatabaseColumn(LocalTime localTime) {
return Optional.ofNullable(localTime)
.map(LocalTime::toString)
.orElse(null);
}
@Override
public LocalTime convertToEntityAttribute(String timeString) {
return Optional.ofNullable(timeString)
.map(LocalTime::parse)
.orElse(null);
}
}
@Column(columnDefinitionType = 'varchar(8)')
@Convert(convert = LocalTimeJpaConverter.class)
private LocalTime scheduleTime;