关联关系的CRUD

关联关系中的CRUD_Cascade_Fetch
  1. hibernate_1700_one2many_many2one_bi_crud
  2. 设定 cascade 可以设定在持久化时对于关联对象的操作(CUD,R归Fetch管)
  3. cascade 仅仅是帮我们省了编程的麻烦而已,不要把它的作用看的太大
    a) Cascade 的属性指明做什么操作的时候关联对象是绑在一起的
    b) Merge = save + update
    c) refresh = A 里面需要度 B 改过之后的数据
  4. 铁律:双向关系在程序中要设定双向关联
  5. 铁律:双向 mappedBy
  6. fetch
    a) 铁律:双向不要两边设置 eager(会有多余的查询语句发出)
    b) 对多方设置 fetch 的时候要谨慎,结合具体应用,一般用 Lazy 不用 eager,特殊情况(多方数量不多的时候可以考虑,提高效率的时候可以考虑)
  7. O/R Mapping 编程模型
    a) 映射模型
      i. jpa annotation
      ii. hibernate annotation extension
      iii. hibernate xml
      iiii.jpa xml
    b) 编程接口
      i. jpa 的编程接口
      ii. hibernate 的编程接口
    c) 数据查询语言
      i. HQL
      ii. EJBQL(JPQL)
  8. 要想删除或者更新,先做 load,出了精确知道 ID 之外
  9. 如果象消除关联关系,先设定关系为 null,再删除对应记录,如果不删记录,该记录就变成垃圾数据
关系映射总结
1. 什么样的关系,设计什么样的表,进行什么样的映射
5. CRUD,按照自然的理解即可(动手测试)

以多对一为例:多个用户(User)对应一个组(Group)

  User:

 1 package com.bjsxt.hibernate;
 2
 3 import javax.persistence.Entity;
 4 import javax.persistence.GeneratedValue;
 5 import javax.persistence.Id;
 6 import javax.persistence.JoinColumn;
 7 import javax.persistence.ManyToOne;
 8 import javax.persistence.Table;
 9
10 @Entity
11 @Table(name="t_user")
12 public class User {
13     private Integer id;
14
15     private String name;
16
17     private Group group;
18
19     @Id
20     @GeneratedValue
21     public Integer getId() {
22         return id;
23     }
24
25     public void setId(Integer id) {
26         this.id = id;
27     }
28
29     public String getName() {
30         return name;
31     }
32
33     public void setName(String name) {
34         this.name = name;
35     }
36
37     @ManyToOne
38     @JoinColumn(name="group_ID")
39     public Group getGroup() {
40         return group;
41     }
42
43     public void setGroup(Group group) {
44         this.group = group;
45     }
46 }

  Group:

 1 package com.bjsxt.hibernate;
 2
 3 import java.util.HashSet;
 4 import java.util.Set;
 5
 6 import javax.persistence.Entity;
 7 import javax.persistence.GeneratedValue;
 8 import javax.persistence.Id;
 9 import javax.persistence.OneToMany;
10 import javax.persistence.Table;
11
12 @Entity
13 @Table(name="t_group")
14 public class Group {
15     private Integer id;
16
17     private String name;
18
19     private Set<User> users = new HashSet<User>();
20
21     @Id
22     @GeneratedValue
23     public Integer getId() {
24         return id;
25     }
26
27     public void setId(Integer id) {
28         this.id = id;
29     }
30
31     public String getName() {
32         return name;
33     }
34
35     public void setName(String name) {
36         this.name = name;
37     }
38
39     @OneToMany(mappedBy="group")
40     public Set<User> getUsers() {
41         return users;
42     }
43
44     public void setUsers(Set<User> users) {
45         this.users = users;
46     }
47 }

