JPA 2.0 中的动态类型安全查询
2009-11-11 00:00:00 来源:WEB开发网类型安全查询 API 必须让您的代码能够引用 Person 类中的持久化属性 age,同时让编译器能够在编译期间检查错误。JPA 2.0 提供的解决办法通过静态地公开相同的持久化属性实例化名为 Person_ 的元模型类(对应于 Person)。
关于元信息的讨论通常都是令人昏昏欲睡的。所以我将为熟悉的 Plain Old Java Object (POJO) 实体类展示一个具体的元模型类例子(domain.Person),如清单 3 所示:
清单 3. 一个简单的持久化实体package domain;
@Entity
public class Person {
@Id
private long ssn;
private string name;
private int age;
// public gettter/setter methods
public String getName() {...}
}
这是 POJO 的典型定义,并且包含注释(比如 @Entity 或 @Id ),从而让 JPA 提供者能够将这个类的实例作为持久化实体管理。
清单 4 显示了 domain.Person 的对应静态规范元模型类:
清单 4. 一个简单实体的规范元模型package domain;
import javax.persistence.metamodel.SingularAttribute;
@javax.persistence.metamodel.StaticMetamodel(domain.Person.class)
public class Person_ {
public static volatile SingularAttribute<Person,Long> ssn;
public static volatile SingularAttribute<Person,String> name;
public static volatile SingularAttribute<Person,Integer> age;
}
元模型类将原来的 domain.Person 实体的每个持久化属性声明为类型为 SingularAttribute<Person,?> 的静态公共字段。通过利用这个 Person_ 元模型类,可以在编译期间引用 domain.Person 的持久化属性 age — 不是通过 Reflection API,而是直接引用静态的 Person_.age 字段。然后,编译器可以根据 age 属性声明的类型实施类型检查。我已经列举了一个关于此类限制的例子:QueryBuilder.gt(p.get(Person_.age), "xyz") 将导致编译器错误,因为编译器通过 QueryBuilder.gt(..) 的签名和 Person_.age 的类型可以确定 Person 的 age 属性是一个数字字段,不能与 String 进行比较。
更多精彩
赞助商链接