首页 > 代码库 > Hibernate注解方式实现1-N双向关联

Hibernate注解方式实现1-N双向关联

由于Hibernate可以实现逆向工程,可以自动在数据库中创建表,因此这里不提供数据字典内容。

以微博或博客为例,用户和博客之间属于一对多的关系,即1-N型,在数据库中我们希望构建如下关系

创建用户实体类User:

import ***;

/**
 * @author Barudisshu
 */
@Entity
@Table(name = "t_user", schema = "", catalog = "db_blog")
public class User implements Serializable {

    private int id;                 //用户自动Id
    private String username;        //用户名
    private String password;        //密码

    private Collection<Post> posts; //用户博客

    @Id
    @Column(name = "id", nullable = false, insertable = true, updatable = true)
    public int getId() {
        return id;
    }

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

    @Basic
    @Column(name = "username", nullable = true, insertable = true, updatable = true, length = 255)
    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    @Basic
    @Column(name = "password", nullable = true, insertable = true, updatable = true, length = 255)
    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    //添加mappedBy属性,否则将创建中间表
    @OneToMany(cascade = CascadeType.PERSIST,targetEntity = Post.class,mappedBy = "user")
    @OrderBy("id")
    public Collection<Post> getPosts() {
        return posts;
    }

    public void setPosts(Collection<Post> posts) {
        this.posts = posts;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        User user = (User) o;

        if (id != user.id) return false;
        if (password != null ? !password.equals(user.password) : user.password != null) return false;
        if (username != null ? !username.equals(user.username) : user.username != null) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = id;
        result = 31 * result + (username != null ? username.hashCode() : 0);
        result = 31 * result + (password != null ? password.hashCode() : 0);
        return result;
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }

}



值得注意的是,以User作为外键的表会自动生成一个对应的字段并以@OrderBy内值自动创建,mappedBy属性内容为目标实体的对应关联字段,如果没有该属性,hibernate会自动创建User和Post的一个中间表。

下面为博客实体类Post:

import ***;

/**
 * @author Barudisshu
 */
@Entity
@Table(name = "t_post", schema = "", catalog = "db_blog")
public class Post implements Serializable{

    private int id;         //博客自动Id
    private String title;   //博客标题
    private Timestamp time; //发布时间
    private String digest;  //摘要
    private String mark;    //标记
    private String content; //博客正文
    private Integer type;   //博客分类
    private Integer views;  //浏览次数

    private User user;      //博客用户

    @Id
    @Column(name = "id", nullable = false, insertable = true, updatable = true)
    public int getId() {
        return id;
    }

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

    @Basic
    @Column(name = "title", nullable = true, insertable = true, updatable = true, length = 255)
    public String getTitle() {
        return title;
    }

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

    @Basic
    @Column(name = "time", nullable = true, insertable = true, updatable = true)
    public Timestamp getTime() {
        return time;
    }

    public void setTime(Timestamp time) {
        this.time = time;
    }

    @Basic
    @Column(name = "digest", nullable = true, insertable = true, updatable = true, length = 1600)
    public String getDigest() {
        return digest;
    }

    public void setDigest(String digest) {
        this.digest = digest;
    }

    @Basic
    @Column(name = "mark", nullable = true, insertable = true, updatable = true, length = 255)
    public String getMark() {
        return mark;
    }

    public void setMark(String mark) {
        this.mark = mark;
    }

    @Basic
    @Column(name = "content", nullable = true, insertable = true, updatable = true, length = 2147483647)
    public String getContent() {
        return content;
    }

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

    @Basic
    @Column(name = "type", nullable = true, insertable = true, updatable = true)
    public Integer getType() {
        return type;
    }

    public void setType(Integer type) {
        this.type = type;
    }

    @Basic
    @Column(name = "views", nullable = true, insertable = true, updatable = true)
    public Integer getViews() {
        return views;
    }

    public void setViews(Integer views) {
        this.views = views;
    }

    @ManyToOne(cascade = CascadeType.PERSIST,targetEntity = User.class)
    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Post post = (Post) o;

        if (id != post.id) return false;
        if (content != null ? !content.equals(post.content) : post.content != null) return false;
        if (digest != null ? !digest.equals(post.digest) : post.digest != null) return false;
        if (mark != null ? !mark.equals(post.mark) : post.mark != null) return false;
        if (time != null ? !time.equals(post.time) : post.time != null) return false;
        if (title != null ? !title.equals(post.title) : post.title != null) return false;
        if (type != null ? !type.equals(post.type) : post.type != null) return false;
        if (views != null ? !views.equals(post.views) : post.views != null) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = id;
        result = 31 * result + (title != null ? title.hashCode() : 0);
        result = 31 * result + (time != null ? time.hashCode() : 0);
        result = 31 * result + (digest != null ? digest.hashCode() : 0);
        result = 31 * result + (mark != null ? mark.hashCode() : 0);
        result = 31 * result + (content != null ? content.hashCode() : 0);
        result = 31 * result + (type != null ? type.hashCode() : 0);
        result = 31 * result + (views != null ? views.hashCode() : 0);
        return result;
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }

}



对于有向与无向的概念,实质上就是是否可以通过一个实体获取得到另一个实体,这样一般要求考虑是否级联操作,如果实际项目中查询复杂度太大,建议使用HQL来进行操作,相对应的建表的时候建立一种较弱的关联。

Hibernate注解方式实现1-N双向关联