我从hibernate开始有几周的时间。
我有这个代码数据库
| TABLE A |
-------------------------------
idA integer not null (PK) |
name varchar(45) not null |
lastname varchar(45) not null |
| TABLE B |
-------------------------------
idB integer not null (PK) |
name varchar(45) not null |
lastname varchar(45) not null |
| TABLE A_B |
-------------------------------
idA integer not null (PK) |
idB integer not null (PK) |
这些是我在java中的实体
@Entity
public class A{
@Id
private int id;
@Column
private String name;
@Column
private String lastName;
@ManyToMany(cascade={CascadeType.ALL})
@JoinTable(name="A_B", joinColumns={@JoinColumn(name="idA")}, inverseJoinColumns={@JoinColumn(name="idB")})
private List<B> ManyB;
//Getter and Setters
}
@Entity
public class B{
@Id
private int id;
@Column
private String name;
@Column
private String lastName;
@ManyToMany(mappedBy="ManyB", cascade={CascadeType.ALL})
private List<A> ManyA;
//Getter and Setters
}
我有2个具有多对多关系的对象,我在中间表中创建了数据库,使其成为一对多的关系。我有几个问题。
1 - 。要在A_B表中添加记录,只允许我在A类中声明的列表中添加对象B,如果我反过来这样做,从A类添加对象B我在表A中添加但不在A_B表中添加。
。 2 - 如何删除或修改表A_B中的记录,而无需删除或修改表A或B中的对象。
。 3 - 当你得到所有对象的列表时,例如我得到了类A,我返回一个列表并且它包含A,并且无限递归toString,这会影响内存或程序的性能吗?
感谢您的评论。
答案 0 :(得分:2)
让我们举一个向A_B表添加记录的例子。获取User对象和Skill对象。每个用户都有很多技能,但Skill还有一个名为技能所有者的用户列表。因此,User是您的表A,Skill是您的表B,Skill-owner是多对多生成的表A_B。
现在,当我想向所有者添加技能时,它也会自动成为技能所有者。在JPA设置中,您必须在两侧添加属性。具体而言,您必须将技能组合添加到技能所有者的用户和用户的技能组中。因此,在您的服务类中,您应该处理这两个存储库。
技能实体:
@Entity
public class Skill {
@Id
@GeneratedValue
@Column(name = "skillId")
private long id;
private String skill;
@ManyToMany(fetch = FetchType.LAZY)
@JoinTable(name = "userSkillsList",
joinColumns = {@JoinColumn(name = "skillId")},
inverseJoinColumns = {@JoinColumn(name = "username")})
private Set<User> skillOwners;
}
用户实体:
@Entity
public class User {
@Id
private String username;
@ManyToMany(fetch = FetchType.LAZY,
mappedBy = "skillOwners")
private List<Skill> skillsList = new LinkedList<Skill>();
}
要向用户添加技能,您可以将以下内容添加到“技能”实体或您认为最合适的位置:
public void addSkillToUser(Long s) {
Skill skill = skillRepository.findOne(s);
selectedUser.addSkill(skill);
skill.addSkillOwner(selectedUser);
userRepository.save(selectedUser);
skillRepository.save(skill);
}
并删除:
public void deleteSkill(Skill skill) {
selectedUser.deleteSkill(skill);
skill.removeSkillOwner(selectedUser);
skillRepository.save(skill);
userRepository.save(selectedUser);
}
关于删除列表中项目的问题,您应该查看JPA / Hibernate的层叠注释。使用正确的注释,您可以仅在更新时级联,而不是在删除时级联。因此,如果在User.skillsList上设置cascade = CascadeType.UPDATE
,则只应在更新时更改技能的属性。在此处阅读有关CascadeType枚举的更多信息:http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html/objectstate.html#objectstate-transitive。
你的第三个问题我不完全明白,但你有没有为A级添加自定义toString方法?
答案 1 :(得分:0)
如果要在两个表之间建立多对多关系,请创建一对一条目的中间表。因此,您的A-B表将具有一对一的数据插入。并使用普通查询插入和删除A-B表中的记录。通过此A-B表进行所有交易。