【问题标题】:Custom ORMLite Persister to Return Wrapper Objects自定义 ORMLite 持久化以返回包装器对象
【发布时间】:2013-03-28 16:58:42
【问题描述】:

我正在编写一个使用 ORMLite 连接到后端数据库的应用程序。由于该应用程序将通过 VPN 运行,因此我正在尽量减少数据库调用。

为了尽量减少数据库调用,我创建了一组类来包装每个字段的值。每个包装类存储从数据库返回的原始值以及当前值。这允许诸如恢复到原始值或检查该值是否脏(即仅在一个或多个字段脏时更新数据库)之类的事情。

这对于 ORMLite 的含义是 ORMLite 在查询数据库时从不返回 null 值(即使数据库返回 null)。如果数据库中有 null 值,它会返回一个完全初始化的“包装器”,其中 currentValueoriginalValue 变量设置为 null。

似乎这样做的正确位置是在自定义持久化器中,例如(其中StatefulIntegerPropertyInteger 的包装器):

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
    }
}

我有三个问题:

  1. 这是正确的方法吗?
  2. 在 ORMLite FieldType.resultToJava 函数中,它似乎会进行空值检查,如果数据库返回空值,它将用 null 替换我的包装器。现在我通过覆盖持久化器中的isStreamType 方法以返回true 来解决这个问题。这是最好的方法吗?我以后会发现意外的负面影响吗?
  3. 自定义持久化器中的resultToSqlArgsqlArgToJava 方法有什么区别,具体来说,我应该使用其中哪一个来包装从数据库返回的值,然后我应该在其他?

【问题讨论】:

    标签: ormlite


    【解决方案1】:

    这是正确的方法吗?

    我不明白为什么您在这里所做的任何事情都会最大限度地减少数据库调用。您可以在users' mailing list 上开始讨论吗?

    现在,当我认为您需要 sqlArgToJava(...) 时,您正在覆盖 resultToSqlArg(...) 方法。见下文。

    现在我通过覆盖持久化器中的 isStreamType 方法以返回 true 来解决这个问题。这是最好的方法吗...

    嗯。如果它可以正常工作,但以这种方式使用此设置似乎很危险。如果我更改了 isStreamType() 方法的行为,那么这可能会破坏您的代码。至少你应该有单元测试来确认如果你升级 ORMLite 会破坏这种行为。

    也就是说,如果 isStreamType() 为真,则代码中的处理特别好,特别是围绕 null 值。

    resultToSqlArg 和 sqlArgToJava 有什么区别...

    我已经充实了这些的 javadocs。

    • resultToSqlArg 从 SQL 结果中获取对象并将其转换为适合作为 SQL 命令参数的 java 对象。例如,如果您有一个长日期类型,这将从数据库结果中提取一个Long 值。
    • sqlArgToJava 获取 sql-arg 值并将其转换为我们的 Java 字段。例如,如果您有一个 date-long 类型,这将采用 Long 值并将其转换为与实体字段匹配的 Date

    我认为你应该覆盖 sqlArgToJava resultToSqlArg

    【讨论】:

    • 感谢您的回复。我的逻辑是,存储从数据库中检索到的值意味着我不必查询数据库来检查记录是否脏,如果记录不脏,我就不必向数据库发送更新。此外,如果用户想要恢复他们的更改,我不必查询数据库来获取原始值。我确实将其发布到邮件列表以供进一步讨论。
    • 重写 sqlArgToJava 函数的问题似乎是,如果 resultToSqlArg 返回 null 值,则 BaseFieldConverter.resultToJava 方法将返回 null 并且永远不会调用 sqlArgToJava 方法。
    猜你喜欢
    • 2015-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-01
    • 1970-01-01
    相关资源
    最近更新 更多