首页 > 学院 > 开发设计 > 正文

Hibernate关联关系的CRUD

2019-11-14 20:48:42
字体:
来源:转载
供稿:网友
Hibernate关联关系的CRUD

本文以Group和User(一对多、多对一)双向关联为例,介绍关联关系的CRUD

 

下面先介绍两个属性

cascade:只影响CRUD中的CUD,即存储(save)、更新(update)、删除(delete)fetch:只影响CRUD中的R,即读取(get、load)

 

cascade(级联):此属性仅仅帮助我们简化编程,不是必选项如果A和B为单向关联,则在主导方设置cascade属性如果A和B为双向关联,则在双方都要设置cascade属性
如果两个对象之间有关联关系,比如User和Group多对一关联如果想要保存User的时候自动保存Group,可在User类的@ManyToOne注解中设置cascade(级联)属性反过来,如果想要保存Group的时候自动保存User,可在Group类的@OneToMany注解中设置cascade(级联)属性

 

对于User(多方)和Group(一方)执行如下语句 User u = (User) session.get(User.class, 1);在取出多方对象u的同时也会把一方对象对应属性取出来,这是@ManyToOne的默认设置.相当于设置@ManyToOne(fetch=FetchType.EAGER)反过来,取一方对象的时候,则不会把多方对象取出若想要在取出一方对象g的同时取出多方对象,则应在Group类的@OneToMany注解中设置fetch属性
@OneToMany注解中fetch的默认值为FetchType.LAZY, 相当于设置@OneToMany(fetch=FetchType.LAZY) fetch的取值有两个fetch=FetchType.EAGER :执行语句就取出fetch=FetchType.LAZY :用的时候才取出两者的区别类似于get和load的区别 注意:对于双向关联,不要两边都设EAGER(会有多余的查询语句发出),可以都设LAZY一般是多对一设置EAGER,一对多设置LAZY

 

建Group实体类和User实体类,以及Junit测试类

@Entity@Table(name="_group")public class Group {PRivate int id;private String name;private Set<User> users = new HashSet<User>();@Id@GeneratedValuepublic int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}@OneToMany(mappedBy="group")public Set<User> getUsers() {return users;}public void setUsers(Set<User> users) {this.users = users;}}

 

@Entity@Table(name="_user")public class User {private int id;private String name;private Group group;@Id@GeneratedValuepublic int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}@ManyToOnepublic Group getGroup() {return group;}public void setGroup(Group group) {this.group = group;}}

 

public class ORMappingTest {private static SessionFactory sf = null;@BeforeClasspublic static void beforeClass(){sf = new Configuration().configure().buildSessionFactory();}@AfterClasspublic static void afterClass(){sf.close();}@Testpublic void test() {//下面将会完善此test()方法}}

 

接下来开始CRUD的练习

首先在Group类和User类的@OneToMany和@ManyToOne注解中添加cascade属性

//Group类    此处fetch属性中,LAZY为默认值,故也可不写@OneToMany(mappedBy="group",cascade={CascadeType.ALL},fetch=FetchType.LAZY)public Set<User> getUsers() {    return users;}

 

//User类    此处fetch属性中,EAGER为默认值,故也可不写@ManyToOne(cascade={CascadeType.ALL},fetch=FetchType.EAGER)public Group getGroup() {    return group;}

 

然后,完善Junit测试类的test()方法

 

CRUD----C   增   session.save()

1.保存User对象的同时自动保存Group对象

@Testpublic void test() {Session session = sf.getCurrentSession();session.beginTransaction();Group g = new Group();g.setName("lisi");User u = new User();u.setName("user1");u.setGroup(g);session.save(u);   //因为在User类的@ManyToOne注解中设置了cascade(级联)属性,故只需保存User对象即可,Group对象会自动保存session.getTransaction().commit();}

2.保存Group对象的同时自动保存User对象

@Testpublic void test() {Session session = sf.getCurrentSession();session.beginTransaction();User u1 = new User();User u2 = new User();Group g = new Group();u1.setName("user1");u1.setGroup(g);u2.setName("user2");u2.setGroup(g);g.setName("group1");g.getUsers().add(u1);g.getUsers().add(u2);session.save(g);   //因为在Group类的@OneToMany注解中设置了cascade(级联)属性,故只需保存Group对象即可,User对象会自动保存session.getTransaction().commit();}

 

CRUD----R   查   session.get()和session.load()

1.取出User对象的同时取出Group对象

@Testpublic void test() {Session session = sf.getCurrentSession();session.beginTransaction();User u = (User) session.get(User.class, 1);   //在取出多方对象u的同时也会把一方对象对应属性取出来,这是@ManyToOne的默认设置System.out.println(u.getGroup().getName());   //打印输出_group表中对应的name值session.getTransaction().commit();}

2.取出Group对象的同时取出User对象

@Testpublic void test() {Session session = sf.getCurrentSession();session.beginTransaction();Group g = (Group) session.get(Group.class, 2); //在取出一方对象g的同时取出多方对象,此时应在Group类的@OneToMany注解中设置fetch属性for(User u : g.getUsers()){System.out.println(u.getId()+","+u.getName());  //打印输出_user表中的相关数据}session.getTransaction().commit();}

CRUD----U   改   session.update()

通过取出的User对象,既可以更改User对象中的属性名字,也可以更改与其级联的Group对象中的属性名字

@Testpublic void test {Session session = sf.getCurrentSession();session.beginTransaction();User u = (User) session.get(User.class, 3);   //在取出多方对象u的同时也会把一方对象对应属性取出来,这是@ManyToOne的默认设置u.setName("name");                            //更改User对象中的属性名字u.getGroup().setName("Groupname");            //也可以更改与其级联的Group对象中的属性名字session.update(u);session.getTransaction().commit();}

CRUD----D   删   session.delete()

删除User表中的某一条记录

两种方式,如下:

@Testpublic void testDelete() {Session session = sf.getCurrentSession();session.beginTransaction();//删除User表中id值为1的记录User u = (User) session.get(User.class, 1);   //在取出多方对象u的同时也会把一方对象对应属性取出来,这是@ManyToOne的默认设置u.setGroup(null);                             //应该先消除关联关系,再删除对应记录session.delete(u);                            //如果直接删除,由于设置了cascade属性,则会删除Group和User中相关的所有数据      //删除User表中id值为2的记录session.createQuery("delete from User u where u.id=2").executeUpdate();session.getTransaction().commit();}

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表