Hibernate表间级联

来源:互联网 发布:二手软件 编辑:程序博客网 时间:2024/06/10 22:22

Hibernate关系映射

 

对象之间的关系:一对一,一对多,多对一,多对多(单双向),集合映射,继承关系映射,组件映射

 

我们只关注怎么写annotation

 

一对一单向外键关联:

         在一个bean中,加上另外一个bean的对象,如:privateWife wife ,并生成getter/setter

         get方法上加上@OneToOne

         默认情况下,外键名为外接的表明_id, @JoinColumn=(name=”wifiId”)可以明确指定他的名字

 

一对一双向外键关联:

         (在双向关联中MappedBy必设)

         和单向一样,在属性中加入另外个表的对象,这样生成的表中2个表都彼此有外键,然而事实上这是没有必要的,所以要在OneToOne中的属性加入annotationmappedBy=”wife”,这样在WiFe表中就不会有husband的外键husband_Id

Q:那么mappedBy=”wife”中的wife是什么?

A:那是在husband中定义的那个属性的名称,privateWife wife, 这个wife

 

组件映射:

         将一个类中的属性作为另一个表中的属性,比如wife表的属性wifenameage作为husband表的一部分属性,WiFe类就不需要@id @entityannotation,只需要在husbandgetWife()上加上@Embedded,并且数据库只会生成一个husband

 

多对一单向关联:

         数据库设计:在多方加外键

         直接看代码吧:在多方加上manyToOne即可

 

一对多单向关联

         一般来讲,我们会这么写:

(应该使用set,数据库表中不能有重复)

 但是操作后我们发现数据库会生成一张中间表:t_group_t_user,因为如果只生成2张表,那么在一对多的关系映射中,t_group表必然会有数据冗余,比如 1, group_a, user_a; 2, group_a, user_b显然这是不合适的

解决办法:在one方加入 @JoinColumn(name=”group_id”),这样在database中不会生成中间表,并且在user表中有一个字段:group_id

 

多对多单向关联:

         会生成一个中间表

         看代码:

解释一下代码吧:

@JoinTable(name="t_s",                                        :指定生成中间表的名称(默认teacher_student)

          joinColumns={@JoinColumn(name="t_id")},          :指定对应的外键的名称(默认teacher_id

          inverseJoinColumns={@JoinColumn(name="s_id")}    :指定对应的外键的名称(默认student_id

      )

 

多对多双向关联:(用得比较少)

         很简单,同上面的多对多单向关联一样:

要注意加上mappedBy=”***”,否则的话会生成一张冗余的表,像这样:student_teacher表是多余的

 

 

 

 

 

 

 

在关联关系中怎么写CRUD

以多对一为例(一对多也是一样的):

 

很明显,我们注意到了cascade,那么cascade是啥呢?

Cascade可以在我们操作有级联关系的表时自动帮助我们进行操作,比如在这个例子中,如果没有cascade这个属性,只有manyToOne,那么在保存GroupUser的时候,既要session.persiste(u),又要session.persiste(g),多麻烦

有了cascade之后只需要保存User即可:

这样Hibernate就会根据表间的级联关系为我们自动保存

Cascade还有以下属性:

ALL 在所有的DB操作中,都会与级联对象产生关联

            PERSIST:保存

      *RERESH:刷新(不常用)

            *MERGE:合并(不常用)

            REMOVE:删除

cascade并不是非用不可,可以手动保存,他只是简化了我们的代码

上面save,我们再来谈谈读取:

就说多对一吧:

如果取多的一方,会把那个一也会取出来,能直接获取到:

User u = (User)session.get(User.class, 1) ;

System.out.println(u.getId()+u.getName()+u.getGroup().getId());

如果取一的那一方,那么只会取一,并不会取多:

Group g = (Group)session.get(Group.class, 1) ;

System.out.println(g.getId()+g.getName());

那么如果我想在取多的那方时,不把一的那方取出来呢?这里就要涉及到另外一个概念了:fetch

他有2个属性:LAZY/EAGER

如果不写fetch,那么默认为EAGER,会把一取出来,如果定义为LAZY,那么不会取一:

1 0
原创粉丝点击