hibernate读取数据库内容,用
1,session.get(Class类型,主键);
立马发出sql语句。从数据库中取出值装到对象里去
2,session.load(Class类型,主键);
从数据库里取出一条记录,到内存里,转换成对应的对象。不发出sql语句,什么时候用对象的内容,什么时候发sql语句。
返回的是代理类,是对象的子类,hibernate给你自动生成的。他并没有直接发出sql语句,当用到对象的内容时,才发出sql'语句
API里的描述:
get(Class clazz, Serializable id)
load(Class theClass, Serializable id)
主键id会自动封箱成Integer,也是实现了序列化接口的。
实验:
数据库里teacher表有这么几天记录:
Test类:
package com.oracle.hibernate.id; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.AnnotationConfiguration; import org.hibernate.cfg.Configuration; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; public class HibernateCoreAPITest { private static SessionFactory sf = null; @BeforeClass public static void beforeClass() { // try-chatch是为了解决Junit有错误不提示的bug try { sf = new AnnotationConfiguration().configure() .buildSessionFactory(); } catch (HibernateException e) { e.printStackTrace(); } } @Test public void testTeacherLoad() { Session session = sf.getCurrentSession(); session.beginTransaction(); Teacher t = (Teacher)session.load(Teacher.class, 2); //System.out.println(t.getName());
//session.delete(t);查询出对象删除。
session.getTransaction().commit(); //System.out.println(t.getName()); System.out.println("用load时,t的类型是代理类: "+t.getClass()); } @Test public void testTeacherGet() { Session session = sf.getCurrentSession(); session.beginTransaction(); Teacher t = (Teacher)session.get(Teacher.class, 1); session.getTransaction().commit(); //System.out.println(t.getName()); System.out.println("用get时,t的类型是: "+t.getClass()); } @AfterClass public static void afterClass() { sf.close(); } }
测试结果:
1,两者打印出的t的类型是:
用load时,t的类型是代理类: class com.oracle.hibernate.id.Teacher_$$_javassist_1
javassist是hibernate专门生产动态代理的类库,直接生成二进制码,效率高。不会生成源码再编译。
用get时,t的类型是: class com.oracle.hibernate.id.Teacher
2,当session commit之后,如果再t.getName():
用load会报错:org.hibernate.LazyInitializationException: could not initialize proxy - no Session 延迟初始化异常
用get正常,因为它是直接发出sql语句从数据库中查。
3,如果查找id不存在的记录:
用get会返回null。
用load,只要你不用它的内容,就不会报错。用时返回ObjectNotFoundException。