【问题标题】:ORMLite Date in MySQL/MariaDB with millisecond precisionMySQL/MariaDB 中的 ORMLite 日期,精度为毫秒
【发布时间】:2013-02-03 13:32:31
【问题描述】:

ORMLite 问题。我有一组 POJO,Android 应用程序和 Java Web 服务都使用这些 POJO 来保存数据(分别保存到 SQLite 和 MariaDB)。我相信从 5.3 开始,MariaDB 支持带有长度的时间戳/日期时间,这将字段的精度扩展到微秒(MySQL 本身在新的 dev 5.6 版本中支持这一点)。

但是,即使我从命令行手动修改字段以将列设置为 DATETIME(6),我也无法让 ORMLite 以毫秒精度保存我的日期字段。我知道我可以在 POJO 中使用 DATE_LONG 或 DATE_STRING 的数据类型,但我想在 MariaDB 中使用实际的 DATETIME 类型。

有什么方法可以做到毫秒级精度吗?

【问题讨论】:

  • 所以这与 MySQL 驱动程序有关?您可能需要添加自定义数据类型:ormlite.com/docs/custom-data-types
  • 啊,你的问题让我意识到了这个问题。 MariaDB 现在实际上有自己的 JDBC java 客户端(他们奇怪地建议您仍然将连接 URI 格式化为 jdbc:mysql://)。由于 DatabaseTypeUtils 的结构,我无法为 MariaDB 驱动程序添加 BaseDatabaseType 子类……所以我只能使用 MySQL 连接器。真正酷的是,如果用户可以创建自己的 BaseDatabaseType 子类,并且 DatabaseTypeUtils 上会有一个用于 databaseTypes 的静态设置器来加载它(当然,我承认你已经涵盖了所有主要的数据库——但 MariaDB 只会变得更受欢迎)!
  • 好吧,我显然是愚蠢的......当你启动一个新的 JdbcConnectionSource / JdbcPooledConnectionSource 时,你支持传入一个 databaseType。所以我只是将 MysqlDatabaseType 子类化并做了我需要做的事情。我将代码放在下面。此外,对于可能实际尝试解决此确切问题的任何用户,您需要在 JDBC 连接字符串中设置 useFractionalSeconds 标志。灰色 - 感谢您如此迅速地回复。
  • 很高兴你明白了,马特。对您的问题和答案 +1。

标签: ormlite mariadb


【解决方案1】:

查看问题下的 cmets 以了解这里发生了什么...基本上您需要一个新的 DatabaseType(如果使用 MariaDB,那么显然只需将 MySQL 子类化):

public class MariaDBType extends MysqlDatabaseType {

    private final static String DATABASE_URL_PORTION = "mysql";
    private final static String DRIVER_CLASS_NAME = "org.mariadb.jdbc.Driver";
    private final static String DATABASE_NAME = "MariaDB";

    @Override
    public boolean isDatabaseUrlThisType(String url, String dbTypePart) {
        return DATABASE_URL_PORTION.equals(dbTypePart);
    }

    @Override
    protected String getDriverClassName() {
        return DRIVER_CLASS_NAME;
    }

    @Override
    public String getDatabaseName() {
        return DATABASE_NAME;
    }

    @Override
    protected void appendDateType(StringBuilder sb, FieldType fieldType, int fieldWidth) {
        /**
         * TIMESTAMP in MySQL does some funky stuff with the last-modification time. Values are 'not null' by default
         * with an automatic default of CURRENT_TIMESTAMP. Strange design decision.
         */
        if (isDatetimeFieldWidthSupported()) {
            sb.append("DATETIME(").append(fieldWidth).append(")");
        } else {
            sb.append("DATETIME");
        }
    }

    public boolean isDatetimeFieldWidthSupported() {
        return true;
    }
}

现在我可以像正常一样使用日期数据类型并获得毫秒或微秒精度......在我的例子中,我使用 Gray 现有的注释参数作为宽度(适用于这样的情况,我只需要毫秒精度,而不是微秒)。

@DatabaseField(columnName = Constants.TIMESTAMP, dataType = DataType.DATE, width = 3)
private Date timestamp;

最后,如果您正在尝试解决这个特定问题,请不要忘记小数秒标志:

private static JdbcPooledConnectionSource cSource = new JdbcPooledConnectionSource();
    cSource.setDatabaseType(new MariaDBType());
    cSource.setUrl("jdbc:mysql://localhost:3306/database?useFractionalSeconds=true");
    cSource.setUsername("username");
    cSource.setPassword("password");

【讨论】:

  • 这是一个很好的答案,马特。做得好。提供其他人做你所做的一切所需的所有信息。
猜你喜欢
  • 2015-06-25
  • 2017-08-31
  • 2017-06-23
  • 2011-02-04
  • 2021-01-23
  • 2020-09-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多