您的位置:首页 > 其它

hibernate实体关系映射——单边的多对多关系

2015-06-19 22:09 357 查看
//刘梦冰发表于2015-6-19

单边的多对多关系

多对一、一对多的关系只需要两个表即可,使用子表的外键与主表的主键连接就能存储主从关系。而对多对多的关系至少需要三个表,其中两个表保存两个实体类,另一个表保存关系。

下面以一个论坛文章管理为例来深入学习:

现在论坛的每个帖子都挺有相关的标签,一个帖子可以属于多个标签,因此它们之间是多对多的关系。本例就使用多对多来处理标签与帖子之间的业务逻辑。

标签类Tag中没有Post属性,但是帖子类Post中有Tag属性,它们之间是单边的多对多的关系。Tag、Post都是多方,它们的多对多关系保存在第三个表(中间表tb_tag_post)中。

Tag标签实体类只有一个id主键以及String类型的name普通属性。

Tag.java

[code]package com.lmb.hibernate.bean;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="tb_tag")
public class Tag {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Integer id;

    private String name;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}


Post帖子实体类中有id主键、标题、内容等普通属性,还有一个Set类型的多对多集合属性tags。从java代码上来看,一对多属性与多对多属性没什么区别,都是set或者list类型的集合属性。但是,它们的hibernate配置是完全不一样的,存储机制也是完全不一样的。

Post.java

[code]package com.lmb.hibernate.bean;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

@Entity
@Table(name="tb_post")
public class Post {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Integer id;

    private String title;

    @ManyToMany(fetch=FetchType.EAGER,
            cascade={CascadeType.PERSIST}
            )

    @JoinTable( //中间关系表配置
            name="tb_tag_post",
            joinColumns= @JoinColumn(name="post id",referencedColumnName="id"),
            inverseJoinColumns=@JoinColumn(name="tag_id",referencedColumnName="id"))

    private Set<Tag> tags=new HashSet<Tag>();

    @Column(columnDefinition="text")
    private String content;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public Set<Tag> getTags() {
        return tags;
    }

    public void setTags(Set<Tag> tags) {
        this.tags = tags;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

}


注意:内容content使用@Column的columnDefination指定在数据库中使用text大文本类型。而在多对多属性tags上,使用@ManyToMany指定该列为多对多属性,fetch配置加载方式, cascade配置级联保存属性。多对多属性必须使用@JoinTable指定中间表的配置,其中name指定表名,joinColumns指定该表(也就是Post对应的表)与中间表的对应关系,inverseJoinColumns指定另一端(也就是Tag对应的表)与中间表的对应关系。@joinColumn的name属性post_id、tag_id都指中间表中的列,referencedColumnName指的是实体类的关联列,默认为主键。如果为主键,referencedColumnName可省略。

将两个实体类配置到hibernate配置文件中去;

hibernate.cfg.xml

[code]<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
          "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<!-- Generated by MyEclipse Hibernate Tools.                   -->
<hibernate-configuration>

    <session-factory>
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/hibernate?characterEncoding=UTF-8</property>
        <property name="connection.username">lmb</property>
        <property name="connection.password">lmb</property>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>

        <mapping class="com.lmb.hibernate.bean.Post" />
        <mapping class="com.lmb.hibernate.bean.Tag" />

    </session-factory>

</hibernate-configuration>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: