Jas*_*oor 32 java postgresql jpa
我们有一个postgres数据库与postgres枚举.我们开始在我们的应用程序中构建JPA.我们还有Java枚举,它反映了postgres枚举.现在最大的问题是如何让JPA一方面理解Java枚举,另一方面知道postgres枚举?Java方面应该相当容易,但我不知道如何做postgres方面.
Arj*_*jms 22
这涉及制作多个映射.
首先,JDBC驱动程序将Postgres枚举作为PGObject类型的实例返回.它的type属性具有postgres枚举的名称,value属性具有其值.(但序数并未存储,因此从技术上讲,它不再是枚举,因此可能完全没用)
无论如何,如果你在Postgres中有这样的定义:
CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy');
然后结果集将包含一个PGObject,其类型为"mood",值为"happy",表示具有此枚举类型的列和值为"happy"的行.
接下来要做的是编写一些拦截器代码,它位于JPA从原始结果集读取的位置和设置实体上的值之间.例如,假设您在Java中有以下实体:
public @Entity class Person {
public static enum Mood {sad, ok, happy}
@Id Long ID;
Mood mood;
}
不幸的是,JPA没有提供一个简单的拦截点,您可以在其中执行从PGObject到Java enum Mood的转换.然而,大多数JPA供应商都有一些专有支持.例如,Hibernate具有TypeDef和Type注释(来自Hibernate-annotations.jar).
@TypeDef(name="myEnumConverter", typeClass=MyEnumConverter.class)
public @Entity class Person {
public static enum Mood {sad, ok, happy}
@Id Long ID;
@Type(type="myEnumConverter") Mood mood;
这些允许您提供实际转换的UserType实例(来自Hibernate-core.jar):
public class MyEnumConverter implements UserType {
private static final int[] SQL_TYPES = new int[]{Types.OTHER};
public Object nullSafeGet(ResultSet arg0, String[] arg1, Object arg2) throws HibernateException, SQLException {
Object pgObject = arg0.getObject(X); // X is the column containing the enum
try {
Method valueMethod = pgObject.getClass().getMethod("getValue");
String value = (String)valueMethod.invoke(pgObject);
return Mood.valueOf(value);
}
catch (Exception e) {
e.printStackTrace();
}
return null;
}
public int[] sqlTypes() {
return SQL_TYPES;
}
// Rest of methods omitted
}
这不是一个完整的工作解决方案,而只是一个快速指针,希望是正确的方向.
小智 19
我实际上使用的方法比使用PGObject和Converters的方式更简单.因为在Postgres中,enum很自然地转换为文本,所以你只需要让它做它最擅长的事情.如果他不介意的话,我会借用Arjan的情绪例子:
Postgres中的枚举类型:
CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy');
Run Code Online (Sandbox Code Playgroud)
Java中的类和枚举:
public @Entity class Person {
public static enum Mood {sad, ok, happy};
@Enumerated(EnumType.STRING)
Mood mood;
Run Code Online (Sandbox Code Playgroud)
}
@Enumerated标记表示枚举的序列化/反序列化应该在文本中完成.没有它,它使用int,这比任何东西都麻烦.
此时您有两种选择.你要么:
要么:
创建从varchar到数据库中枚举的隐式转换.所以在第二种情况下,数据库接收一些赋值或比较,如'enum = varchar',它在其内部目录中找到一条规则,说它可以通过varchar的序列化函数传递右手值,然后是反序列化函数.枚举.这比我们需要的步骤更多; 并且在目录中有太多隐式强制转换可能导致任意查询具有模糊的解释,因此请谨慎使用它.演员创作是:
创建CAST(字符变化为情绪),而不是隐含的;
应该只是这样.
归档时间: |
|
查看次数: |
17839 次 |
最近记录: |