Hibernate的常用方法区别(六)

感谢Jie’ blog http://ilog.vip/ ,谢谢他让我有了继续写下去的信念。愿一起坚持,在路上…
上一章简单介绍了Hibernate三种实体状态(五),如果没有看过,请观看上一章
Hibernate的Session中提供了很多的方法,这些方法在某些方面是效果一样的,但还是有一些不同的。下面,进行一些简单的区分.

一. save()与saveOrUpdate()方法

save()方法的执行过程为:

  1. 系统根据指定的ID生成策略,为临时对象生成一个唯一的OID;
  2. 将临时对象加载到缓存中,使之变成持久化对象;
  3. 提交事务时,清理缓存,利用持久化对象包含的信息生成insert语句,将持久化对象保存到数据库。
    这个方法,主要是进行实体对象的保存,将瞬时对象转换成持久对象,保存在数据库中。
/**
	 * 验证save()方法设置id的情形
	 */
	@Test
	public void test1(){
		Session session=HibernateUtil.getSession();
		Transaction transaction=session.beginTransaction();
		User user=new User();
		user.setId(6);
		user.setSex("不知道");
		session.save(user);
		transaction.commit();
	}

设置的这个id,并不会起作用,只是将瞬时态对象转换成游离态对象。Hibernate 中的真实id是根据Id生成策略进行指定的。
数据库中的接下来的id该为27.
在这里插入图片描述
saveOrUpdate()方法,如果设置的这个对象,如果没有Id,

@Test
	public void test2(){
		Session session=HibernateUtil.getSession();
		Transaction transaction=session.beginTransaction();
		User user=new User();
		user.setSex("不知道");
		session.saveOrUpdate(user);
		transaction.commit();
	}

执行的是插入的方法,调用insert 语句进行插入.
如果有id,并且这个id已经存在于数据库中:

@Test
	public void test2(){
		Session session=HibernateUtil.getSession();
		Transaction transaction=session.beginTransaction();
		User user=new User();
		user.setId(8);  //存在为8的数据,调用的是update的语句,进行修改.
		// user.setId(30) ;// 没有id为30的数据。
		user.setSex("不知道");
		session.saveOrUpdate(user);
		transaction.commit();
	}

如果有id,但这个id并没有存在于数据库中,即这个id很大,如30的Id.
会抛出异常。 这个时候,应该用save()方法。
在这里插入图片描述
如果执行的是删除后的数据,如:

@Test
	public void test2(){
		Session session=HibernateUtil.getSession();
		Transaction transaction=session.beginTransaction();
		User user=new User();
		user.setId(6);
		session.delete(user);
		user.setSex("知道");
		session.saveOrUpdate(user);
		transaction.commit();
	}

那么会执行两条语句,一条是删除6的数据,另外一条是insert语句,插入sex=“知道”。

二.save()与saveOrUpdate()与merge()方法。

merge()方法时,当session中已经存在了一条持久化对象,再设置一个相同的id的对象,那么这里用saveOrUpdate()方法会出现错误,抛出异常的,应该用merge()方法。merge,中文意思为合并。

@Test
	public void testMerge(){
		Session session=HibernateUtil.getSession();
		Transaction transaction=session.beginTransaction();
		User user1=session.get(User.class,7);
		User user2=new User();
		user2.setId(7);
		user2.setDescription("两个相同的id");
		//session.saveOrUpdate(user2);  会出现错误
		session.merge(user2);  // 应该使用merge()方法
		transaction.commit();//再次进行提交 
	}

这5个观点,引用于:http://www.noobyard.com/article/p-gdmzgzmm-gt.html

  1. 如果merge的对象在数据库中不存在,merge将会进行save操作,作用等同于updateOrSave();而update因为找不到对象而报错。
  2. 如果merge的对象能在数据库中操作,merge操作和update操作效果一样。
  3. 新new一个对象,如果该对象设置了ID,则这个对象就当作游离态处理.
  4. merge可以持久化游离态的对象A,持久化后的对象A仍然处于游离态,持久化的对象A不和session关联。
  5. merge返回持久化对象的副本,该副本处于持久化态。

三.get()和load()的区别

get是立即加载,load()是延迟加载。 与一个lazy 的属性设置值有关。
如果是get()的时候,

User user=session.get(User.class,1); //会在这里去数据库中进行查找

如果是load()的时候,

User user=session.load(User.class,1); //不会去数据库中查询
System.out.println(user.getUserName()); //会去数据库中进行相应的查询

另外,如果查询出的数据不存在时:

@Test
	public void test3(){
		Session session=HibernateUtil.getSession();
		User user=session.get(User.class,100); //不存在id为100的值
		System.out.println(user.toString());
	}


会抛出空指向异常。即get()的返回值为null.
如果是load()的话,

@Test
	public void test3(){
		Session session=HibernateUtil.getSession();
		User user=session.load(User.class,100); //不存在id为100的值
		System.out.println(user.toString());
	}

在这里插入图片描述
会抛出ObjectNotFoundExcetpion 异常。

四. close(),flush(),clear()和evict()

close()为关闭Session,表示断开与数据库的连接。
clear()为清空缓存,清空Session中的所有的对象,但不包括正在操作的对象。 Session中可以存储很多的对象,如果这个对象正在被操作,当session.clear()时,会把其余的对象给清空。
flush(),是将缓冲区的对象刷新到数据库中,与数据库进行同步。
可以设置flushModel的值,以前常用setFlushMode()方法,但这个方法已经被废除了,现在常用setHibernateFlushMode()方法。
在这里插入图片描述
在这里插入图片描述
其中,FlushMode的常用值为:

MANUAL(0),   // 手动方式
COMMIT(5),  //commit提交时
AUTO(10),  //自动,默认的
ALWAYS(20); //任何代码都会

以下节选自:https://blog.csdn.net/z69183787/article/details/38403367/
在这里插入图片描述
在这里插入图片描述
evict() 将指定的对象清除。

session.evict(user); //只清空当前 的user对象,不会清除其他的对象。

谢谢!!!