gpt4 book ai didi

java - 消除 Hibernate 表中一对多关系引用的重复条目

转载 作者:行者123 更新时间:2023-11-29 11:03:41 25 4
gpt4 key购买 nike

我目前正在使用一个程序,每次运行该程序时,该程序都会收到三个数值(companyName、groupName、hostName)。每次收到这三个值时,我都会将它们分组为一个对象(Datas)并将它们存储在一个列表(List)中。

我的目标是将所有值存储到包含三个表(公司、组、主机)的数据库中。

三个表是相连的:Company 与 Group 是一对多,Group 是与 Host 一对多。

因此,我创建了三个类(Company.java、Group.java、Host.java),它们将采用适当的值并使用构造函数创建该类的新实例。

然后我将使用 hibernate session 将类的每个实例存储到数据库中。

我的代码是这样的:

for (Datas data:Datas){
Company company = new Company(data.getCompanyName);
Group group = new Group(company, data.getGroupName);
Host host = new Host(group, data.getHostName);

session.save(company);
session.save(group);
session.save(host);
}

虽然上面的代码确实允许我使用正确的一对多关系将所有数据保存到表中,但它不允许我防止重复条目。

例如,现在我的表在保存 5 个数据后以这种方式存储内容:

Company
id (auto-increment) Name
1 Google
2 Google
3 Google
4 Yahoo
5 Yahoo

Group
id (auto-increment) Company_id Name
1 1 HR
2 2 HR
3 3 OP
4 4 HR
5 5 PR

Host
id (auto-increment) Group_id Name
1 1 Jane
2 2 Harry
3 3 Molly
4 4 Garry
5 5 Neo

虽然上面的表格在技术上是正确的,但我真的想消除重复项。现在在公司表中,所有“Google”和“Yahoo”条目都是完全相同的。在组表中,第一个条目和第二个条目是相同的,因为它们的名称都是“HR”,并且都引用了公司“Google”。

这样,我们将只创建 1 个公司条目,而不是创建 3 个“Google”公司条目。并且组表中的所有条目都将仅引用该条目。主机表的逻辑相同。

正确的表格应如下所示:

Company
id (auto-increment) Name
1 Google
2 Yahoo

Group
id (auto-increment) Company_id Name
1 1 HR
2 1 OP
3 2 HR
4 2 PR

Host
id (auto-increment) Group_id Name
1 1 Jane
2 1 Harry
3 3 Molly
4 4 Garry
5 5 Neo

如何在我的代码中进行此类调整?在实例化这三个类之前我应该​​对数据做一些事情吗?或者在使用类构造函数实例化时我应该做些什么?或者我可以使用 Hibernate 注释来防止这种重复?

非常感谢您的帮助。

最佳答案

您的 for 循环基本上应该根据业务自然键值查询数据库,并确定记录是否存在并根据该事实进行分支。

for ( Datas data : datas ) {
Company company = companyRepository.findByName( data.getCompanyName() );
if ( company == null ) {
// new company implies everything else is also new
company = new Company( data.getCompanyName() );
group = new Group( company, data.getGroupName() );
host = new Host( group, data.getHostName() );
session.save( company );
session.save( group );
session.save( host );
}
else {
// since company exists, we need to check whether group/host exist
Group group = groupRepository.findByName( data.getGroupName() );
if ( group == null ) {
// since group doesn't exist, neither will host
group = new Group( company, data.getGroupName() );
host = new Host( group, data.getHostName() );
session.save( group );
session.save( host );
// depending on relationships, you may need to link group to company
// followed by updating company.
}
else {
// group exists, check if host does
Host host = hostRepository.findByName( data.getHostName() );
if ( host == null ) {
// host doesn't, create it.
host = new Host( group, data.getHostName() );
session.save( host );
// depending on relationships, you may need to link host to group
// followed by updating group.
}
}
}
}

公开 #findByName(String) 方法的各种存储库类旨在说明您使用查找实体的指定名称的谓词执行的查询。

显然,如果您的 Datas 结构除了名称值之外还包含更多详细信息(还需要与现有记录合并),则您需要向循环添加逻辑以应用任何修改到由 #findByName(String 方法获取的持久对象。

// Simplified example for the Host
Host host = hostRepository.findByName( data.getHostName() );
if ( host == null ) {
host = new Host( group, data.getHostName() );
host.setSomeOtherAttribute( data.getHostSomeOtherAttribute() );
session.save( host );
}
else {
host.setsomeOtherAttribute( data.getHostSomeOtherAttribute() );
session.update( host );
}

关于java - 消除 Hibernate 表中一对多关系引用的重复条目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41774431/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com