当两个类(a,b)使用@ManyToMany注解时,会产生一个中间表a_b,该中间表表示两个类的关联关系,此时有两种情况:只有一端(类)维护该关联关系,两端(类)均可维护该关联关系。
现有一新闻类Label和一标签类News,其为多对多的关系,使用@ManyToMany注解
情况一:只有一端(类)维护该关联关系
若仅News端可维护该关联关系,则意为只能通过向News类对象的集合属性labels中添加Label类的对象来更改中间表,即维护关联关系,测试代码如下:
News类
@Entity
@Table(name="news_inf")
public class News{
//新闻编号,设置为自动增长@Id@Column(name="newId")@GeneratedValue(strategy=GenerationType.IDENTITY)private Integer newId;//新闻标题private String title;//新闻的标签@ManyToMany(targetEntity = Label.class)@JoinTable(name = "new_label", joinColumns = { @JoinColumn(name = "newsId", referencedColumnName = "newId") }, inverseJoinColumns = { @JoinColumn(name = "labelId", referencedColumnName = "labelId") })private Set<Label> labels = new HashSet<Label>();……省略setter和getter方法
}
Label类
@Entity
@Table(name="label_inf")
public class Label {
//新闻编号,设置为自动增长@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Integer labelId;//标签内容private String text;//标上该标签的新闻@ManyToMany(mappedBy="labels")private Set<News> news = new HashSet<News>();……省略setter和getter方法
}
初始数据库表:
News表
Label表
中间表
部分hibernate代码片段
// 创建SessionSession sess = sf.openSession();// 开始事务Transaction tx = sess.beginTransaction();Label l = new Label();l.setLabelId(1);News n1 = new News();n1.setNewId(1);News n2 = new News();n2.setNewId(2);l.getNews().add(n1);l.getNews().add(n2);sess.update(l); // 提交事务tx.commit();// 关闭Sessionsess.close();
上述代码执行后的中间表:
上述结果说明无法通过向Label类对象的集合属性news中添加News类的对象来更改中间表。
数据库不变,更改部分hibernate代码片段至如下:
// 创建SessionSession sess = sf.openSession();// 开始事务Transaction tx = sess.beginTransaction();Label l1 = new Label();l1.setLabelId(1);Label l2 = new Label();l2.setLabelId(2);News n1 = new News();n1.setNewId(1);n1.getLabels().add(l1);n1.getLabels().add(l2);sess.update(n1); // 提交事务tx.commit();// 关闭Sessionsess.close();
上述代码执行后的中间表:
上述结果说明可以通过向News类对象的集合属性labels中添加Label类的对象来更改中间表
情况二:两端(类)均可维护该关联关系
测试代码如下:
News类
@Entity
@Table(name="news_inf")
public class News {
//新闻编号,设置为自动增长@Id@Column(name="newId")@GeneratedValue(strategy=GenerationType.IDENTITY)private Integer newId;//新闻标题private String title;//新闻的标签@ManyToMany(targetEntity = Label.class)@JoinTable(name = "new_label", joinColumns = { @JoinColumn(name = "newsId", referencedColumnName = "newId") }, inverseJoinColumns = { @JoinColumn(name = "labelId", referencedColumnName = "labelId") })private Set<Label> labels = new HashSet<Label>();……省略setter和getter方法
}
Label类
@Entity
@Table(name="label_inf")
public class Label {
//新闻编号,设置为自动增长@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Integer labelId;//标签内容private String text;//标上该标签的新闻@ManyToMany(targetEntity = News.class)@JoinTable(name = "new_label", joinColumns = { @JoinColumn(name = "labelId", referencedColumnName = "labelId") }, inverseJoinColumns = { @JoinColumn(name = "newsId", referencedColumnName = "newId") })private Set<News> news = new HashSet<News>();……省略setter和getter方法
}
初始数据库表:
News表
Label表
中间表
部分hibernate代码片段
// 创建SessionSession sess = sf.openSession();// 开始事务Transaction tx = sess.beginTransaction();Label l1 = new Label();l1.setLabelId(1);Label l2 = new Label();l2.setLabelId(2);News n1 = new News();n1.setNewId(1);n1.getLabels().add(l1);n1.getLabels().add(l2);sess.update(n1);// 提交事务tx.commit();// 关闭Sessionsess.close();
上述代码执行后的中间表:
清空中间表,更改部分hibernate代码片段至如下:
// 创建SessionSession sess = sf.openSession();// 开始事务Transaction tx = sess.beginTransaction();Label l = new Label();l.setLabelId(1);News n1 = new News();n1.setNewId(1);News n2 = new News();n2.setNewId(2);l.getNews().add(n1);l.getNews().add(n2);sess.update(l); // 提交事务tx.commit();// 关闭Sessionsess.close();
上述代码执行后的中间表:
说明两端类均可维护关联关系