保存顺序:逐个保存

 1 @Test
 2     public void testSaveUser(){
 3         User u = new User();
 4         u.setName("u1");
 5         Group g = new Group();
 6         g.setName("g1");
 7         u.setGroup(g);
 8         Session session = sf.getCurrentSession();
 9         session.beginTransaction();
10         session.save(g);
11         session.save(u);
12         session.getTransaction().commit();
13     }

如果希望在保存 u 的时候顺带保存 g,则需要在User中设置 Cascade:

1    @ManyToOne(cascade=CascadeType.ALL)
2     @JoinColumn(name="group_ID")
3     public Group getGroup() {
4         return group;
5     }

然后再进行保存的代码:

 1     @Test
 2     public void testSaveUser(){
 3         User u = new User();
 4         u.setName("u1");
 5         Group g = new Group();
 6         g.setName("g1");
 7         u.setGroup(g);
 8         Session session = sf.getCurrentSession();
 9         session.beginTransaction();
10 //        session.save(g);
11         session.save(u);
12         session.getTransaction().commit();
13     }

设置Casecade的目的就是为了级联保存,如果嫌麻烦,就理清关系逐个保存就行了。

CRUD 操作:

    C:Create 新增;

    R:Retrieve 检索;

    U:Update 更新;

    D:Delete 删除。

    cascade 负责 CUD(新增、修改、删除),fetch 负责 R(检索)。

