您的位置:首页 > 其它

Hibernate学习笔记之Session-API实现CRUD以及get&load&merge方法

2016-08-01 10:45 555 查看
本文主要介绍以下三个方面:

1.使用Session-API CRUD操作

2.get()/load()的区别

3.saveOrUpdate()/merge()的区别

1.session.save(obj)

a.当前对象如果是持久态,执行save方法,会发送update语句;

b.当前对象如果是瞬时态,执行save方法,会发送insert语句,对象会从瞬时态转为持久态。

/*session.save(obj);
* 当前对象是持久态时,执行save方法,会执行Update语句
* 当前对象是瞬时态时,执行save方法,会执行insert语句,从瞬时态转换为持久态
* */
@Test
public void testSave() {

Session session = sessionFactory.getCurrentSession();
Transaction tx = session.beginTransaction();

try {

Students s = new Students();
//s为瞬时态
s.setSname("lisi");
session.save(s);//会执行insert语句,s变成持久态

//Students s = (Students)session.get(Students.class, 1);
//get到的s为持久态

Students s = new Students();

s.setSid(1);
s.setSname("zhangsan2");
session.save(s);

tx.commit();

} catch (Exception e) {

e.printStackTrace();
tx.rollback();
}
}


@Test
public void testSave() {

Session session = sessionFactory.getCurrentSession();
Transaction tx = session.beginTransaction();

try {

Students s = (Students)session.get(Students.class, 1);
//get到的s为持久态

s.setSid(1);
s.setSname("zhangsan2");
session.save(s);//此时执行update语句

tx.commit();

} catch (Exception e) {

e.printStackTrace();
tx.rollback();
}
}


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

a.get方法创建对象时首先查询session缓存,没有的话查询二级缓存,最后查询数据库;load方法创建对象时首先查询session缓存,没有的话就创建代理,实际使用数据时才查询二级缓存和数据库;

b.如果找不到符合条件的记录,get方法返回null,而load方法抛出异常(ObjectNotFoundException);

c.使用load方法,一般都是假定你要取得的对象肯定是存在的,而get方法则会去尝试,如果对象不存在,就返回null。

@Test
public void testGet(){
Session session = sessionFactory.getCurrentSession();
Transaction tx = session.beginTransaction();

try {

//执行get后,变成持久态,立刻发送SQL语句
//Students s = (Students)session.get(Students.class, 1);
Students s1 = (Students)session.get("PersistenceClass.Students", 0);
System.out.println("学号:"+s1.getSid()+"姓名:"+s1.getSname());

//由于s2和s1生成的对象相同,故直接查找session缓存,不再发送SQL语句
Students s2 = (Students)session.get("PersistenceClass.Students", 0);
System.out.println("学号:"+s2.getSid()+"姓名:"+s2.getSname());

tx.commit();

} catch (Exception e) {

e.printStackTrace();
tx.rollback();
}
}






@Test
public void testLoad(){

Session session = sessionFactory.getCurrentSession();
Transaction tx = session.beginTransaction();

try {

//执行load后,生成代理对象,当用到对象的属性或者方法时,才发送SQL语句
//Students s = (Students)session.get(Students.class, 1);
Students s1 = (Students)session.load("PersistenceClass.Students", 0);
System.out.println("学号:"+s1.getSid()+"姓名:"+s1.getSname());

//由于s2和s1生成的对象相同,故直接查找session缓存,不再发送SQL语句
Students s2 = (Students)session.load("PersistenceClass.Students", 0);
System.out.println("学号:"+s2.getSid()+"姓名:"+s2.getSname());

tx.commit();

} catch (Exception e) {

e.printStackTrace();
tx.rollback();
}
}






总结:

a.从两种方法的调试情况可以看出,get每次生成的都是持久态对象,load每次生成的都是代理对象(Students_$$_javassist_0);

b.虽然最后的执行结果相同,但是,load方法只有在使用到对象的属性和方法时,才会发送SQL语句,而get在创建对象时就立刻发送SQL语句。

3.Update()

a.瞬时态不能执行update();

b.持久态和托管态可以执行update();

c.代理对象在session对象关闭后不能执行update()。

@Test
public void testUpdate(){
Session session = sessionFactory.getCurrentSession();
Transaction tx = session.beginTransaction();
Students s = null;
try {

/*瞬时态对象不能调用update方法
* Students s = new Students();
* s.setSid(2);
* s.setSname("lisi");
* session.update(s);
* */

/*持久化对象可以调用update
* Students s = (Students)session.load("PersistenceClass.Students", 1);
s.setSname("lisi");
session.update(s);*/

s = (Students)session.get(Students.class, 1);

tx.commit();

} catch (Exception e) {

e.printStackTrace();
tx.rollback();
}

/*getCurrentSession()可以在执行try...catch...语句后自动关闭session,此时s变为托管状态*/
//下面重新开启一个session
session = sessionFactory.getCurrentSession();
tx = session.beginTransaction();
s.setSname("wanglaowu");
session.update(s); //s重新变成了持久态
tx.commit();

}


4.从瞬时态转换为持久态,不确定是否存在主键冲突,推荐使用saveOrUpdate()。

@Test
public void testSaveOrUpdate(){

//测试SaveOrUpdate时需要将数据库的主键生成策略改为"assigned"
//从瞬时态转换为持久态,不确定主键是否冲突,推荐使用SaveOrUpdate
Session session = sessionFactory.getCurrentSession();
Transaction tx = session.beginTransaction();

try {

Students s = new Students();

s.setSid(1);
s.setSname("lisi");
session.saveOrUpdate(s);

/*
* s.getSid(1);
* s.setSname("lisi");
* session.save(s);
* 此时由于主键1已经存在,执行save方法,故会产生主键冲突
*
* */
tx.commit();

} catch (Exception e) {

e.printStackTrace();
tx.rollback();
}
}


5.delete()

a.持久态或者托管态可以执行delete();

b.瞬时态可以执行delete(),但是Hibernate并不推荐使用delete()删除瞬时态对象,因为这样做没有任何意义。

@Test
public void testDelete(){

//持久态或者托管态可以执行delete方法
Session session = sessionFactory.getCurrentSession();
Transaction tx = session.beginTransaction();

try {

Students s = (Students)session.get(Students.class, 1);
session.delete(s);

tx.commit();

} catch (Exception e) {

e.printStackTrace();
tx.rollback();
}
}


6.Merge()

a.使用merge方法,如果数据库中有该记录,则更新该记录,如果不存在该记录,则进行insert操作。使用saveOrUpdate()的话和此方法相同;

b.执行完merge(obj)返回一个持久化对象的引用,而实参obj本身还是托管状态的;

c.saveOrUpdate()后的对象会纳入session的管理,对象的状态会跟数据库同步,再次查询该对象会直接从session中取,merge后的对象不会纳入session管理,再次查询该对象还是会从数据库中取。

@Test
public void testMerge(){

Session session = sessionFactory.getCurrentSession();
Transaction tx = session.beginTransaction();

try {

Students s1 = new Students();
s1.setSid(1);
s1.setSname("lisi");
Students s2 = (Students)session.merge(s1);
System.out.println(s1.hashCode());//s1还是托管的
System.out.println(s2.hashCode());//s2是持久化的

tx.commit();

} catch (Exception e) {

e.printStackTrace();
tx.rollback();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