hibernate实体类设计体会

以博客实体类和用户实体类为例,他们之间是多对多的关系,即一个博客可以被多个用户收藏,一个用户也可以收藏多个博客,现在考虑三个问题:
1.双方是否持有对方集合的引用
2.当双方均持有对方集合的引用时,哪一方拥有对于联系的维护权限
3.当双方均持有对方集合的引用时,如何设置级联关系

首先第一个问题,双方是否持有对方的引用。我认为这取决于在传递数据(一方的pojo对象)时是否可能需要同时传递另一方的pojo对象集合。例如,若在传递用户时同时需要传递其收藏的博客列表,则用户类需要持有博客集合的引用,反之亦然。

当双方均持有对方集合的引用时,设有下面用户类和博客类(省略setter和getter方法)

@Entity
@Table(name="user_inf")
public class User
{
    //新闻编号,设置为自动增长
    @Id@Column(name="user_id")
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Integer userId;

    //新闻的标签
    @ManyToMany(targetEntity = Blog.class,cascade=CascadeType.ALL)
    @JoinTable(name = "user_blog", joinColumns = { @JoinColumn(name = "user_id") }, inverseJoinColumns = { @JoinColumn(name = "blog_id") })
    private Set<Blog> blogs = new HashSet<Blog>();
@Entity
@Table(name="blog_inf")
public class Blog {
    //新闻编号,设置为自动增长
    @Id@Column(name="blog_id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer blogId;
    //mappedBy后面的属性为User类中相应的集合字段名
    @ManyToMany(mappedBy="blogs")
    private Set<User> user = new HashSet<User>();

现在看第二个问题,当双方均持有对方集合的引用时,哪一方拥有对于联系的维护权限。一方拥有对于联系的维护权限=可以通过对该方对象的修改来修改中间表(多对多关系会产生一个中间表)。例如,若想通过修改用户对象的博客集合这一属性来对中间表进行修改,如下列语句

        //数据库中已存在主键为1的博客记录
        Blog blog = new Blog();
        blog.setBlogId(1);
        //数据库中已存在主键为1的用户记录
        User user = new User();
        user.setUserId(1);
        //为id为1的用户添加收藏id为1的博客
        user.getBlogs().add(blog);
        sess.update(user);
        //执行后中间表user_blog多了一行记录

则应让用户类持有对于联系的维护权限,此时应在博客的用户集合属性的manyToMany注解中添加mappedBy属性,表示博客这一端放弃对联系的维护权限。关于这个问题可以参考一下我的另一篇博客Hibernate注解之@ManyToMany

最后第三个问题,当双方均持有对方集合的引用时,如何设计级联关系。例如,若想在添加用户对象时,同时添加该用户对象持有的博客对象,,如下列语句

        //新的用户对象
        User user = new User();
        //该用户对象持有两个新的博客对象
        user.getBlogs().add(new Blog());
        user.getBlogs().add(new Blog());
        //同时保存用户对象以及其关联的博客对象
        sess.save(user);
        //执行后user_inf表多了一行记录
        //执行后blog_inf表多了二行记录
        //执行后中间表user_blog多了二行记录

此时应在用户的博客集合属性的ManyToMany注解中添加cascade=CascadeType.ALL属性,表示对用户表增加,更新等操作会级联到博客表。

另外在级联操作中有两点需要注意:

1.在级联删除时,若需要在删除用户记录的同时级联删除与其关联的博客记录,则在调用sess.delete(user)方法进行删除时,user对象中必须持有相应博客对象的引用,若user对象中仅有userId属性而blogs属性为空,那么此时只能删除用户记录和中间表内的相关记录,无法级联删除相应的博客记录。
2.在级联操作时,不要通过对放弃维护关联关系的那一方进行级联操作,因为该方不具备修改中间表的权限,而在级联操作中,必然会对中间表进行修改,这样做通常会产生一个由外键约束而导致的异常 。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值