有时候你可能会想要在一个entity里面用到存储在两个表中的数据。你只需要一个entity类,不过数据是分开存储在两张表里面的,这种情况在处理遗留数据库的时候尤为多见。JPA允许你在一个entity类里面使用到一个以上表的数据,对应的注解为@javax.persistence.SecondaryTable。客户类里面有个属性用来存储客户的地址,不过相关的地址数据却是存储在另外一个表里面的。这两张表的结构为:
create table CUSTOMER_TABLE
(
CUST_ID integer Primary Key Not Null,
FIRST_NAME varchar(20) not null,
LAST_NAME varchar(50) not null
);
create table ADDRESS_TABLE
(
ADDRESS_ID integer primary key not null,
STREET varchar(255) not null,
CITY varchar(255) not null,
STATE varchar(255) not null
);
想要使用@SecondaryTable注解,那么ADDRESS_TABLE的主键列必须与CUSTOMER_TABLE中的一列或多列有关联。
public @interface SecondaryTable
{
String name( );
String catalog( ) default "";
String schema( ) default "";
PrimaryKeyJoinColumn[] pkJoinColumns( ) default {};
UniqueConstraint[] uniqueConstraints( ) default {};
}
public @interface PrimaryKeyJoinColumn
{
String name( ) default "";
String referencedColumnName( ) default "";
String columnDefinition( ) default "";
}
@SecondaryTable一眼看上去与@Table注解很像,只是多了一个pkJoinColumns( )属性。在客户类中,你需要加上这个注解,并且使用嵌入式注解@PrimaryKeyJoinColumn来将ADDRESS_TABLE表的主键标注出来。@PrimaryKeyJoinColumn注解的name属性用来指定在当前关联中用来维护关系的列。referencedColumnName属性指定了CUSTOMER_TABLE表中用来与ADDRESS_TABLE表关联的列。
package com.titan.domain;
import javax.persistence.*;
import com.acme.imaging.JPEG;
@Entity
@Table(name="CUSTOMER_TABLE")
@SecondaryTable(name="ADDRESS_TABLE",
pkJoinColumns={
@PrimaryKeyJoinColumn(name="ADDRESS_ID")})
public class Customer implements java.io.Serializable {
...
@PrimaryKeyJoinColumn指明了ADDRESS_TABLE表中与CUSTOMER _TABLE表的主键关联的列。在这里,我们使用的是ADDRESS_ID。我们这里没有明确指定referencedColumnName属性的值,因为它会自动使用客户类的主键列。
下一步,我们来关联ADDRESS_TABLE表中的street、city、state列。如果你仔细看过@Column注解,那么你可能会记得,里面有个属性我们不常用到,就是table,我们使用这个属性来将地址相关的属性映射到其他表中:
package com.titan.domain;
import javax.persistence.*;
import com.acme.imaging.JPEG;
@Entity
@Table(name="CUSTOMER_TABLE")
@SecondaryTable(name="ADDRESS_TABLE",
pkJoinColumns={
@PrimaryKeyJoinColumn(name="ADDRESS_ID")})
public class Customer implements java.io.Serializable {
private long id;
private String firstName;
private String lastName;
private String street;
private String city;
private String state;
...
@Column(name="STREET", table="ADDRESS_TABLE")
public String getStreet( ) { return street; }
public void setStreet(String street) { this.street = street; }
@Column(name="CITY", table="ADDRESS_TABLE")
public String getCity( ) { return city; }
public void setCity(String city) { this.city = city; }
@Column(name="STATE", table="ADDRESS_TABLE")
public String getState( ) { return state; }
public void setState(String state) { this.state = state; }
...
接下来你可能会要问,如果我需要在这里映射超过两张表,该怎么办?比如你想要嵌入信用卡信息,但是信用卡信息又是存储在另外一张表中了。这里我们就要用到@SecondaryTables注解了。
package com.titan.domain;
import javax.persistence.*;
import com.acme.imaging.JPEG;
@Entity
@Table(name="CUSTOMER_TABLE")
@SecondaryTables({
@SecondaryTable(name="ADDRESS_TABLE",
pkJoinColumns={@PrimaryKeyJoinColumn (name="ADDRESS_ID")}),
@SecondaryTable(name="CREDIT_CARD_TABLE",
pkJoinColumns={@PrimaryKeyJoinColumn (name="CC_ID")})
})
public class Customer
然后你就可以将相关的属性通过@Column.table来指定了。
最后我们来看一下在xml配置文件里面,我们该如何写:
<entity-mappings>
<entity class="com.titan.domain.Customer" access="PROPERTY">
<table name="CUSTOMER_TABLE"/>
<secondary-table name="ADDRESS_TABLE">
<primary-key-join-column name="ADDRESS_ID"/>
</secondary-table>
<secondary-table name="CREDIT_CARD_TABLE">
<primary-key-join-column name="CC_ID"/>
</secondary-table>
<attributes>
<id name="id">
<generated-value/>
</id>
<basic name="street">
<column name="STREET" table="ADDRESS_TABLE"/>
</basic>
...
</attributes>
</entity>
</entity-mappings>
<secondary-table>可以在<entity>内被多次定义。<primary-key-join-column>标签为<secondary-table>标签的子标签,其属性有name、referenced-column-name、column-definition。我们使用<column>标签的table属性来指定某一列是否存储在其他表中。
分享到:
相关推荐
通过 `@SecondaryTable` 注解可以将一个实体映射到多个表,常用于分离数据结构。 #### 映射查询 - `@NamedQuery` 和 `@NamedNativeQuery` 用于定义预编译的 HQL 或 SQL 查询,提高性能。 - `@Query` 注解允许在...
- `@SecondaryTable`和`@SecondaryTables`:当一个实体需要映射到多个表时使用。 2. **数据库模式属性**: - `@Column`:定义字段对应的数据库列名和属性。 - `@JoinColumn`和`@JoinColumns`:用于建立实体间的...
- `@SecondaryTable`, `@SecondaryTables`:用于将一个实体映射到多个数据库表。 - `@Column`, `@JoinColumn`, `@JoinColumns`:控制实体属性如何映射到数据库列,以及外键的设置。 - `@PrimaryKeyJoinColumn`, `...
4. `@SecondaryTable`: 将实体映射到多个数据库表。 八、实战应用 在实际开发中,利用Hibernate Annotations可以快速构建数据访问层,减少XML配置,提高开发效率。例如,通过注解定义一个用户实体,包括ID、用户名...
使用类级别的`@SecondaryTable`和`@SecondaryTables`注解可以实现单个实体到多个表的映射。例如: ```java @Entity @Table(name="MainCat") @SecondaryTables({ @SecondaryTable(name="Cat1", pkJoinColumns={ @...
- **@SecondaryTable** / **@SecondaryTables**:当实体类需要映射到多个表时使用。 - **@Column**:指定实体属性映射到表中的哪一列。 - **@JoinColumn** / **@JoinColumns**:定义一对多或多对多关系时,用于...
10. **多表查询与联合实体**:Hibernate支持多表查询,通过@JoinTable、@SecondaryTable等注解,可以实现跨表操作。联合实体(Component)则允许将多个属性组合成一个逻辑单元,方便处理复杂对象结构。 综上所述,...