感谢Jie’ blog http://ilog.vip/ ,谢谢他让我有了继续写下去的信念。愿一起坚持,在路上…
上一章简单介绍了Hibernate三种实体状态(五),如果没有看过,请观看上一章
Hibernate的Session中提供了很多的方法,这些方法在某些方面是效果一样的,但还是有一些不同的。下面,进行一些简单的区分.
一. save()与saveOrUpdate()方法
save()方法的执行过程为:
- 系统根据指定的ID生成策略,为临时对象生成一个唯一的OID;
- 将临时对象加载到缓存中,使之变成持久化对象;
- 提交事务时,清理缓存,利用持久化对象包含的信息生成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个观点,引用于:https://blog.csdn.net/csujiangyu/article/details/48223459
- 如果merge的对象在数据库中不存在,merge将会进行save操作,作用等同于updateOrSave();而update因为找不到对象而报错。
- 如果merge的对象能在数据库中操作,merge操作和update操作效果一样。
- 新new一个对象,如果该对象设置了ID,则这个对象就当作游离态处理.
- merge可以持久化游离态的对象A,持久化后的对象A仍然处于游离态,持久化的对象A不和session关联。
- 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对象,不会清除其他的对象。
谢谢!!!