JPA,如何使用同一个类(实体)来映射不同的表?

Posted

技术标签:

【中文标题】JPA,如何使用同一个类(实体)来映射不同的表?【英文标题】:JPA, How to use the same class (entity) to map different tables? 【发布时间】:2010-11-03 02:09:03 【问题描述】:

我有两张桌子:TaTb。它们的表结构完全相同,但表名不同。

我尝试创建一个实体类来映射表结构。我的一些常用应用程序模块将使用这个实体类根据参数动态查询和更新TaTb。可以在JPA中完成吗?如何编写程序在运行时将实体类动态映射到不同的表?

【问题讨论】:

【参考方案1】:

不确定是否可以完全按照自己的意愿进行操作,但可以使用继承来产生相同的结果。

AbsT 包含所有字段,但没有 @Table 注释

Ta 和 Tb 继承自 AbsT 并且每个都有一个 @Table 注释

使用

@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)

在摘要中。

示例代码:

@Entity
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public class abstract AbsT 
    @Id Long id;
...


@Entity
@Table(name = "Ta")
public class Ta extends AbsT 
...


@Entity
@Table(name = "Tb")
public class Tb extends AbsT 
...

【讨论】:

它确实有效,谢谢!但是,对于 Toplink,不支持 TABLE_PER_CLASS。我尝试了@mappedSuperClass 方法,它也能正常工作。 对于那些不确定 Inheritance 与 MappedSuperClass 的人,这里对它们进行了很好的描述和比较:***.com/a/9669719/2278186【参考方案2】:

创建一个带有注解@MappedSuperclass 的抽象类(模板类),然后扩展它。扩展的每个类都使用@table、@entity 注释并且只包含一个空的构造函数。所有代码都将在您的父类中。 在您的方法上使用泛型指示您的参数实体从 templateClass 扩展,并且不需要更多的代码更改。正确的映射将在您传递的每个儿子中。

【讨论】:

通常,Son 与 Child 有 IS-A 关系。【参考方案3】:

如果您使用两个不同的持久性单元,您也可以在不使用子类的情况下执行此操作。

每个持久性单元都可以指定一组唯一的映射(包括表名)。实现此目的的一种方法是创建两个 orm.xml 文件。在 persistence.xml 中你需要这样的东西:

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    version="1.0">

    <persistence-unit name="mapping-1"> 
        . . .
        <mapping-file>orm-1.xml</mapping-file>
        . . .
    </persistence-unit>

    <persistence-unit name="mapping-2"> 
        . . .
        <mapping-file>orm-2.xml</mapping-file>
        . . .
    </persistence-unit>
</persistence>

然后在 orm-1.xml 中:

<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
    version="1.0">
    <package>mypackage</package>
    <entity name="myEntity" class="myClass">
        <table name="TABLE1">
            </table>
    </entity>
</entity-mappings>

在 orm-2.xml 中:

<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
    version="1.0">
    <package>mypackage</package>
    <entity name="myEntity" class="myClass">
        <table name="TABLE2">
            </table>
    </entity>
</entity-mappings>

您需要为每个 PersistenceUnit 创建一个单独的 EntityManagerFactory(可能不是您想要的),但如果您想在不同的数据库(具有不同的表名)上使用相同的类,这将是一种方法。

【讨论】:

以上是关于JPA,如何使用同一个类(实体)来映射不同的表?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 JPA 注释的实体类生成 JPA 映射文件?

如何使用 hibernate/jpa 注释将一个类映射到不同的表

学习Spring-Data-Jpa---JPA基本注解

JPA实体类中的注解

JPA-基本注解

JPA集合映射