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属性

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
	@GeneratedValue
	public 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
	@GeneratedValue
	public 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;
	}
	@ManyToOne
	public Group getGroup() {
		return group;
	}
	public void setGroup(Group group) {
		this.group = group;
	}
}

 

public class ORMappingTest {

	private static SessionFactory sf = null;

	@BeforeClass
	public static void beforeClass(){
		sf = new Configuration().configure().buildSessionFactory();
	}

	@AfterClass
	public static void afterClass(){
		sf.close();
	}

	@Test
	public void test() {

		//下面将会完善此test()方法

	}
}

 

接下来开始CRUD的练习

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

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

 

//User类
@ManyToOne(cascade={CascadeType.ALL})
public Group getGroup() {
    return group;
}

 

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

 

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

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

@Test
public 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对象

@Test
public 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对象

@Test
public 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对象

@Test
public 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对象中的属性名字

@Test
public 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表中的某一条记录

两种方式,如下:

@Test
public 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();
}

Hibernate关联关系的CRUD,布布扣,bubuko.com

时间: 2024-10-03 10:09:54

Hibernate关联关系的CRUD的相关文章

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

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.  Hibernate对象的CRUD操作 1.1.  对象的三种状态 瞬时(Transient) - 由new操作符创建,且尚未与HibernateSession 关联的对象被认定为瞬时(Transient)的.瞬时(Transient)对象不会被持久化到数据库中,也不会被赋予持久化标识(identifier).如果瞬时(Transient)对象在程序中没有被引用,它会被垃圾回收器(garbage collector)销毁.使用Hibernate Session可以将其变为持久(Persis

Hibernate关联关系映射(单向篇)

Hibernate关联关系可分为单向关联和双向关联两大类.单向关联可以分为一对一.一对多.多对一和多对多4种关联方式,而多向关联可以分为一对一.一对多和多对多3种关联方式. Hibernate连接管理类HibernateUtil.java public class HibernateUtil { private static SessionFactory sessionFactory; private static final ThreadLocal<Session> threadLocal

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);//

关联关系的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. 铁

hibernate之2.CRUD

Key Generator(主键产生器) 可选项说明: 1) assigned 主键由外部程序负责生成,无需Hibernate参与. 2) hilo 通过hi/lo 算法实现的主键生成机制,需要额外的数据库表保存主键生成历史状态. 3) seqhilo 与hilo 类似,通过hi/lo 算法实现的主键生成机制,只是主键历史状态保存在Sequence中,适用于支持Sequence的数据库,如Oracle. 4) increment 主键按数值顺序递增.此方式的实现机制为在当前应用实例中维持一个变量

hibernate关联关系

hibernate是一个强大的ORM框架,为了使用面向对象的方式管理数据库,hibernate提供了4中关系设置: 1.一对一 (one-to-one) 2.一对多 (one-to-many) 3.多对一 (many-to-one) 4.多对多 (many-to-many) 5最常用的关系是一对多和多对一 6.实现方式: 一对多:在"一方"定义"多方"的集合(set集合) 多对一: 在"多方"定义"一方"的引用(对象属性),多

hibernate关联关系映射之配置文件

词汇解释 关系:事物之间相互作用.相互联系的状态.范围最大. 联系:在关系数据库中表示实体与实体之间的联系,1:1,1:n,m:n. 关联:表示对象之间的关系,既有数量性,又有方向性:动词:将对象之间通过某种方式联系起来. 映射:这里指java对象和数据库表的一种对应关系.动词:形成这种对应关系. 级联:有关系的双方中操作一方,另一方也将采取一些动作. 关联的联系种类 在不考虑关联的方向前提下,联系就是关系数据库中表示实体与实体之间的联系,1:1,1:n,m:n. 一对一联系(1:1):如用户和