Hibernate之核心开发接口与对象的三种状态
所有的hibernate应用中都会访问5个核心接口,它们分别是:
- Configuration:配置hibernate,创建SessionFactory对象
- SessionFactory:初始化hibernate,充当数据存储源的代理,创建Session对象
- Session:负责保存、更新、删除、加载和查询对象
- Transaction:管理事事务
- Query和Criteria:执行数据库查询
(1)Configuration(类):对配置信息进行管理,用来产生SessionFactory;他的继承类有:AnnotationConfiguration
用来加载默认的配置文件(hibernate.cfg.xml),如果把配置文件改为:hibernate.xml,可以用他的configure()方法进行加载
例如:Configuration configuration = new Configuration().configure(“hibernate.xml”)
(2)SessionFactory(接口):主要维护数据库的连接池,用来产生Session。通过
public abstract Session openSession(Connection paramConnection,Interceptor paramInterceptor); //通过配置文件获取数据库的Connection
public abstract Session openSession() throws HibernateException;
public abstract Session getCurrentSession() throws HibernateException;
区分:openSession()与getCurrentSession():
1、openSession():每次都打开一个新的Session,用完需要关闭close();
2,、getCurrentSession():从上下文找,如果有就使用当前Session,没有就新建一个;当事务提交,会自动关闭。
用途:可以用来界定事务的边界。
使用getCurrentSession()方法必须在hibernate.cfg.xml中配置:<property name="current_session_context_class">thread</property>,否则报错无法找到session.
current_session_context_class上下文主要有两种:jta(java transaction api)和thread
thread:使用单个Connection,从数据库界定事务(单个数据库)
jta:从分布式事务边界的界定(多个数据库之间),需要外界提供一个事务管理器(TransactionManager):管理不同数据库的事务,记录各个数据库的操作,发生异常然后回滚
TransactionManager由ApplicationServer(应用服务器)提供,JBoss可以,但tomcat无法提供需要这种服务,可以借助第三方类库才可以(通过Spring的类库即可)。
(3)Hibernate对象的三种状态
Transient:瞬时状态(临时状态) Persistent:持久化状态 Detached:脱管状态(游离状态)
例子程序:
Teacher类:
1 package hibernate; 2 3 import javax.persistence.Entity; 4 import javax.persistence.GeneratedValue; 5 import javax.persistence.Id; 6 7 @Entity 8 public class Teacher { 9 10 11 12 private int id; 13 private String name; 14 15 private String title; 16 17 @Id 18 @GeneratedValue 19 public int getId() { 20 return id; 21 } 22 23 public void setId(int id) { 24 this.id = id; 25 } 26 27 public String getName() { 28 return name; 29 } 30 31 public void setName(String name) { 32 this.name = name; 33 } 34 35 public String getTitle() { 36 return title; 37 } 38 39 public void setTitle(String title) { 40 this.title = title; 41 } 42 43 44 }
测试类:
package hibernate; 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 testTeacher() { Teacher t = new Teacher(); // 没有设id t.setName("li"); t.setTitle("high"); // 执行到此时,状态为transient。 // 在内存中有一个session对象, Session session = sf.getCurrentSession(); session.beginTransaction(); // save后变成persistent session.save(t); // 打印出id System.out.println(t.getId()); // commit后自动close session,变成detached状态 session.getTransaction().commit(); } @AfterClass public static void afterClass() { sf.close(); } }
代码详细解读,内存分析:
1,当Theacher t = new Teacher(); t.setXXX后,此时的t是没有id的,只是在内存中有了一个Teacher对象t。此时状态就是transient。
2,当执行Session session = sf.getCurrentSession();内存中会有一个Session对象,session对象里有一个hashmap,他其实就是缓存:内存中的一块区域,放着一系列想要的提高读取效率的对象(的引用)。这个HashMap的key,是用来保存将要持久化的对象的id,value保存我们的对象,在这里就是t,其实是保存对象的引用,指向t对象。这都是准备工作,没有调用save方法,里边什么都没有。当执行了session.save(t);就在session的缓存里就有了t对象,key里有了id 1,value指向t对象。调用save方法的同时,会发出insert语句,在数据里也就有了t对象。
所以save完之后,内存里有t对象,数据库里也有t对象,称为persistent状态。
这样做的好处是:
提高效率,如果要找id=1的对象,直接从内存里去查,而不用去数据库里找。
3,当执行了session.getTransaction().commit();session自动关了,session对象没有了,缓存也没了。看图可知,此时t对象在内存中还有,只是HashMap指向t没了。t对象已经脱离了session的管理,称为detached 脱管状态。
总结:
hibernate对象三种状态的区分关键在于:
a)有没有id
b)id在数据库中有没有
c)在内存中有没有(session缓存)
三种状态:
a) transient :内存中一个对象,没id,缓存中也没有
b)persistent:内存中有对象,缓存中有,数据库中有(id)
c)detached:内存有对象,缓存没有,数据库有
可以参考文档:http://www.cnblogs.com/xujian2014/p/4804540.html