如何使用 SQLResult 从 SQLTemplate 获取 JodaTime DateTime 对象
How to get JodaTime DateTime object from SQLTemplate using SQLResult
我正在尝试 return JodaTime DateTime 对象。它适用于下面的 effective_date 字段。但我不确定如何将它获取到 Event 对象的 return DateTime。有什么想法吗?
String sql = "SELECT a.availability_id, a.event_id, a.availability_set_id, "
+ "e.event_id, "
+ "#result('e.start' 'org.joda.time.DateTime' '' 'event.start'), "
+ "#result('e.end' 'org.joda.time.DateTime' '' 'event.end'), "
+ "e.recurrence_id, "
+ "e.sequence, "
+ "e.uid, "
+ "#result('effective_date' 'org.joda.time.DateTime' '' 'effective_date'), "
+ "#result('next_effective_date' 'org.joda.time.DateTime' '' 'next_effective_date') "
<snip>
EntityResult eventResult = new EntityResult(Event.class);
eventResult.addDbField(Event.EVENT_ID_PK_COLUMN, "event_id");
eventResult.addObjectField(Event.START_PROPERTY, "start");
eventResult.addObjectField(Event.END_PROPERTY, "end")
<snip>
SQLResult resultDescriptor = new SQLResult();
resultDescriptor.addEntityResult(availabilityResult);
resultDescriptor.addEntityResult(eventResult);
<snip>
List<Object[]> dataList = context.performQuery(query);
for (Object[] data : dataList) {
Event event = (Event) data[1];
event.getStart(); // Runs into class cast error where it's returning Date instead of DateTime
}
编辑:
我已经将 Joda DateTime 添加到 ExtendedType。上述问题仅在我使用 SQLResult 构建 Event 对象时出现。
// create custom ExtendedType instance
ExtendedType dateTimeType = new DateTimeType();
DataNode node = domain.getNode("MySQLNode");
// install ExtendedType
node.getAdapter().getExtendedTypes().registerType(dateTimeType);
在不使用 SQLResult 实例化 Event 对象时效果很好。在这里,Cayenne Modeler 生成了 DateTime return 类型的 _Event class。
public abstract class _Event extends CayenneDataObject {
<snip>
public void setStart(DateTime start) {
writeProperty("start", start);
}
public DateTime getStart() {
return (DateTime)readProperty("start");
}
我已经设法做到了以下几点。我创建了以 OTHER 作为数据库类型的 DbEntity 字段和以 org.joda.time.DateTime 作为 Java 类型的 ObjEntity 字段。
它非常适合您的示例。
您也可以尝试使用任何第三方(或您自己的)ExtendedType for JodaTime DateTime。
更新 1:
此外,如果您想使用#result 指令,则需要对 SQL 模板中的每一列使用它。
更新 2:
这是一个运行良好的示例。
请注意,我使用 4.0.M3-SNAPSHOT 版本和来自 github.
的 cayenne-joda 模块
// add CayenneJodaModule to the ServerRuntime
ServerRuntime cayenneRuntime = new ServerRuntime(
"cayenne-project.xml", new CayenneJodaModule());
ObjectContext context = cayenneRuntime.newContext();
// add Joda object
Joda newJoda = context.newObject(Joda.class);
newJoda.setDatetime(new DateTime());
context.commitChanges();
String sql = "SELECT #result('j.ID' 'int' 'ID'), "
+ "#result('j.DATETIME' 'org.joda.time.DateTime' 'DATETIME') "
+ "FROM JODA j";
EntityResult jodaResult = new EntityResult(Joda.class);
jodaResult.addDbField(Joda.ID_PK_COLUMN, "ID");
jodaResult.addObjectField(Joda.DATETIME_PROPERTY, "DATETIME");
SQLResult resultDescriptor = new SQLResult();
resultDescriptor.addEntityResult(jodaResult);
SQLTemplate query = new SQLTemplate(Joda.class, sql);
query.setResult(resultDescriptor);
List<Joda> jodaList = context.performQuery(query);
for (Joda joda : jodaList) {
System.out.println(joda.getDatetime().getClass());
}
其中 _Joda.class 有:
public void setDatetime(DateTime datetime) {
writeProperty("datetime", datetime);
}
public DateTime getDatetime() {
return (DateTime)readProperty("datetime");
}
结果:
class org.joda.time.DateTime
我正在尝试 return JodaTime DateTime 对象。它适用于下面的 effective_date 字段。但我不确定如何将它获取到 Event 对象的 return DateTime。有什么想法吗?
String sql = "SELECT a.availability_id, a.event_id, a.availability_set_id, "
+ "e.event_id, "
+ "#result('e.start' 'org.joda.time.DateTime' '' 'event.start'), "
+ "#result('e.end' 'org.joda.time.DateTime' '' 'event.end'), "
+ "e.recurrence_id, "
+ "e.sequence, "
+ "e.uid, "
+ "#result('effective_date' 'org.joda.time.DateTime' '' 'effective_date'), "
+ "#result('next_effective_date' 'org.joda.time.DateTime' '' 'next_effective_date') "
<snip>
EntityResult eventResult = new EntityResult(Event.class);
eventResult.addDbField(Event.EVENT_ID_PK_COLUMN, "event_id");
eventResult.addObjectField(Event.START_PROPERTY, "start");
eventResult.addObjectField(Event.END_PROPERTY, "end")
<snip>
SQLResult resultDescriptor = new SQLResult();
resultDescriptor.addEntityResult(availabilityResult);
resultDescriptor.addEntityResult(eventResult);
<snip>
List<Object[]> dataList = context.performQuery(query);
for (Object[] data : dataList) {
Event event = (Event) data[1];
event.getStart(); // Runs into class cast error where it's returning Date instead of DateTime
}
编辑:
我已经将 Joda DateTime 添加到 ExtendedType。上述问题仅在我使用 SQLResult 构建 Event 对象时出现。
// create custom ExtendedType instance
ExtendedType dateTimeType = new DateTimeType();
DataNode node = domain.getNode("MySQLNode");
// install ExtendedType
node.getAdapter().getExtendedTypes().registerType(dateTimeType);
在不使用 SQLResult 实例化 Event 对象时效果很好。在这里,Cayenne Modeler 生成了 DateTime return 类型的 _Event class。
public abstract class _Event extends CayenneDataObject {
<snip>
public void setStart(DateTime start) {
writeProperty("start", start);
}
public DateTime getStart() {
return (DateTime)readProperty("start");
}
我已经设法做到了以下几点。我创建了以 OTHER 作为数据库类型的 DbEntity 字段和以 org.joda.time.DateTime 作为 Java 类型的 ObjEntity 字段。 它非常适合您的示例。
您也可以尝试使用任何第三方(或您自己的)ExtendedType for JodaTime DateTime。
更新 1:
此外,如果您想使用#result 指令,则需要对 SQL 模板中的每一列使用它。
更新 2:
这是一个运行良好的示例。 请注意,我使用 4.0.M3-SNAPSHOT 版本和来自 github.
的 cayenne-joda 模块 // add CayenneJodaModule to the ServerRuntime
ServerRuntime cayenneRuntime = new ServerRuntime(
"cayenne-project.xml", new CayenneJodaModule());
ObjectContext context = cayenneRuntime.newContext();
// add Joda object
Joda newJoda = context.newObject(Joda.class);
newJoda.setDatetime(new DateTime());
context.commitChanges();
String sql = "SELECT #result('j.ID' 'int' 'ID'), "
+ "#result('j.DATETIME' 'org.joda.time.DateTime' 'DATETIME') "
+ "FROM JODA j";
EntityResult jodaResult = new EntityResult(Joda.class);
jodaResult.addDbField(Joda.ID_PK_COLUMN, "ID");
jodaResult.addObjectField(Joda.DATETIME_PROPERTY, "DATETIME");
SQLResult resultDescriptor = new SQLResult();
resultDescriptor.addEntityResult(jodaResult);
SQLTemplate query = new SQLTemplate(Joda.class, sql);
query.setResult(resultDescriptor);
List<Joda> jodaList = context.performQuery(query);
for (Joda joda : jodaList) {
System.out.println(joda.getDatetime().getClass());
}
其中 _Joda.class 有:
public void setDatetime(DateTime datetime) {
writeProperty("datetime", datetime);
}
public DateTime getDatetime() {
return (DateTime)readProperty("datetime");
}
结果:
class org.joda.time.DateTime