我有两张桌子:Ta
和Tb
。它们具有完全相同的表结构,但表名不同。
我尝试创建一个实体类来映射表结构。我的一些常见的应用程序模块将使用这个实体类来动态查询和更新Ta
或者Tb
基于参数。可以在JPA中完成吗?如何编写程序以在运行时将实体类动态映射到不同的表?
不确定您是否可以完全按照您的意愿进行操作,但您可以使用继承来产生相同的结果。
AbsT 具有所有字段,但没有 @Table 注释
Ta 和 Tb 继承自 AbsT 并且每个都有一个 @Table 注释
利用
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
在 AbsT。
示例代码:
@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 {
...
}
创建一个带有注解 @MappedSuperclass 的抽象类(模板类),然后扩展它。扩展的每个类都使用@table、@entity 注释并且只包含一个空的构造函数。所有代码都将在您的父类中。在您的方法上使用泛型指示您的参数实体从 templateClass 扩展,并且不需要更多的代码更改。正确的映射将在您传递的每个儿子中。
如果您使用两个不同的持久性单元,您也可以在不使用子类的情况下执行此操作。
每个持久性单元都可以指定一组唯一的映射(包括表名)。实现此目的的一种方法是创建两个 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(可能不是您想要的),但是如果您想在不同的数据库(具有不同的表名)上使用相同的类,这将是一种方法。