我正在编写一个使用ORMLite连接到后端数据库的应用程序。由于应用程序将通过VPN运行,我正在尝试最小化数据库调用。
为了最小化数据库调用,我创建了一组类来包装每个字段的值。每个包装类都存储从数据库返回的原始值以及当前值。这允许恢复原始值,或检查值是否为脏(即,如果一个或多个字段为脏,则仅更新数据库)。
这与ORMLite的含义是,ORMLite在查询数据库时永远不会返回null
值(即使数据库返回null
)。如果数据库中存在null
值,则返回完全初始化的“包装器”,其中currentValue
和originalValue
变量设置为null。
似乎正确的地方是在自定义容器中,例如(StatefulIntegerProperty
是Integer
的包装器):
public class StatefulIntegerPersister extends BaseDataType {
... misc. other code
@Override
public Object resultToSqlArg(FieldType fieldType, DatabaseResults results, int columnPos) throws SQLException {
Integer result = results.getInt(columnPos);
return new StatefulIntegerProperty((results.wasNull(columnPos)) ? null : result);
}
@Override
public Object sqlArgToJava(FieldType fieldType, Object sqlArg, int columnPos) throws SQLException {
return sqlArg;
}
@Override
public Object javaToSqlArg(FieldType fieldType, Object obj) throws SQLException {
return ((StatefulIntegerProperty)obj).getCurrentValue();
}
@Override
public boolean isStreamType() {
return true; // this is a hack to work around ORMLite setting the value to null in the FieldType.resultToJava function
}
}
我有三个问题:
FieldType.resultToJava
函数中,它似乎进行空检查,如果数据库返回null,将用null
替换我的包装器。现在,我通过覆盖persister中的isStreamType
方法返回true来解决这个问题。这是最好的方法,我后来会发现意外的负面副作用吗?resultToSqlArg
和sqlArgToJava
方法有什么区别,具体来说,我应该使用哪一个来包装从DB返回的值,然后我该怎么办?在另一个做什么?答案 0 :(得分:1)
这是正确的方法吗?
我不明白为什么你在这里做的任何事情都会减少数据库调用。你能开始讨论users' mailing list吗?
现在,当我认为您需要resultToSqlArg(...)
时,您将覆盖sqlArgToJava(...)
方法。见下文。
现在我通过覆盖persister中的isStreamType方法来返回true来实现此目的。这是最好的方法......
槽糕。如果它工作正常,但以这种方式使用此设置似乎很危险。如果我更改了isStreamType()
方法的行为,那么这可能会破坏您的代码。至少你应该进行单元测试来确认如果你升级ORMLite会破坏这种行为。
也就是说,如果null
为真,那么代码中的isStreamType()
值会有很好的处理。
resultToSqlArg和sqlArgToJava有什么区别...
我已经充实了这些javadocs。
resultToSqlArg
从SQL结果中获取对象,并将其转换为适合作为SQL命令参数的java对象。例如,如果您有一个日期长的类型,这将从数据库结果中提取Long
值。sqlArgToJava
获取sql-arg值并将其转换为我们的Java字段。例如,如果您有一个日期长的类型,则会获取Long
值并将其转换为与实体字段匹配的Date
。我认为你应该覆盖sqlArgToJava
和而不是 resultToSqlArg
。