用正常人的思维进行思考,然后再通过做实验验证,不要死记硬背。

    查询多的一方(User),会自动带出一的一方(Group):

      OneToMany 默认是 fetch=FetchType.LAZY

      ManyToOne 默认是 fetch=FetchType.EAGER

    @Test
    public void testGetUser(){
        testSaveUser();

        Session session = sf.getCurrentSession();
        session.beginTransaction();
        User u = (User) session.load(User.class, 1);
        System.out.println(u.getGroup().getName());
        session.getTransaction().commit();
    }

    查询一的一方(Group),不会带出多的一方(User),因为这会导致非常严重的性能问题,hibernate也是根据这个思路设计的:

    @Test
    public void testGetGroup(){
        testSaveUser();

        Session session = sf.getCurrentSession();
        session.beginTransaction();
        Group g = (Group) session.get(Group.class, 1);
        session.getTransaction().commit();
        for(User u : g.getUsers()){
            System.out.println(u.getName());
        }

如果非要在查询一的一方的时候带出多的一方,需要在一的一方配置fetch注解:

      FetchType 有两个值:

    @OneToMany(mappedBy="group",
            cascade={CascadeType.ALL},
            fetch=FetchType.EAGER
    )
    public Set<User> getUsers() {
        return users;
    }

这样hibernate就会发出联合查询的sql语句了。

如果多对一和一对多都设置了fetchType=FetchType.EAGER,层次比较深的话,有时查询一行需要关联到很多查询,不利于效率。但有时也需要查询出所有将其放置到hibernate的缓存之中,这个需要根据实际的业务需要。

jar包链接: https://pan.baidu.com/s/1eSf3G1k 密码: bpxb

代码链接: https://pan.baidu.com/s/1cw6N5k 密码: 43im

时间: 2024-10-15 18:46:30

关联关系的CRUD的相关文章

Hibernate关联关系的CRUD

本文以Group和User(一对多.多对一)双向关联为例,介绍关联关系的CRUD   下面先介绍两个属性 cascade:只影响CRUD中的CUD,即存储(save).更新(update).删除(delete) fetch:只影响CRUD中的R,即读取(get.load)   cascade(级联): 此属性仅仅帮助我们简化编程,不是必选项 如果A和B为单向关联,则在主导方设置cascade属性 如果A和B为双向关联,则在双方都要设置cascade属性 如果两个对象之间有关联关系,比如User和

Hibernate中关联关系的CRUD(增删改查)

关联关系的CRUD(增删改查) 一.增加数据 1.User和Group的关联关系:User对Group是Many-To-One,Group对User是One-To-Many 2.默认情况下,不会自动保存尚未保存关联的对象.因为对象没有保存的情况下,对象是Transient状态,此时数据库中并没有存储,所以获取不到该对象. 3.使用级联cascade方式可以自动将关联的对象进行存储.其取值有ALL,PERSIST,REFRESH,REMOVE,DETACH,MERGE这几种取值.其中,ALL表示在

hibernate(十)关联关系的CRUD

一.保存 1. 假设一个group有多个user,一个user只属于一个group,当保存user对象到数据库中时可以 User u = new User(); u.setName("u1"); Group g = new Group(); g.setName("g1"); u.setGroup(g); Session s = sessionFactory.getCurrentSession(); s.beginTransaction(); s.save(g);//

hibernate关联关系的crud之级联

cascade级联,只会影响CRUD的CUD,不会影响读取.不设置级联,从多的一方能读出一的一方,设了级联,从一的一方,默认也不能读出多的一方. 如果两个对象之间有关联,不管是一对多,多对一,单向还是双向,如果从A可以导向到B: A--->B 默认情况下对A的保存不会影响到B,除非设cascade.如果A--->B--->C,从A能导航到B,B能导航到C,在B上也加上级联,对A的操作就能影响到C,但是,级联不是必须的,它只是让编程稍有方便.完全可以手动先存C,再存B,再存A.. 例子:G

ABP源码分析四十一:ZERO的Audit,Setting,Background Job

AuditLog: 继承自Entity<long>的实体类.封装AuditLog的信息. AuditingStore: 实现了IAuditingStore接口,实现了将AuditLog的信息保存到数据库的功能.其通过IRepository<AuditLog, long>实例完成对数据库的操作. BackgroundJobStore :  实现了IBackgroundJobStore接口,通过IRepository<BackgroundJobInfo, long>完成对B

[原创]java WEB学习笔记82:Hibernate学习之路---映射 一对多关联关系,配置,CRUD方法测试及注意点

本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱好者,互联网技术发烧友 微博:伊直都在0221 QQ:951226918 -----------------------------------------------------------------------------------------------------------------

jpa入门之环境搭建和CRUD基本操作

hibernate虽然好用但编写映射文件还是比较麻烦,虽然可以借助插件但是后期的维护还是比较麻烦,jpa的全称是Java Persistence API,实现该规范的产品很多像hibernate就是其中比较出名的一个,原则上应该尽量不要使用hibernate,可惜jpa只是一个接口规范,自己按照规范写一套也不现实,只能通过hibernate间接的使用jpa. 1 使用hibernate的jpa实现需要的jar包如下 我用的是hibernate3.6的版本,如果是低版本的hibernate则还需要

Hibernate(5)—— 联合主键 、一对一关联关系映射(xml和注解) 和 领域驱动设计

俗话说,自己写的代码,6个月后也是别人的代码……复习!复习!复习!涉及的知识点总结如下: One to One 映射关系 一对一单向外键(XML/Annotation) 一对一双向外键关联(XML/Annotation) 联合主键 一对一单向外键联合主键(Xml/Annotation) 一对一组件关联(XML/Annotation) 理解组件 领域驱动设计——自动生成数据库脚本 一对一关系的小结 一些出错问题的总结 自动生成数据库脚本 一般在项目开发过程中,我们的习惯是先建好数据库和表,然后在进

Hibernate学习笔记之关联关系

??关联关系是面向对象分析.面向对象设计最重要的知识,Hibernate完全可以理解这种关联关系,如果映射得当,Hibernate的关联映射将可以大大简化持久层数据的访问.关联关系大致有如下两类: 单向关系:只需单向访问关联端. 双向关系:关联的两端可以互相访问 注:双向关系没有N-1,因为双向关系1-N和N-1是完全相同的. 注意:无论单向关系,还是双向关系,是针对面向对象中的类的调用,与底层数据库关系有所差异,不要搞混了. 专业名词通俗解释: 持久化操作:将数据CRUD(增加(Create)