* 將 metamodel class 定義為 持久化實體類的描述。
就像 Reflection API 需要其他接口(比如 java.lang.reflect.Field 或 java.lang.reflect.Method)來描述 java.lang.Class 的组成一樣,JPA Metamodel API 也需要其他接口(比如 SingularAttribute 和 PluralAttribute)來描述元模型类的类型及其属性。
* 持久化实体在语义上区分为 MappedSuperClass、Entity 和 Embeddable。
在 JPA 2.0 之前,这种语义区分是通过持久化类定义中的对应类级别注释来表示的。
* JPA Metamodel 在 javax.persistence.metamodel 包中描述了 3 个独立的接口:
- MappedSuperclassType
- EntityType
- EmbeddableType
* 持久化单元作用域的持久化实体在 META-INF/persistence.xml 文件的 <class> 子句中枚举。
通过 javax.persistence.metamodel.Metamodel 接口让开发人员可以在运行时使用作用域。Metamodel 接口是特定持久化单元知道的所有持久化实体的容器。
* 元模型接口是持久化单元中的类型的容器。
* 这个接口允许通过元模型元素的对应持久化实体类访问元模型元素。
* 可以在运行时浏览 EntityType<person> 获得在 Person 实体中声明的持久化属性。
* 如果应用程序在 pClass(比如 pClass.getSingularAttribute("age", Integer.class))上调用一个方法,它将返回一个 SingularAttribute<person, integer=""> 实例,该实例与实例化规范元模型类的静态 Person_.age 成员相同。
* 最重要的是,对于应用程序可以通过 Metamodel API 在运行时引用的属性,是通过实例化静态规范元模型 Person_ 类向 Java 编译器提供的。
* 除了将持久化实体分解为对应的元模型元素之外,Metamodel API 还允许访问所有已知的元模型类 (Metamodel.getManagedTypes()),或者通过类的持久化信息访问元模型类,例如 embeddable(Address.class),它将返回一个 EmbeddableType<address> 实例(ManagedType<> 的子接口)。
* 持久化元信息分为两大类:
- 持久化, ex: @Entity
- 元模型仅为持久化注释(不是映射注释)捕捉元数据。因此,使用当前版本的 Metamodel API 可以知道哪些字段是持久化的,但不能找到它们映射到的数据库列。
- 映射, ex: @Table
- 表示 Person 的持久化属性 age。
- 是 Person_ 类中的公共静态字段,Person_ 是静态、已实例化的规范元模型类,对应于原来的 Person 实体类。
- 规范的元模型类是静态的,因此它的所有成员变量都被声明为静态的(也是 public 的)。
- Person_.age 是静态成员变量之一。您可以在开发时在源代码中生成一个具体的 Person_.java 来实例化 一个规范类。
- 实例化之后,它就可以在编译期间以强类型的方式引用 Person 的持久化属性。
* JPA 2.0 提供的解决办法通过静态地公开相同的持久化属性实例化名为 Person_ 的元模型类(对应于 Person)。
- 元模型类将原来的 domain.Person 实体的每个持久化属性声明为类型为 SingularAttribute< Person,?> 的静态公共字段。
- 通过利用这个 Person_ 元模型类,可以在编译期间引用 domain.Person 的持久化属性 age — 不是通过 Reflection API,而是直接引用静态的 Person_.age 字段。
- 编译器可以根据 age 属性声明的类型实施类型检查。
- ex:QueryBuilder.gt(p.get(Person_.age), "xyz") 将导致编译器错误,因为编译器通过 QueryBuilder.gt(..) 的签名和 Person_.age 的类型可以确定 Person 的 age 属性是一个数字字段,不能与 String 进行比较。
* 元模型类被注释为 @StaticMetamodel(domain.Person.class) 以将其标记为一个与原来的持久化 domain.Person 实体对应的元模型类。
[Criteria API]
* This dynamic query definition capability, referred as Criteria API, is based on the:
- abstract persistent schema of the entities.
- their embedded objects.
- their relationships.
* The first step in constructing a query definition is specification of query roots.
- Query roots
- Specify the domain objects on which the query is evaluated.
- Is an instance of the Root
interface. - A query root is added to a CriteriaQuery by addRoot(Class c) method.
* A query domain can be further refined by joining to other domain objects.
* An attribute of a domain object can also be specified by navigating via get(String attr). The attribute should refer to a valid persistent property of the receiving domain object, however no such validation is enforced during the construction of the query definition.
* CriteriaBuilder interface
- The factory for CriteriaQuery.
- Is obtained from either an EntityManagerFactory or an EntityManager.
* queryBuilder
- 是 CriteriaQuery 的工厂,同时也是查询表达式的工厂。
- 包含构造传统 JPQL 语法支持的所有查询表达式的 API 方法,并且还包含额外的方法。
* CriteriaQuery
- 一个查询表达式节点树。
- 在传统的基于字符串的查询语言中,这些表达式节点用于指定查询子句,比如 FROM、WHERE 和 ORDER BY。
* Reference
- JPA 2.0 中的动态类型安全查询(3)
- JPA 2.0 中的动态类型安全查询(4)
- 详解JPA 2.0动态查询机制:Criteria API(1)
- 详解JPA 2.0动态查询机制:Criteria API(2)
- Part 2. Java Persistence API
沒有留言:
張貼留言