Java JPA,如何使用同一个类(实体)来映射不同的表?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/997203/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JPA, How to use the same class (entity) to map different tables?
提问by
I have two tables: Ta
and Tb
. They have exactly the same table structure but different table names.
我有两个表:Ta
和Tb
。它们具有完全相同的表结构但不同的表名。
I try to create one entity class to map the table structures. Some of my common application modules will use this entity class to dynamically query and update either Ta
or Tb
based on parameters. Can it be done in JPA? How can I write the program to dynamically mapping the entity class to different tables at run time?
我尝试创建一个实体类来映射表结构。我的一些常见应用模块将使用这个实体类来动态查询和更新Ta
或者Tb
基于参数。可以在JPA中完成吗?如何编写程序以在运行时将实体类动态映射到不同的表?
回答by Glen
Not sure you can do it exactly as you want but you can use inheritance to produce the same result.
不确定您是否可以完全按照自己的意愿进行操作,但是您可以使用继承来产生相同的结果。
AbsT has all the fields but no @Table annotation
AbsT 拥有所有字段,但没有 @Table 注释
Ta and Tb inherit from AbsT and have an @Table annotation each
Ta 和 Tb 继承自 AbsT 并且每个都有一个 @Table 注释
Use
用
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
in AbsT.
在 AbsT。
Sample code:
示例代码:
@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 {
...
}
回答by Mike
You can also do this without using subclasses if you use two different persistence units.
如果您使用两个不同的持久性单元,您也可以不使用子类来执行此操作。
Each persistence unit can specify a unique set of mappings (including table name). One way to achieve this is to create two orm.xml files. In persistence.xml you'll need something like this :
每个持久化单元可以指定一组唯一的映射(包括表名)。实现此目的的一种方法是创建两个 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>
Then within orm-1.xml :
然后在 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>
And within orm-2.xml :
在 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>
You'll need to create a separate EntityManagerFactory for each PersistenceUnit (probably not what you want), but if you wanted to use the same class on different databases (with different table names) this would be a way to go.
您需要为每个 PersistenceUnit 创建一个单独的 EntityManagerFactory(可能不是您想要的),但是如果您想在不同的数据库(具有不同的表名)上使用相同的类,这将是一种方法。
回答by arbano
Create an abstract class (a template class) with annotation @MappedSuperclass then extend it. Each class that extends uses @table, @entity annotations and contains nothing but an empty constructor. All code will be in your parent class. On your methods use generics indicating your parameter entity extends from templateClass and no more code changes are needed. The proper mappings will be in each son you pass.
创建一个带有注释@MappedSuperclass 的抽象类(模板类),然后扩展它。每个扩展类都使用@table、@entity 注释并且只包含一个空构造函数。所有代码都将在您的父类中。在您的方法上使用泛型指示您的参数实体从 templateClass 扩展,并且不需要更多的代码更改。正确的映射将在您传递的每个儿子中。