在Hibernate中java对象的状态:
1、临时状态(Transient):
与数据库没有对应,跟Session没有关联
一般是新new出的对象
2、持久化状态(Persist):
对象再Session的管理之中,最终会有对应的数据记录
特点:
a、有OID(唯一标示)
b、对对象的修改会同步到数据库中
3、游离状态(Detached):
数据库中有对应记录,但对象不再Session管理之中
修改了此状态对象时,数据库不会变化
4、删除状态(Removed):
执行了delete()后的对象
Session中的方法:
一、操作实体对象的方法
save()
update()
saveOrUpdate()
delete()
二、操作缓存的方法
clear()
evict()
flush() 马上执行数据库操作,默认是在事务提交的时候才执行,但是save()和get()的时候会马上执行
三、查询实体对象的方法
get()
load()
createQuery()
createCriteria()
下面演示的是save()方法,它能把对象的临时状态变成持久化状态。第9行新建一个User对象,此时对象时临时状态,第9行调用session的save()方法,将对象变成了持久化状态,交给Session管理,但此时并不马上执行insert语句,而是在事务提交,session关闭的时候才会执行insert语句。第13行设置了对象的名字为“李四”,第16行提交事务,第17行关闭session,此时就会执行insert语句,所以数据库中新插入的数据其name属性为李四,而不是一开始的test。只要对象属于持久化状态,对对象属性的操作,都会作用于数据库中。
//save():把临时状态变为持久化状态(交给Session管理)
@Test
public void testSave(){
Session session = sessionFactory.openSession();
session.beginTransaction();
//-----------------------------------------------
//构建对象
User user = new User(); //临时状态
user.setName("test");
session.save(user); //变成持久化状态
user.setName("李四");
//-----------------------------------------------
session.getTransaction().commit();
session.close();
System.out.println(user.getName());
}
下面演示的是update()方法,它能把游离状态的对象变成持久化状态。第8行通过id获取对象,得到的对象为持久化状态。第11行为对象属性设置新值,第12行调用session的flush()方法,此方法是将session中的数据刷出到数据库,此时会马上执行update语句更新数据库,第13行清空了session中的所有对象,此时之前的user对象变成了游离的状态,如果有清除session中的指定对象,可以使用evict方法。
//update():把游离状态变为持久化状态
@Test
public void testUpdate(){
Session session = sessionFactory.openSession();
session.beginTransaction();
//-----------------------------------------------
User user = (User) session.get(User.class, 9);
System.out.println(user.getName()); //持久化状态
user.setName("newname");
session.flush(); //刷出到数据库
session.clear(); //变为游离状态,清除session中所有的对象
//session.evict(user); //清除session中一个指定的对象
//-----------------------------------------------
session.getTransaction().commit();
session.close();
}
下面演示的是saveOrUpdate()方法,它能把临时或游离状态的对象转换为持久化状态。
//saveOrUpdate():把临时或游离状态转为持久化状态
//在更新的时候,如果对象不存在就报错
//本方法是根据id判断对象是什么状态的:如果id为原始值(对象的是null,原始类型的数字是0)
//就是临时状态,如果不是原始值就是游离状态
@Test
public void testSaveOrUpdate(){
Session session = sessionFactory.openSession();
session.beginTransaction();
//-----------------------------------------------
User user = new User();
user.setId(9); //自己生成一个游离状态对象
user.setName("白子画");
session.saveOrUpdate(user);
//-----------------------------------------------
session.getTransaction().commit();
session.close();
}
下面演示的是delete()方法,它能把持久化或游离状态的对象转换为删除状态。
//delete():把持久化或游离状态转换为删除状态
//如果删除的对象不存在,就会抛异常
@Test
public void testDelete(){
Session session = sessionFactory.openSession();
session.beginTransaction();
//-----------------------------------------------
User user = (User) session.get(User.class, 10);
session.delete(user);
//-----------------------------------------------
session.getTransaction().commit();
session.close();
}
下面演示的是get()方法,它可以从数据库中获取数据,获取到的对象是持久化状态。第10行通过id获取一个User对象,此时会直接执行select语句,如果打印出SQL语句的话,会看到先打印出select语句,再打印出“====”,如果查找的对象不存在,就返回null。
//get():获取数据,是持久化状态
//会马上执行SQL语句
//如果对象不存在,就返回null
@Test
public void testGet(){
Session session = sessionFactory.openSession();
session.beginTransaction();
//-----------------------------------------------
User user = (User) session.get(User.class, 11);
System.out.println("====");
System.out.println(user.getName());
//-----------------------------------------------
session.getTransaction().commit();
session.close();
}
下面演示的是load()方法,它可以从数据库中获取数据,获取到的对象是持久化状态。load方法返回的是一个代理对象,如果此时打印出user.getClass.getName(),就会发现其类型不是自己定义的User类型了,而是一个User的代理对象。第16行打印user的name属性,此时才会执行select语句查询数据库,这是hibernate懒加载的特性。
//load():获取数据,是持久化状态
//load后返回的是一个代理对象,要求类不能是final的,否则不能生成子类代理,就不能使用懒加载功能
//让懒加载失效的方式:
// 一、把实体类写成final
// 二、在hbm.xml的<class>配置lazy="false"
//不会马上执行SQL语句,而是在第一次使用非id和class属性时执行sql
//如果对象不存在,就抛异常:org.hibernate.ObjectNotFoundException
@Test
public void testLoad(){
Session session = sessionFactory.openSession();
session.beginTransaction();
//-----------------------------------------------
User user = (User) session.load(User.class, 11);
System.out.println("=====");
System.out.println(user.getName());
//-----------------------------------------------
session.getTransaction().commit();
session.close();
}
下面演示的是批量保存,Session缓冲区是由一定的大小的,如果存放过多的对象,可能会导致内存溢出。所以第13行采取的方法是每保存15个对象,就调用一次flush把对象刷出到数据库,然后清空session,这样就防止了内存溢出的问题。
//操作大量数据,要防止Session中对象过多而内存溢出
@Test
public void testBatchSave(){
Session session = sessionFactory.openSession();
session.beginTransaction();
//-----------------------------------------------
for(int i = 0; i < 100; i++){
User user = new User();
user.setName("测试");
session.save(user);
if(i % 15 ==0){
session.flush(); //先刷出
session.clear(); //再清空
}
}
//-----------------------------------------------
session.getTransaction().commit();
session.close();
}