Hibernate具体执行流程
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hibernate具体执行流程相关的知识,希望对你有一定的参考价值。
客户端提删除请求 服务器端执行DAO操作
public class UserDao extends HibernateTemplate
public void deleteUser(Users users)
super.delete(users);
问题是这些如何跟Users.hbm.xml和Users.java(javabean)关联 配置文件里写好了就自动关联了吗?但是还是想弄明白原理
还有一个HibernateSessionFactory.java 他们之间的关系是怎么样的
能详细说下嘛?
对数据库的写操作包括保存、更新和删除,当保存一个POJO持久对象时,触发Hibernate的保存事件监听器
进行处理。Hibernate通过映射文件获得对象对应数据库表名以及属性所对应的表中的列名,然后通过反射机制
持久化对象(实体对象)的各个属性,最终组织成向数据库插入新对象的SQL insert语句。调用了
session.save()方法后,这个对象会标识成持久化状态存放在session中,对于Hibernate来说它就是一个持久化
了的对象,但这个时候Hibernate还不会真正的执行insert语句,当进行session的刷新同部或事务提交时,
Hibernate会把session缓存中的所有SQL语句一起执行,对于更新、删除操作也是采用类似的机制。
然后,提交事务并事务提交成功后,这些写操作就会被永久地保存进数据库中,所以,使用session对数据
库操作还依赖于Hibernate事务的处理。如果设置了二级缓存,那么这些操作会被同步到二级缓存中,Hibernate
对数据库最终操作也是依赖于底层JDBC对数据库进行 参考技术A Hibernate具体执行流程如下:
1 通过传过来的对象,得到类名称,然后根据这个名称,得到该目录下的对应的XML文件。
2 解析XML文件,生成相应的SQL文件。
3 应用反射,得到类中的相关字段的值。
4 进行保存 参考技术B hiberbate : 简单的理解就是 将类中的对象利用之中方式保存到数据库中,实现数据的持久化,而这种方式就是 运用java SE的,xml解析,反射机制,等完成操作,对与hibernate的 保存,删除,修改,底层还是运用JDBC的机制来对sql语句操作的,,,, 参考技术C JavaBean和对应的XML文件如何关联,我的猜想是这样的:
1.通过传过来的对象,得到类名称,然后根据这个名称,得到该目录下的对应的XML文件。
2.解析XML文件,生成相应的SQL文件。
3.应用反射,得到类中的相关字段的值。
4.进行保存
前段时间,因为项目的需要,也写过一个小小的例子来实现了这样的一个过程。
Hibernate的执行流程——SessionFactory的创建
Hibernate的执行流程:
1、创建Configuration类实例,用来读取并解析配置文件(如Hibernate.cfg.xml),一个Configuration实例代表hibernate所有Pojo类到SQL数据库映射的集合;
2、创建SessionFactory对象,用来读取并解析映射信息,同时将上一步Configuration对象中的所有配置信息copy到SessionFactory缓存中;
3、通过上一步创建的SessionFactory对象,打开Session;
4、开始事务,事务指Session提供的接口对数据库进行CRUD操作。
只有了解Hibernate的执行流程,才能够更好的理解SessionFactory的创建过程。
先放代码:
package com; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; import org.hibernate.service.ServiceRegistry; import org.hibernate.service.ServiceRegistryBuilder; public class HibernateSessionFactory { private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml"; private static final ThreadLocal<Session> sessionThreadLocal = new ThreadLocal<Session>();//创建一个ThreadLocal<Session>对象用来存放当前Session对象 private static Configuration configuration = new Configuration(); private static SessionFactory sessionFactory; private static String configFile = CONFIG_FILE_LOCATION; static { try{ configuration.configure();//读取并解析hibernate.cfg.xml文件
//在Hibernate4.x会使用注册机来解析映射信息,所以会先创建ServiceRegistry对象 ServiceRegistry serviceRgistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();
//ServiceRegister对象作为参数,使用configuration对象创建sessionFactory对象,即将configuration对象里的信息copy到sessionFactory缓存中 sessionFactory = configuration.buildSessionFactory(serviceRgistry); }catch(Exception e){ e.printStackTrace(); } }
//声明一个私有无参构造函数 private HibernateSessionFactory(){} public static SessionFactory getSessionFactory(){ return sessionFactory; } public static void rebuildSessionFactory(){ synchronized(sessionFactory){ try{ configuration.configure(configFile); ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry(); sessionFactory = configuration.buildSessionFactory(serviceRegistry); }catch(Exception e){ e.printStackTrace(); } } }
//打开session public static Session getSession(){
//获取当前线程的session对象 Session session = sessionThreadLocal.get(); try{ if(session == null || !session.isOpen()){ if(sessionFactory == null){//如果sessionFactory为null,创建一个 rebuildSessionFactory(); }
//如果session没有打开,就用sessionFactory打开 session = (sessionFactory!=null)?sessionFactory.openSession():null;
//将session对象放到ThreadLocal对象里,以便使用 sessionThreadLocal.set(session); } }catch(Exception e){ e.printStackTrace(); } return session; } public static void closeSession(){ Session session = sessionThreadLocal.get(); sessionThreadLocal.set(null); try{ if(session != null && session.isOpen()){ session.close(); } }catch(Exception e){ e.printStackTrace(); } } public static void setConfigFile(String configFile){ HibernateSessionFactory.configFile = configFile; sessionFactory = null; } public static Configuration getConfiguration(){ return configuration; } }
代码里已经有部分注释,相信足够理解代码了。这里特别注意的一点就是,这个SessionFactory创建代码使用的jar包是Hibernate4.x,如果使用5.x以上版本,需要对创建SessionFactory过程做出以下改变:
//添加add(User.class),这个User类是一个POJO类,对应数据库的一个user表,hibernate.cfg.xml里面有配置的,如果没有这一条语句,将会报错:Unknow Entity xxx
configuration。add(User.class); configuration.configure();//读取并解析hibernate.cfg.xml文件 //在Hibernate5.x会使用注册机来解析映射信息,所以会先创建ServiceRegistry对象,使用StandardServiceRegistryBuilder() ServiceRegistry serviceRgistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build(); //ServiceRegister对象作为参数,使用configuration对象创建sessionFactory对象,即将configuration对象里的信息copy到sessionFactory缓存中 sessionFactory = configuration.buildSessionFactory(serviceRgistry);
细心的读者可以看出,创建出来的SessionFactory是线程安全的,因此SessionFactory可以同时被多个线程共享,但是正常情况下,session并不是线程安全,每个线程都会使用这个session实例,如果多个线程同时操作数据库时,某个线程将session关闭了,正在操作数据库的线程就会出现异常,为了解决这个问题,代码中使用ThreadLocal对象来保证session的线程安全,这样的话,每个线程只会操作当前session实例的副本,不影响其他线程。
以上是关于Hibernate具体执行流程的主要内容,如果未能解决你的问题,请参考以下文章
Struts 2 Spring Hibernate三大框架的执行流程以及原理
java面试题_简单说明hibernateStruts2SpringspringMVCmybatis的执行流程或者原理_1_hibernate