hibernate session,hibernate session 需要关闭吗
hibernate session,hibernate session 需要关闭吗详细介绍
本文目录一览: Hibernate session的方法的一些说明
用Hibernate肯定会频繁的用到session 下面就将Hibernate session中一些经常的用方法逐个的解释一下
Transaction beginTransaction()
开始一个工作单元并返回一个与之相关Transaction对象 最为事务的开始 通常在需要对数据库进行更改例如save update或delete时使用 在事务结束后需要调用Transaction的mit方法提交更改 该方法必须在Hibernate session关闭之前使用
void flush() void clear()
这两个方法通常在一起使用 由于Hibernate有缓存数据的功能 所以当我们要批量查询和批量插入时 会因为大量的缓存而导致内存溢出 所以我们可以在执行批量插入时插入一定数目的数据后调用flush()提交插入 然后调用clear()清空当前Hibernate session内的所有缓存 批量查询同理
Connection close()
关闭Hibernate session 同时清空所有的缓存
Connection connection()
获取当前Hibernate session使用的JDBC connection
boolean contains(Object object)
返回boolean值 判断一个实例是否与当前Hibernate session保持关联 即为持久化状态
Query createQuery(String queryString)
返回一个给定HQL语句的Query对象
SQLQuery createSQLQuery(String queryString)
返回一个用于执行原生SQL语句的SQLQuery对象
void delete(Object object)
删除与该对象关联的数据里内的一条记录 该对象可以是处于持久化状态也可以是处于瞬态但与数据库的记录有id联系 如果该对象的cascade属性为delete或all将会同时删除相关联的数据
void delete(String entityName Object object)
不太明白什么意思 占个位
Connection disconnect()
断开与session与当前JDBC的连接 如果连接有Hibernate管理 则将连接送回连接池 否则将送回给程序本身
Object get(Class clazz Serializable id)
根据指定的实体类以及实体id返回一个实体的实例 如果找不到记录则返回null
Object get(String entityName Serializable id)
同上 entity为实体的名字
String getEntityName(Object object)
返回一个持久化类的实体名
Serializable getIdentifier(Object object)
返回一个被session缓存的实体实例的id
Query getNamedQuery(String queryName)
返回一个在映射文件中定义的命名查询的query对象
SessionFactory getSessionFactory()
获取生成当前session的SessionFactory
Transaction getTransaction()
不说了 地球人都知道
Object load(Class theClass Serializable id)
Object load(String entityName Serializable id)
和get方法一个效果 不同的是该方法在找不到对应记录时会抛出异常
Serializable save(Object object)
将一个实体实例持久化 返回该持久化实例的id 在持久化之前必须手动或自动的指派id
void update(Object object)
通过给定的分离状态的实例的id更新数据库记录 如果在持久化类中有相同的id则会抛出异常 如果这个实例cascade设置为save update或all是将同时更新所有关联的实例记录
lishixinzhi/Article/program/Java/ky/201311/28676
Hibernate的session是怎么创建的
Hibernat
对数据库的操作是通过Session来实现的,这里的session不同于页面间传递参数的session,
而是类似于JDBC中的
Connection。Session是Hibernate运作的中心,对象的生命周期、事务的管理、数据库的存取都与session息息相关。
Session是由HibernateSessionFactory创建的,是线程安全的,可以让多个执行线程同时存取
HibernateSessionFactory而不会有数据共享的问题,但不能让多个线程共享一个Session。
SessionFactory对象的创建:
Java代码
Configuration
cfg
=
new
Configuration().configure();
SessionFactory
sessions
=
cfg.buildSessionFactory();
session创建时使用了一个ThreadLocal类来建立一个Session管理的辅助类,使用ThreadLocal可以有效隔离执行所用的数据,
避开了Session的多线程之间的数据共享问题。
//创建一个线程本地变量。
Java代码
public
static
final
ThreadLocal
threadlocal
=
new
ThreadLocal
();
public
static
org.hibernate.SessionFactory
sessionFactory;
//获取session的方法
public
static
Sessin
getSession()
throws
HibernateException{
//返回线程局部变量的当前线程的值
Session
s
=
(Session)threadLocal.get();
//如果sessionFactory为空,重新创建sessionFactory;如果线程为空,就打开一个新的session
if(session==null
||
!session.isOpen()){
if(sessionFactory
==
null){
rebuildSessionFactory();
session
=
(sessionFactory
!=
null)
sessionFactory.openSession():null;
//
将hibernate的session放入到线程中保存;只要这个线程不结束,都可以通过线程的get()方法来获取
threadLocal.set(session);return
session;
hibernate为什么要有session
你好,getcurrentsession得到的session是和事务绑定的session,所以:
1,要用getcurrentsession生产的session,就必须有事务环境,意思就是你必须在调用session方法之前,session.begintransaction();就算你只是get或者query
2,在事务提交之后,即session.gettransaction().commit()之后,session自动关闭,所以你用getcurrentsession,只需要commit事务,不要去调用session.close()
3,你用的是ssh,spring为hibernate的current_session_context_class配置了一个springsessioncontext来帮你管理getcurrentsession中的session,所以,你在opensessioninview的时候,spring就自动的帮你打开了session——>你在执行用aop包装的事务的时候,事务就开启了——>执行你的业务方法——>提交事务(注意,hibernate管理的getcurrentsession在提交事务的时候才会关闭session,而spring提供的这个springsessioncontext不会)——>opensessioninview关闭session。
从上面的执行流程可以看出,你在ssh集成的时候,如果用的是getcurrentsession的集成方式,就不能设置hibernate的current_session_context_class为thread,而应该空着,让spring帮你。
这个是框架开发者设计的,没有为什么,只是把原生的java连接数据库的代码,和一些常用的操作进行了一层封装,使开发人员使用更简单,下面再详细介绍一下Session:
(1)
单线程的,短寿命的对象,代表了一次会话的过程。实际上是把一个JDBC
Connection
打包
了,它可以包含一些持久化对象的缓存看作介于数据连接与事物管理一种中间接口.
在
hibernate
的设计者中.他们将session看作介于数据连接与事物管理的一种中间接口或者想象成一个持久对象的缓冲区
hibernate能检测到这些持久对象的改变,并及时刷新数据库
(2)
每一个Session实例和一个
数据库事务
绑定
通常将每一个Session实例和一个数据处理库事务绑定
就是说,每执行一个数据库事务(操作),都应该先创建一个新的Session实例.
如果事务执行中出现异常,应该撤消事务.
不论事务执行成功与否,最后都应该调用Session的close()方法,从而释放Session实例占用的资源.
(3)
如何获得
Session对象
首先创建SessionFactory对象
应用服务器
如果访问多个数据源时,则应该产生多个SessionFactory;
但是仅仅为了服务与某个请求时,不要创建一个新的SessionFactory,因为创建SessionFactory需要消耗大量的资源.
然后根据SessionFactory再创建Session对象
Hibernate中Session什么意思
Hibernate中Session是数据库的一个连接,一个session就是一个连接,相当于jdbc。connection。平时的session是用户的会话,记录用户的信息
一.主配置
◆查询缓存,同下面讲的缓存不太一样,它是针对HQL语句的缓存,即完全一样的语句再次执行时可以利用缓存数据。但是,查询缓存在一个交易系统(数据变更频繁,查询条件相同的机率并不大)中可能会起反作用:它会白白耗费大量的系统资源但却难以派上用场。
◆fetch_size,同JDBC的相关参数作用类似,参数并不是越大越好,而应根据业务特征去设置
◆batch_size同上。
◆生产系统中,切记要关掉SQL语句打印。
二.Hibernate Session缓存
1.数据库级缓存:这级缓存是最高效和安全的,但不同的数据库可管理的层次并不一样,比如,在ORACLE中,可以在建表时指定将整个表置于缓存当中。
2.Session缓存:在一个Hibernate Session有效,这级缓存的可干预性不强,大多于Hibernate自动管理,但它提供清除缓存的方法,这在大批量增加/更新操作是有效的。比如,同时增加十万条记录,按常规方式进行,很可能会发现OutofMemeroy的异常,这时可能需要手动清除这一级缓存:Session.evict以及 Session.clear
3.应用缓存:在一个SessionFACTORY中有效,因此也是优化的重中之重,因此,各类策略也考虑的较多,在将数据放入这一级缓存之前,需要考虑一些前提条件:
◆数据不会被第三方修改(比如,是否有另一个应用也在修改这些数据?)
◆数据不会太大
◆数据不会频繁更新(否则使用CACHE可能适得其反)
◆数据会被频繁查询
◆数据不是关键数据(如涉及钱,安全等方面的问题)。
Hibernate Session缓存有几种形式,可以在映射文件中配置:read-only(只读,适用于很少变更的静态数据/历史数据),nonstrict-read- write,read-write(比较普遍的形式,效率一般),transactional(JTA中,且支持的缓存产品较少)
4.分布式缓存:同3)的配置一样,只是缓存产品的选用不同,在目前的Hibernate中可供选择的不多,oscache, jboss cache,目前的大多数项目,对它们的用于集群的使用(特别是关键交易系统)都持保守态度。在集群环境中,只利用数据库级的缓存是最安全的。
三.延迟加载
◆实体延迟加载:通过使用动态代理实现
◆集合延迟加载:通过实现自有的SET/LIST,Hibernate提供了这方面的支持
Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。
Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用,最具革命意义的是,Hibernate可以在应用EJB的J2EE架构中取代CMP,完成数据持久化的重任。
Session:在计算机中,尤其是在网络应用中,称为"会话控制"。Session 对象存储特定用户会话所需的属性及配置信息。这样,当用户在应用程序的 Web 页之间跳转时,存储在 Session 对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。
当用户请求来自应用程序的 Web 页时,如果该用户还没有会话,则 Web 服务器将自动创建一个 Session 对象。当会话过期或被放弃后,服务器将终止该会话。Session 对象最常见的一个用法就是存储用户的首选项。
例如,如果用户指明不喜欢查看图形,就可以将该信息存储在 Session 对象中。有关使用 Session 对象的详细信息,请参阅"ASP 应用程序"部分的"管理会话"。注意 会话状态仅在支持 cookie 的浏览器中保留。
HIBERNATE是 自然水公司SESSION 是从自然水公司到你家里的管道。要用水,你必须先造一个管道。如果延迟加载的话,记得把水龙头开着。
Hibernate中Session 是Hibernate中的缓存对象 用此session操作数据库后会缓存返回的结果在session里面 当你再次操作数据库的时候 如果session缓存里面有相应的值 则不用去与数据库交互直接返回结果
servlet 中的Session 也是缓存 其缓存你与服务器对话时候的一些信息
总之所有的session基本都是起缓存作用的 就是把一些信息缓存在内存中 方便存取值
但是不同的session是不能相互直接赋值的 因为是两个不同的概念 只是名字一样
名字一样也是为了帮助程序员理解 学了servlet的session 后再遇到session也就应该是缓存作用的
不知道我的回答你满意不
hibernate session 什么时候关闭
你好,getCurrentSession得到的session是和事务绑定的session,所以:
1,要用getCurrentSession生产的session,就必须有事务环境,意思就是你必须在调用session方法之前,session.beginTransaction();就算你只是get或者query
2,在事务提交之后,即session.getTransaction().commit()之后,session自动关闭,所以你用getCurrentSession,只需要commit事务,不要去调用session.close()
3,你用的是ssh,spring为
hibernate
的current_session_context_class配置了一个SpringSessionContext来帮你管理getCurrentSession中的session,所以,你在OpenSessionInview的时候,spring就自动的帮你打开了session——>你在执行用AOP包装的事务的时候,事务就开启了——>执行你的业务方法——>提交事务(注意,hibernate管理的getCurrentSession在提交事务的时候才会关闭session,而spring提供的这个SpringSessionContext不会)——>opensessioninview关闭session。
从上面的执行流程可以看出,你在SSH集成的时候,如果用的是getCurrentSession的集成方式,就不能设置hibernate的current_session_context_class为thread,而应该空着,让spring帮你。
如何查看hibernate session是否关闭
hibernate判断session是否关闭的方法:
1、通常需要首先获得session:
public
static
Session
getSession()
{
Session
session
=
threadLocal.get();
if(session
==
null){
session
=
sessionFactory.openSession();
threadLocal.set(session);
}
return
session;
}
2、从session中开启事务:
Transaction
tx
=
session.beginTransaction();
try
{
for
(int
i
=
0;
i
<
mesages.size();
i++)
{
Message
message
=
messages.get(i);
session.save(message);
if
(i
%
75
==
0)
{
//
flush
a
batch
of
inserts
and
release
memory:
session.flush();
session.clear();
}
}
tx.commit();
}catch
(Exception
e)
{
//
TODO
Auto-generated
catch
block
e.printStackTrace();
tx.rollBack();
}finally{
session.close();
}
}
3、关闭session,调用
session.close()。
hibernate怎么判断session是否关闭
hibernate判断session是否关闭的方法:
1、通常需要首先获得session:
public static Session getSession() {
Session session = threadLocal.get();
if(session == null){
session = sessionFactory.openSession();
threadLocal.set(session);
}
return session;
}
2、从session中开启事务:
Transaction tx = session.beginTransaction();
try {
for (int i = 0; i < mesages.size(); i++) {
Message message = messages.get(i);
session.save(message);
if (i % 75 == 0) {
// flush a batch of inserts and release memory:
session.flush();
session.clear();
}
}
tx.commit();
}catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
tx.rollBack();
}finally{
session.close();
}
}
3、关闭session,调用 session.close()。
利用ThreadLocal绑定Hibernate的session
无论是立即加载还是延迟加载必须要连接数据库的 而在java中连接数据库是依赖java sql Connection 在hibernate中session就是Connection的一层高级封装 一个session对应了一个Connection 要实现延迟加载必须有session才行 而且要进行延迟加载还必须保证是同一个session才行 用另外一个session去延迟加载前一个session的代理对象是不行的 大家都知道Connection是使用过后必须要进行关闭的 那么我们如何保证一次请求过程中 一直都使用一个session呢 即一个Connection呢 而且还要保证请求结束后正确的关闭
好 现在我们知道了我们要解决的问题
如何保证请求结束后正确的关闭session
如何保证请求过程中一直使用同一个session
第一个问题很容易想到 使用过滤器
view plaincopy to clipboardprint? public void doFilter(ServletRequest request ServletResponse response
FilterChain filterChain) {
try {
filterChain doFilter(request response);
} catch (IOException e) {
e printStackTrace();
} catch (ServletException e) {
e printStackTrace();
} finally {
try {
mitTransaction();
} catch (Exception e) {
HibernateUtil rollbackTransaction();
} finally {
HibernateUtil closeSession();
}
}
}
public void doFilter(ServletRequest request ServletResponse response
FilterChain filterChain) {
try {
filterChain doFilter(request response);
} catch (IOException e) {
e printStackTrace();
} catch (ServletException e) {
e printStackTrace();
} finally {
try {
mitTransaction();
} catch (Exception e) {
HibernateUtil rollbackTransaction();
} finally {
HibernateUtil closeSession();
}
}
}要解决第二个问题我们必须先搞清楚 请求在java中是以什么样的机制实现的 在java中一个请求就是一个线程 像流行的web容器Tomcat等 往往都是采用线程池机制的也就是说有n个线程在池子里面 每当有请求时 随机从线程池中取出一个线程对象去处理请求 实际上多次请求可能使用的是同一线程也可能不是 这是随机的 要保证整个请求中使用同一session最容易想到的就是把这个session绑定到线程上 在java中使用ThreadLocal可以轻松绑定变量 每个线程有一个自己的ThreadLocal 这个ThreadLocal会随线程的销毁一起销毁 既然是每个线程有一个那么多个线程间自然是不会有影响了 所以把session绑定在ThreadLocal里面是最好的选择了
有关ThreadLocal的更多资料 大家可以百度或者参考
最后我把相关的代码发出来
view plaincopy to clipboardprint? import java sql SQLException;
import hibernate HibernateException;
import hibernate Session;
import hibernate SessionFactory;
import hibernate Transaction;
import hibernate cfg Configuration;
import java sql Connection;
import apache log j Logger;
import java io File;
/**
*
*
* Title:Hibernate工具类
*
*
*
* 利用ThreadLocal 绑定 Hibernate 的session
*
*
* @author 孙钰佳
* @mail
* @version
*/
public class HibernateUtil {
/**
* Loger j的logger
*/
private static final Logger logger = Logger getLogger(HibernateUtil class);
/**
* 存储hibernate session的ThreadLocal
*/
private static final ThreadLocal sessionThread = new ThreadLocal();
/**
* 存储事务的ThreadLocal
*/
private static final ThreadLocal transactionThread = new ThreadLocal();
/**
* Hibernate 的 Session工厂
*/
private static SessionFactory sessionFactory = null;
/**
* 初始化SessionFactory
*
* @param file
* Hibernate配置文件
*/
public static void initSessionFactory(File file) {
Configuration config = new Configuration();
nfigure(file);
sessionFactory = config buildSessionFactory();
}
/**
* 获取当前线程绑定的session
*
* @return Session
* @throws HibernateException
*/
public static Session getSession() {
Session s = (Session) sessionThread get();
if (s == null) {
s = sessionFactory openSession();
sessionThread set(s);
} else {
Connection conn = nnection();
try {
if (conn == null || conn isClosed()) {
try {
s close();
} catch (HibernateException e) {
logger warn( close session error: + e getMessage() e);
}
s = sessionFactory openSession();
sessionThread set(s);
}
} catch (SQLException e) {
throw new HibernateException(e);
}
}
return s;
}
/**
* 取得当前session的事务
*
* @return Transaction
*/
public static Transaction transaction() {
Transaction transaction = (Transaction) transactionThread get();
if (transaction == null) {
transaction = getSession() beginTransaction();
transactionThread set(transaction);
}
return transaction;
}
/**
* 提交当前session的事务
*/
public static void mitTransaction() {
Transaction transaction = (Transaction) transactionThread get();
transactionThread set(null);
if (transaction != null)
mit();
}
/**
* 回滚当前session的事务
*/
public static void rollbackTransaction() {
Transaction tx = (Transaction) transactionThread get();
transactionThread set(null);
if (tx != null)
tx rollback();
}
/**
* 关闭当前线程使用的session
*/
public static void closeSession() {
Session session = (Session) sessionThread get();
if (session != null) {
session clear();
session close();
sessionThread set(null);
}
}
}
import java sql SQLException;
import hibernate HibernateException;
import hibernate Session;
import hibernate SessionFactory;
import hibernate Transaction;
import hibernate cfg Configuration;
import java sql Connection;
import apache log j Logger;
import java io File;
/**
*
*
* Title:Hibernate工具类
*
*
*
* 利用ThreadLocal 绑定 Hibernate 的session
*
*
* @author 孙钰佳
* @mail
* @version
*/
public class HibernateUtil {
/**
* Loger j的logger
*/
private static final Logger logger = Logger getLogger(HibernateUtil class);
/**
* 存储hibernate session的ThreadLocal
*/
private static final ThreadLocal sessionThread = new ThreadLocal();
/**
* 存储事务的ThreadLocal
*/
private static final ThreadLocal transactionThread = new ThreadLocal();
/**
* Hibernate 的 Session工厂
*/
private static SessionFactory sessionFactory = null;
/**
* 初始化SessionFactory
*
* @param file
* Hibernate配置文件
*/
public static void initSessionFactory(File file) {
Configuration config = new Configuration();
nfigure(file);
sessionFactory = config buildSessionFactory();
}
/**
* 获取当前线程绑定的session
*
* @return Session
* @throws HibernateException
*/
public static Session getSession() {
Session s = (Session) sessionThread get();
if (s == null) {
s = sessionFactory openSession();
sessionThread set(s);
} else {
Connection conn = nnection();
try {
if (conn == null || conn isClosed()) {
try {
s close();
} catch (HibernateException e) {
logger warn( close session error: + e getMessage() e);
}
s = sessionFactory openSession();
sessionThread set(s);
}
} catch (SQLException e) {
throw new HibernateException(e);
}
}
return s;
}
/**
* 取得当前session的事务
*
* @return Transaction
*/
public static Transaction transaction() {
Transaction transaction = (Transaction) transactionThread get();
if (transaction == null) {
transaction = getSession() beginTransaction();
transactionThread set(transaction);
}
return transaction;
}
/**
* 提交当前session的事务
*/
public static void mitTransaction() {
Transaction transaction = (Transaction) transactionThread get();
transactionThread set(null);
if (transaction != null)
mit();
}
/**
* 回滚当前session的事务
*/
public static void rollbackTransaction() {
Transaction tx = (Transaction) transactionThread get();
transactionThread set(null);
if (tx != null)
tx rollback();
}
/**
* 关闭当前线程使用的session
*/
public static void closeSession() {
Session session = (Session) sessionThread get();
if (session != null) {
session clear();
session close();
sessionThread set(null);
}
}
}
下面是一个调用的例子: view plaincopy to clipboardprint? public static void main(String[] args) throws Exception {
HibernateUtil initSessionFactory(new File(Test class getClassLoader()
getResource( hibernate cfg xml ) getFile()));
Session session = HibernateUtil getSession();
HibernateUtil transaction();
User u = new User();
u setName( test );
session save(u);
mitTransaction();
HibernateUtil closeSession();
lishixinzhi/Article/program/Java/ky/201311/28894
在hibernate中,session的作用是什么,怎么用呢,谢谢各位大虾了。
你好,Session表示的是一次会话,你能理解这点很重要,在hibernate中,这次会话的主要任务就是操作数据库,包括增删改查,开启事务等等。
不用框架,纯java代码操作数据库用的是jdbc,代码量太多
用hibernate则是简化了原先的jdbc操作数据库时——增删改查,需要写大量sql语句的弊端
因此,hibernate就用session的一些方法来代替原先的增删改查操作:例如
session.save();//保存
session.get();//获取
session.delete()//删除
session.update();//修改等等
方法我就不一一介绍;
下面说一下用hibernate的三个必须要了解的三个方面(具体代码我就不写了,你去hibernate框架提供的例子里面找,hibernate有中文文档提供给你的)
1。主配置文件:hibernate.cfg.xml:
用来 配置数据库连接;
映射文件的配置;
其他一些配置;
2。映射文件:XXX.hbm.xml //XXX代表你要关联的类的名称是是什么,你就写什么
向数据中存储数据需要用对象来存储封装,那数据库怎样将对象的属性跟数据库中表的属性对应,就需要你写映射文件;(这是学习重点,量比较多)
3。api:也就是你上面问的session的用法等等
这部分只要了解一些简单操作就行,往往得到session后代码就一句话,这块比较简单,重点还是映射文件那块,只要配置文件整出来,这块不成问题。
hibernate session 需要关闭吗
1、getCurrentSession()与openSession()的区别?
* 采用getCurrentSession()创建的session会绑定到当前线程中,而采用openSession(),创建的session则不会
* 采用getCurrentSession()创建的session在commit或rollback时会自动关闭,而采用openSession(),创建的session必须手动关闭
2、使用getCurrentSession()需要在hibernate.cfg.xml文件中加入如下配置:
* 如果使用的是本地事务(jdbc事务)
thread
* 如果使用的是全局事务(jta事务)
jta
openSession() 与 getCurrentSession() 有何不同和关联呢?
在 SessionFactory 启动的时候, Hibernate 会根据配置创建相应的 CurrentSessionContext ,在getCurrentSession() 被调用的时候,实际被执行的方法是 CurrentSessionContext.currentSession() 。在currentSession() 执行时,如果当前 Session 为空, currentSession 会调用 SessionFactory 的 openSession 。所以 getCurrentSession() 对于 Java EE 来说是更好的获取 Session 的方法。
许多时候出现session is close();原因就是你在hibernate.cfg.xml里面设置了
thread
系统在commit();执行完之后就关闭了session,这时候你手动再关闭session就当然提示错误了