Java 我可以使用Hibernate将一个字段映射到数据库中的两列吗?

Java 我可以使用Hibernate将一个字段映射到数据库中的两列吗?,java,hibernate,jpa,Java,Hibernate,Jpa,考虑以下Java Hibernate实体示例(代码段): 这将生成一个列,其中一列是数据库 如何/应该在数据库表中生成从同一字段生成的第二列column\u TWO?第二列在使用该实体的Java代码中并不重要,因此我的实体不应该将第二列导出给该实体的用户第二列将用于数据库本身(用于某些索引)和其他应用程序。免责声明:我没有尝试过这个,但我相信Hibernate可以访问私有方法,因为它可以访问私有字段 对于本例,假设您有一个类用户看到的类型为LocalDateTime的属性,但您希望将值存储为IS

考虑以下Java Hibernate实体示例(代码段):

这将生成一个
列,其中一列是数据库

如何/应该在数据库表中生成从同一字段生成的第二列
column\u TWO
?第二列在使用该实体的Java代码中并不重要,因此我的实体不应该将第二列导出给该实体的用户<代码>第二列
将用于数据库本身(用于某些索引)和其他应用程序。

免责声明:我没有尝试过这个,但我相信Hibernate可以访问私有方法,因为它可以访问私有字段

对于本例,假设您有一个类用户看到的类型为
LocalDateTime
的属性,但您希望将值存储为ISO-8601格式的字符串(
VARCHAR
),其中日期在一列中,时间在另一列中

因此,您有普通的
private
字段和普通的
public
getter/setter方法。您不会将
@Column
放在这两个属性上,而是使用
@Transient
使JPA忽略该属性

然后创建两个派生的getter/setter方法对,将它们设置为
private
,这样类的用户就看不到它们,然后用
@Column
注释这两个方法对,以便JPA在数据库中持久化时使用它们

private LocalDateTime dateTime;
@暂时//不在数据库中持久化
公共LocalDateTime getDateTime(){
返回此.dateTime;
}
public void setDateTime(LocalDateTime dateTime){
this.dateTime=dateTime;
}
@列(name=“FOO_DATE”,null=true,长度=10)
私有字符串getDate(){
if(this.dateTime==null)
返回null;
返回此.dateTime.toLocalDate().toString();
}
私有无效设置日期(字符串日期){
如果(日期==null){
this.dateTime=null;
}否则{
LocalDate=LocalDate.parse(日期);
LocalTime时间=(this.dateTime==null?LocalTime.MIDNIGHT
:this.dateTime.toLocalTime());
this.dateTime=LocalDateTime.of(日期,时间);
}
}
@列(name=“FOO_TIME”,null=true,长度=12)
私有字符串getTime(){
if(this.dateTime==null)
返回null;
返回此.dateTime.toLocalTime()
.format(模式的DateTimeFormatter.of(“HH:mm:ss.SSS”);
}
私有void设置时间(字符串时间){
if(time==null){
this.dateTime=null;
}否则{
LocalTime=LocalTime.parse(time);
LocalDate日期=(this.dateTime==null?LocalDate.ofEpochDay(0)
:this.dateTime.toLocalDate());
this.dateTime=LocalDateTime.of(日期,时间);
}
}
免责声明:我没有尝试过,但我相信Hibernate可以访问私有方法,因为它可以访问私有字段

对于本例,假设您有一个类用户看到的类型为
LocalDateTime
的属性,但您希望将值存储为ISO-8601格式的字符串(
VARCHAR
),其中日期在一列中,时间在另一列中

因此,您有普通的
private
字段和普通的
public
getter/setter方法。您不会将
@Column
放在这两个属性上,而是使用
@Transient
使JPA忽略该属性

然后创建两个派生的getter/setter方法对,将它们设置为
private
,这样类的用户就看不到它们,然后用
@Column
注释这两个方法对,以便JPA在数据库中持久化时使用它们

private LocalDateTime dateTime;
@暂时//不在数据库中持久化
公共LocalDateTime getDateTime(){
返回此.dateTime;
}
public void setDateTime(LocalDateTime dateTime){
this.dateTime=dateTime;
}
@列(name=“FOO_DATE”,null=true,长度=10)
私有字符串getDate(){
if(this.dateTime==null)
返回null;
返回此.dateTime.toLocalDate().toString();
}
私有无效设置日期(字符串日期){
如果(日期==null){
this.dateTime=null;
}否则{
LocalDate=LocalDate.parse(日期);
LocalTime时间=(this.dateTime==null?LocalTime.MIDNIGHT
:this.dateTime.toLocalTime());
this.dateTime=LocalDateTime.of(日期,时间);
}
}
@列(name=“FOO_TIME”,null=true,长度=12)
私有字符串getTime(){
if(this.dateTime==null)
返回null;
返回此.dateTime.toLocalTime()
.format(模式的DateTimeFormatter.of(“HH:mm:ss.SSS”);
}
私有void设置时间(字符串时间){
if(time==null){
this.dateTime=null;
}否则{
LocalTime=LocalTime.parse(time);
LocalDate日期=(this.dateTime==null?LocalDate.ofEpochDay(0)
:this.dateTime.toLocalDate());
this.dateTime=LocalDateTime.of(日期,时间);
}
}

您必须决定是希望数据库设计由实体设计驱动,还是希望将两者解耦

如果您不需要实体中的列,那么就不要映射它。如果这种方法的“问题”是hbm2ddl没有生成列,那么您必须确定实体模型是否真的应该是数据库设计的驱动因素。您可以(而且IMO应该)使用Liquibase或Flyway之类的工具进行数据库模式迁移。这样,您可以在数据库中拥有该列,同时不将其映射到实体中


我理解这对于您的小用例来说可能太多了,但我建议您最终还是这样做,因为您在某个时候会需要它。无论如何,您也可以将其映射为私有字段而不公开字段。

您必须决定是否希望您的数据库设计由实体驱动
...

@Column
@Converter(...)
private String columnOne;

public String getcolumnOne() {
    return columnOne;
}

public setColumnOne(String columnOne) {
    this.columnOne = columnOne;
}

...