我有两个表:Ta
和Tb
。它们具有完全相同的表结构,但表名不同。
我尝试创建一个实体类来映射表结构。我的一些常见应用程序模块将使用此实体类根据参数动态查询和更新Ta
或Tb
。可以在JPA中完成吗?如何编写程序以在运行时将实体类动态映射到不同的表?
答案 0 :(得分:44)
不确定您是否可以完全按照自己的意愿去做,但可以使用继承来产生相同的结果。
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 {
...
}
答案 1 :(得分:21)
使用注释@MappedSuperclass创建一个抽象类(模板类),然后对其进行扩展。扩展的每个类都使用@table,@entity注释,只包含一个空构造函数。所有代码都将在您的父类中。 在您的方法上使用泛型,指示您的参数实体从templateClass扩展,不再需要更改代码。适当的映射将在你经过的每个儿子身上。
答案 2 :(得分:7)
如果使用两个不同的持久性单元,也可以在不使用子类的情况下执行此操作。
每个持久性单元可以指定一组唯一的映射(包括表名)。实现此目的的一种方法是创建两个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(可能不是你想要的),但如果你想在不同的数据库(使用不同的表名)上使用相同的类,这将是一种方法。