@SecondaryTable 注解

在正式了解 @SecondaryTable 注解用法之前,我们先看看一个关于主表(users)和子表(users_ext)的实例:

上图中,users 为主表,该表记录了用户主要信息;users_ext 为子表(也称为附表),该表用来记录用户的扩展信息。我们可以使用 @SecondaryTable 注解将一个实体中的数据分别存储到不同的数据表中。

@SecondaryTable

@SecondaryTable 注解的主要用是将主表提取成公共表,子表是自行定义。@SecondaryTable 和 @Table 注解一样,也支持如下属性:

name

该属性用于指定数据库表名称,即主表的附表名称;例如:

// users_ext 为副表
@SecondaryTable(name = "users_ext",
        pkJoinColumns = @PrimaryKeyJoinColumn(name = "user_id")
)

catalog

可选属性,用于指定数据库实例名,一般来说 persistence.xml 文件中必须指定数据库 url,url 中将包含数据库实例;

schema

作用与 catalog 属性作用一致,可自行测试;

uniqueConstraints

该属性用于设定约束条件,即唯一性约束;

pkJoinColumns

指定用于和主表连接的列;例如:

// user_id 用来和主表进行关联
@SecondaryTable(name = "users_ext",
        pkJoinColumns = @PrimaryKeyJoinColumn(name = "user_id")
)

实例

使用 @SecondaryTable 将 users 和 users_ext 表进行关联(根据 user_id 列进行关联),将 User7 实体中的数据分别存储到 users 主表 和 users_ext 附表。代码如下:

@Entity
@Table(name = "users")
@SecondaryTable(name = "users_ext",
        pkJoinColumns = @PrimaryKeyJoinColumn(name = "user_id")
)
public class User7 {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(table = "users")
    private Integer id;

    @Column(name = "name", table = "users")
    private String name;

    @Column(precision = 8, table = "users")
    private Integer age;

    // 下面字段数据来自 users_ext 表
    @Column(name = "user_id", table = "users_ext")
    private Integer userId;

    @Column(name = "email", table = "users_ext")
    private String email;

    @Column(name = "home_url", table = "users_ext")
    private String homeUrl;

}

客户端代码,使用 EntityManager 实例插入和查询 User7 对应的数据,代码如下:

import com.alibaba.fastjson.JSONObject;
import com.huangx.openjpa.annotation.entity.User7;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import java.util.List;

public class OpenJpaDemo7 {
    /** 持久化单元名称 */
    private static final String NAME = "openJPA";

    public static void main(String[] args) {
        EntityManagerFactory emf = Persistence.createEntityManagerFactory(NAME);
        EntityManager em = emf.createEntityManager();
        em.getTransaction().begin();

        // INSERT
        User7 user = new User7();
        user.setName("武松-" + System.currentTimeMillis());
        user.setAge(27);
        user.setEmail("wusong@outlook.com");
        user.setHomeUrl("http://www.wusong.com/index.html");
        em.persist(user);

        // SELECT
        String qlString = "select t from User7 t";
        Query query = em.createQuery(qlString);
        List<User7> userList = (List<User7>) query.getResultList();
        for (User7 item : userList) {
            System.out.println(JSONObject.toJSONString(item));
        }

        em.getTransaction().commit();
        em.close();
        emf.close();
        System.out.println("finished.");
    }

}

如果在 @Entity 实体上未指定 @SecondaryTable 注释,则实体的所有可持久化字段或属性都映射到主表。

如果注释 @SecondaryTable 未指定主键连接列(pkJoinColumns 属性),则假设连接列引用主表的主键列。实例:

@Entity
@Table(name = "users")
@SecondaryTable(name = "users_ext2")
public class User9 {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(table = "users")
    private Integer id;

    @Column(name = "name", table = "users")
    private String name;

    @Column(precision = 8, table = "users")
    private Integer age;

    // 下面字段数据来自 users_ext 表
    @Column(name = "email", table = "users_ext2")
    private String email;

    @Column(name = "home_url", table = "users_ext2")
    private String homeUrl;

}

等价于

@SecondaryTable(name = "users_ext2", pkJoinColumns = {
        @PrimaryKeyJoinColumn(name = "USER9_ID")
}

上面实例将自动在 users_ext 表中创建一个 user9_id 字段来存放关联主键,SQL 脚本如下:

CREATE TABLE `users_ext2` (
  `email` varchar(255) DEFAULT NULL,
  `home_url` varchar(255) DEFAULT NULL,
  `USER9_ID` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

@SecondaryTables

该注解用来为一个实体指定多个辅助表。例如:

实例1:多个辅助表假设所有表中的主键列名称相同。

@Entity
@Table(name="users")
@SecondaryTables({
    @SecondaryTable(name="users_ext"),
    @SecondaryTable(name="users_ext2")
})
public class User9 {
    // ...
}

实例2:具有不同名称的主键列的多个辅助表。

@Entity
@Table(name="users")
@SecondaryTables({
    @SecondaryTable(name="users_ext", 
        pkJoinColumns=@PrimaryKeyJoinColumn(name="user_id")),
    @SecondaryTable(name="users_ext2", 
        pkJoinColumns=@PrimaryKeyJoinColumn(name="user9_id"))
})
public class User9 {
    // ...
}
说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号