我所有人,我有一个Spring Boot应用程序。我具体想要的是在他相应的实体中转换一个类(具有嵌套对象字段)。例如:
public class example{
String string;
ObjectExample object;
}
public class ObjectExample{
String oneString;
XMLGregorianCalendar date;
}
这2个对象在另一个包中也标记为实体,但是在ObjectExampleEntity中,我有Date date而不是XMLGregorianCalendar,例如带有示例的
@Entity
public class example{
String string;
ObjectExample object;
}
@Entity
public class ObjectExample{
String oneString;
Date date;
}
因为我有一个带有很多嵌套类的大型模型和大型实体(以上仅是示例),所以我使用推土机将模型从模型转换为类。 例如,考虑仅为父示例类创建存储库jpa。 我想知道如何使用推土机将Date(实体)转换为XMLGregorianCalendar(模型)并反转。模型和实体,我重复相同。唯一的区别是日期的类型。谢谢
答案 0 :(得分:1)
我假设:
date
,因此它包含一个日历日期(无时间)。XMLGregorianCalendar
上,但是您可以在实体端更改类型。基于这些假设,我建议在实体方面使用LocalDate
。它是现代Java日期和时间API java.time的一部分,并且完全代表没有日期的日期。您使用的Date
类设计欠佳,过时了,不建议使用。同样,尽管名称Date
从未表示日期,但表示时间点。
还有更多选择。我要介绍三个。
从XMLGregorianCalendar
到LocalDate
:
DatatypeFactory xmlFactory = DatatypeFactory.newInstance();
XMLGregorianCalendar wsDate = xmlFactory
.newXMLGregorianCalendarDate(2019, DatatypeConstants.MARCH, 30,
DatatypeConstants.FIELD_UNDEFINED);
// Validate
if ((wsDate.getHour() != 0 && wsDate.getHour() != DatatypeConstants.FIELD_UNDEFINED)
|| (wsDate.getMinute() != 0 && wsDate.getMinute() != DatatypeConstants.FIELD_UNDEFINED)
|| (wsDate.getSecond() != 0 && wsDate.getSecond() != DatatypeConstants.FIELD_UNDEFINED)
|| (wsDate.getMillisecond() != 0 && wsDate.getMillisecond() != DatatypeConstants.FIELD_UNDEFINED)) {
System.out.println("Warning: time of day will be lost in conversion");
}
if (wsDate.getTimezone() != DatatypeConstants.FIELD_UNDEFINED) {
System.out.println("Warning: UTC offset will be lost in conversion");
}
// Convert
LocalDate entityDate = LocalDate.of(wsDate.getYear(), wsDate.getMonth(), wsDate.getDay());
System.out.println(entityDate);
在这种情况下,输出为:
2019-03-30
从LocalDate
到XMLGregorianCalendar
:
LocalDate entityDate = LocalDate.of(2019, Month.MARCH, 31);
XMLGregorianCalendar wsDate = xmlFactory.newXMLGregorianCalendarDate(
entityDate.getYear(),
entityDate.getMonthValue(),
entityDate.getDayOfMonth(),
DatatypeConstants.FIELD_UNDEFINED);
System.out.println(wsDate);
2019-03-31
这种方式的优点:非常简单。缺点:您和您的读者需要注意以正确的顺序提及这些字段。
// Validate as before
// Convert
LocalDate entityDate = LocalDate.parse(wsDate.toXMLFormat());
结果和以前一样。
XMLGregorianCalendar wsDate
= xmlFactory.newXMLGregorianCalendar(entityDate.toString());
优点:它很简短,结果正确是不足为奇的。缺点:对我来说,将其格式化为字符串以将其解析回来是一种浪费。
GregorianCalendar
和ZonedDateTime
进行转换 ZonedDateTime zdt = wsDate.toGregorianCalendar().toZonedDateTime();
// Validate
if (! zdt.toLocalTime().equals(LocalTime.MIN)) {
System.out.println("Warning: time of day will be lost in conversion");
}
if (! zdt.getZone().equals(ZoneId.systemDefault())) {
System.out.println("Warning: UTC offset will be lost in conversion");
}
// Finish conversion
LocalDate entityDate = zdt.toLocalDate();
另一种方式:
// It doesn’t matter which time zone we pick
// since we are discarding it after conversion anyway
ZonedDateTime zdt = entityDate.atStartOfDay(ZoneOffset.UTC);
GregorianCalendar gCal = GregorianCalendar.from(zdt);
XMLGregorianCalendar wsDate = xmlFactory.newXMLGregorianCalendar(gCal);
wsDate.setTime(DatatypeConstants.FIELD_UNDEFINED, DatatypeConstants.FIELD_UNDEFINED,
DatatypeConstants.FIELD_UNDEFINED, DatatypeConstants.FIELD_UNDEFINED);
wsDate.setTimezone(DatatypeConstants.FIELD_UNDEFINED);
我在这里提出的验证比较简单,但也不太严格。如果您想进行严格的验证,则可以只使用以前的验证。
优势:我认为这是官方的方式;至少它使用提供的转换方法。我喜欢的是转换本身是直接而简短的。缺点:转换为XMLGregorianCalendar
时,我们需要将未使用的字段手动设置为undefined,这使它变得冗长。
我介绍了三种选择,各有其优缺点。当然,您也可以混合使用,但是两种方式都使用类似的转换最终可能会减少混乱。