Hibernate注解之@ManyToMany

当两个类(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代码片段

        // 创建Session
        Session 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();
        // 关闭Session
        sess.close();

上述代码执行后的中间表:

这里写图片描述

上述结果说明无法通过向Label类对象的集合属性news中添加News类的对象来更改中间表。

数据库不变,更改部分hibernate代码片段至如下:

        // 创建Session
        Session 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();
        // 关闭Session
        sess.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代码片段

        // 创建Session
        Session 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();
        // 关闭Session
        sess.close();

上述代码执行后的中间表:
这里写图片描述

清空中间表,更改部分hibernate代码片段至如下:

        // 创建Session
        Session 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();
        // 关闭Session
        sess.close();

上述代码执行后的中间表:
这里写图片描述

说明两端类均可维护关联关系

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值