H2 - CREATE TABLE创建错误的数据类型

时间:2017-03-20 15:28:56

标签: jdbc h2

使用H2内存数据库测试我的DAL目前无法正常工作,因为数据tye BINARY转换为VARBINARY:

CREATE TABLE test (
  pk_user_id INT AUTO_INCREMENT(1, 1) PRIMARY KEY,
  uuid BINARY(16) UNIQUE NOT NULL
);

如果我检查是否存在具有预期数据类型的列,则会导致错误的数据类型:

  

2017-03-20 16:24:48 persistence.database.Table检查Unexpected列   (UUID)或类型(-3,VARBINARY)

1 个答案:

答案 0 :(得分:2)

TL;博士

  

导致错误的数据类型

不,不是错误的类型,只是同一类型的另一个标签

二进制类型有五个同义词:{ BINARY | VARBINARY | LONGVARBINARY | RAW | BYTEA }

所有五个名字都表示the same type,并且所有名称都映射到Java中的byte[]

数据类型名称的同义词

SQL世界中没有严格定义数据类型。 SQL规范只定义了几种类型。许多数据库系统按许多名称定义了许多类型。为了使客户更容易从一个数据库系统移植到他们的数据库系统,数据库供应商通常实现数据类型的同义词,以匹配类型兼容的竞争对手的同义词。

H2与许多其他数据库系统一样,数据类型具有多个名称。对于将整个值加载到内存中的二进制类型, H2为同一单一数据类型定义五个名称

  

{BINARY | VARBINARY | LONGVARBINARY | RAW | BYTEA}

类似地,H2通过五个同义词中的任何一个提供带符号的32位整数数据类型:

  

{INT | INTEGER | MEDIUMINT | INT4 | SIGNED}

因此,您可以指定这五个名称中的任何一个,但是您将获得相同的效果,即H2提供的相同基础数据类型。

实际上,我自己运行代码来使用二进制类型的这五个名称中的每一个来创建列。在每种情况下,列名称的元数据都会将数据类型报告为VARBINARY

虽然在内部使用五个中的哪一个来跟踪列的数据类型并不重要,但我对使用VARBINARY感到有些惊讶,因为H2 datatype documentation page标题将此类型通告为{ {1}}。所以我希望在元数据中默认使用BINARY。如果你真的在意,你可能想要记录一个bug /问题,因为似乎应该将doc标题更改为BINARY或者将H2的数据类型的内部标签更改为VARBINARY。 / p>

下面是一些示例Java JDBC代码,用于确认您在问题中报告的行为。

我建议您更改数据类型检查代码,以查找此数据类型的五个可能名称中的任何,而不是只检查一个特定名称。

BINARY
  

目录

     

COLLATIONS

     

...

     

USERS

     

视图

     

TEST _

     

表格列:test _

     

PK_USER_ID_ | 4 | INTEGER

     

UUID_ | -3 | VARBINARY

提示:

  • 在所有SQL名称中添加一个尾随下划线可以避免与SQL世界中的一千多个保留字冲突。 SQL规范承诺SQL系统永远不会使用尾随下划线。例如,您对列名try { Class.forName ( "org.h2.Driver" ); } catch ( ClassNotFoundException e ) { e.printStackTrace ( ); } try ( Connection conn = DriverManager.getConnection ( "jdbc:h2:mem:" ) ; Statement stmt = conn.createStatement ( ) ; ) { String tableName = "test_"; String sql = "CREATE TABLE " + tableName + " (\n" + " pk_user_id_ INT AUTO_INCREMENT(1, 1) PRIMARY KEY,\n" + " uuid_ BINARY(16) UNIQUE NOT NULL\n" + ");"; // String sql = "CREATE TABLE " + tableName + // "(" + // " id_ INT AUTO_INCREMENT(1, 1) PRIMARY KEY, " + // " binary_id_ BINARY(16) UNIQUE NOT NULL, " + // " uuid_id_ UUID, " + // " age_ INTEGER " + ")"; stmt.execute ( sql ); // List tables DatabaseMetaData md = conn.getMetaData ( ); try ( ResultSet rs = md.getTables ( null, null, null, null ) ) { while ( rs.next ( ) ) { System.out.println ( rs.getString ( 3 ) ); } } // List columns of our table. try ( ResultSet rs = md.getColumns ( null, null, tableName.toUpperCase ( Locale.US ), null ) ) { System.out.println ( "Columns of table: " + tableName ); while ( rs.next ( ) ) { System.out.println ( rs.getString ( 4 ) + " | " + rs.getString ( 5 ) + " | " + rs.getString ( 6 ) ); // COLUMN_NAME, DATA_TYPE , TYPE_NAME. } } } catch ( SQLException e ) { e.printStackTrace ( ); } 的使用可能与H2的uuid数据类型冲突。
  • 您的代码UUID建议您尝试存储UUID(128位值,其中某些位已定义语义)。请注意H2 supports UUID natively作为数据类型as does Postgres和其他一些数据库系统。因此,将uuid BINARY(16)更改为uuid_ BINARY(16)