Java 什么是持久化扩展类的适当方法?
考虑下图: 我在JPA工作了很短一段时间,到目前为止,我从来没有需要持久化扩展类。。。如示例所示,Java 什么是持久化扩展类的适当方法?,java,spring,hibernate,jpa,spring-data-jpa,Java,Spring,Hibernate,Jpa,Spring Data Jpa,考虑下图: 我在JPA工作了很短一段时间,到目前为止,我从来没有需要持久化扩展类。。。如示例所示,SNMPNode、IPNode等都是Node的扩展类,也是从GeoLocation的扩展类 我知道我可以用@MappedSuperclass和IPNode注释主类,SNMPNode将继承它们的属性以持久化。。。但在这个场景中,我将得到几乎相同的表,据我所知,我可以将所有信息分组到节点中并使用单个表,而不是这样做 这是JPA上扩展类的持久性工作的方式还是我的概念是错误的 与恢复的代码相同: publ
SNMPNode
、IPNode
等都是Node
的扩展类,也是从GeoLocation
的扩展类
我知道我可以用@MappedSuperclass
和IPNode
注释主类,SNMPNode
将继承它们的属性以持久化。。。但在这个场景中,我将得到几乎相同的表,据我所知,我可以将所有信息分组到节点中并使用单个表,而不是这样做
这是JPA上扩展类的持久性工作的方式还是我的概念是错误的
与恢复的代码相同:
public class Node extends GeoLocation {
private String name;
private Group group;
private Location location;
private Type type;
private Company company;
}
public class IPNode extends Node {
private Long id;
private String ipAddress;
}
public class SNMPNode extends Node {
private Long id;
private SNMPServer server;
}
[[根据这一点的答案进行编辑]
为了做出贡献,这里有一个我最终要做的示例:
INode:
public interface INode {
public Long getId();
public void setId(Long id);
public String getName();
public void setName(String name);
public String getIpAddress();
public void setIpAddress(String ipAddress);
public String getCommunity();
public void setCommunity(String community);
}
节点:
IPNode:
@Entity
@DiscriminatorValue("I")
public class IPNode extends Node {
private String ipAddress;
public String getIpAddress() { return this.ipAddress;}
public void setIpAddress(String ipAddress) { this.ipAddress = ipAddress; }
(... Overrides from INode ...)
}
SNMPNode:
@Entity
@DiscriminatorValue("S")
public class SNMPNode extends Node {
private String community;
public String getCommunity() { return community;}
public void setCommunity(String community) { this.community = community; }
(... Overrides from INode ...)
}
NodeRepository:
@Repository
public interface NodeRepository extends JpaRepository<Node, Long> { }
两种节点类型都保存在同一个表中,因此它们的键不能重复。。。我的RESTURL可以通过/nodes/1或/nodes/2获取它们,这毕竟是我的主要目标
谢谢:)如果您的基类是用
@MappedSuperclass
注释的,那么继承只与OOP上下文相关。@MappedSuperclass
属性只需复制到每个子类关联的数据库表中,您只能查询子类实体
以无法声明所有特定子类属性(因为所有基类和所有子类特定属性都将被放入单个数据库表)为代价,产生最佳性能(不涉及联接或联合)
使用,可以在基本数据库表中具有基类属性,并且每个特定的子类都有自己的关联表。子类表通过FK与基础数据库表链接,因此需要连接这些表以获取子类实体。正如前面提到的
@MappedSuperclass
,基类是可查询的,因为OOP上下文和数据库都反映了继承模型。简单检查google(“jpa继承”):您将得到非常好的文档。示例表使其非常容易理解。谢谢。你的回答和这些文件让我很容易理解。谢谢我主要担心的是,这将是一个REST应用程序,节点将使用类似于/Nodes/的URL进行检索。但我希望IPNode或SNMPNode使用相同的URL,而在这些类上使用ID将不起作用,因为它们可能会重复。。。我想我需要一个带有ID字段的抽象节点类,然后在任何表继承之间做出决定。
@Repository
public interface NodeRepository extends JpaRepository<Node, Long> { }
@ContextConfiguration("classpath:/spring/application-context.xml")
@RunWith(SpringJUnit4ClassRunner.class)
public class NodeRepositoryTest {
@Autowired
NodeRepository repo;
private INode node;
@Before
@Transactional
@Rollback(false)
public void setup() {
node = new IPNode();
node.setName("ipNode");
node.setIpAddress("1.1.1.1");
repo.save((IPNode)node);
node = new SNMPNode();
node.setName("snmpNode");
node.setIpAddress("2.2.2.2");
node.setCommunity("some text");
repo.save((SNMPNode)node);
}
@Test
@Transactional
public void Test() throws Exception {
INode testNode = repo.findOne(1L);
assertNotNull(testNode);
}
}