Apache Derby中的用户定义类型作为ENUM替换

时间:2017-07-25 04:31:51

标签: java enums derby

我使用Apache Derby作为内存模拟数据库,用于测试一些使用jOOQ与MySQL协同工作的代码。

生产数据库使用某些字段的枚举(这是这个问题的一个给定和超出范围 - 我知道枚举很糟糕但我现在无法更改此部分),因此jOOQ生成代码来处理枚举

不幸的是,Derby不支持枚举,当我尝试在Derby中创建数据库时(来自jOOQ SQL生成器),我收到错误。

我的解决方案是通过包装相关的jOOQ生成的枚举Java类来模仿枚举的用户定义类型。因此,例如,如果表kind中有枚举字段stuffs,则jOOQ SQL生成器会创建描述stuffs_kind的Derby表创建SQL。

为了支持这一点,我创建了包含jOOQ生成的枚举类型my.project.tests.StuffsKindDebyEnum的类my.project.model.StuffsKind。然后,在运行jOOQ数据库创建SQL之前,我通过Derby运行以下SQL:

CREATE TYPE stuffs_kind EXTERNAL NAME 'my.project.tests.StuffsKindDerbyEnum' LANGUAGE JAVA

当我然后使用jOOQ插入新记录时,jOOQ会生成看起来像这样的SQL:

insert into "schema"."stuffs" ("text", "kind") 
  values (cast (? as varchar(32672)), cast(? as stuffs_kind)

但是将一个字符串值绑定到kind参数(如预期的那样),它适用于MySQL但是使用Derby我得到一个例外:

java.sql.SQLDataException: An attempt was made to get a data value of type
  '"APP"."STUFFS_KIND"' from a data value of type 'VARCHAR'

在查看解决此问题的各种方法之后(包括尝试将枚举视为简单的VARCHAR),在我放弃能够测试我的jOOQ使用代码之前,有没有办法让Derby进入& #34;铸造" varchar到用户定义的类型?如果可以放一些可以处理它的Java代码,那就不会有问题,因为我只需要StuffsKind.valueOf(value)将字符串转换为正确的枚举类型,但在仔细阅读(非常小的)Derby文档后,我可以& #39;弄清楚它是否应该是可能的。

欢迎任何想法!

1 个答案:

答案 0 :(得分:1)

实现方言敏感的自定义数据类型绑定:

这里正确的方法是使用方言敏感的自定义数据类型绑定: https://www.jooq.org/doc/latest/manual/sql-building/queryparts/custom-bindings

然后,绑定可以实现,例如绑定变量SQL生成如下:

google.auth.scopes=https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/plus.me email profile

您显然还必须实现其他方法,告诉jOOQ如何将您的变量绑定到JDBC @Override public void sql(BindingSQLContext<StuffsKindDerbyEnum> ctx) throws SQLException { if (ctx.family() == MYSQL) ctx.render().visit(DSL.val(ctx.convert(converter()).value())); else if (ctx.family() == DERBY) ctx.render() .sql("cast( .visit(DSL.val(ctx.convert(converter()).value())) .sql(" as varchar(255))"); else throw new UnsupportedOperationException("Dialect not supported: " + ctx.family()); } ,或者如何从PreparedStatement

获取它

避免MySQL枚举

另一种更简单的方法可能是避免特定于供应商的功能,只在两个数据库中使用ResultSet。您仍然可以使用在两个数据库中以相同方式工作的jOOQ VARCHARVARCHAR映射到Java enum类型。

通过避免Derby

简化测试

更简单的方法是直接在MySQL上测试您的应用程序,例如:在内存中的docker虚拟化。数据库供应商和他们的功能之间存在很多差异,并且在某些时候,解决这些差异只是为了获得稍快的测试并不合理。

当然,例外情况是,如果您必须在生产中同时支持Derby和MySQL,那么数据类型绑定也是最佳解决方案。