第三十一天 慵懒的投射在JDBC上的暖阳 —Hibernate的使用(四)

6月19日,小雨。“黄梅时节家家雨,青草池塘处处蛙。有约不来过夜半,闲敲棋子落灯花。”

面向对象无限包容的个性,给对SQL和数据库一窍不通的澳大利亚人Gavin King创造了极大的想象空间。那些原本尴尬的不利因素---OO对象模型和关系型数据库之间的设计理念上的差异即-“O/R阻抗失衡(O/R Impedance
Mismatch)”等。在澳大利亚人的转化手段中,都被自觉或不自觉地消除了。Hibernate的出现,让面向对象的对象模型和关系型数据库的数据结构之间的相互转换达到了一种高峰。好的coder对Hibernate的Session的理解往往会让人大吃一惊。或许可以说,澳大利亚人用Session表达了自己柔软变通的适应性。所有的这些,让每一个Session在open和close之间的短暂生命得到了升华。

Session接口负责执行被持久化对象的CRUD操作(CRUD的任务是完成与数据库的交流,包含了很多常见的SQL语句。)。但需要注意的是Session对象是非线程安全的。

1、自己动手,封装HibernateUtil类

在运用中为避免资源消耗,一般都会手动封装一个HibernateUtil类(未使用Spring管理的前提下)。该类的作用使Hibernate加载配置文件config, 创建sessionFactory等只运行一次。

package edu.eurasia.hibernate;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;

/**
 * Configures and provides access to Hibernate sessions, tied to the current
 * thread of execution.
 */
public class HibernateUtil {

	/**
	 * Location of hibernate.cfg.xml file. NOTICE: Location should be on the
	 * classpath as Hibernate uses #resourceAsStream style lookup for its
	 * configuration file. That is place the config file in a Java package - the
	 * default location is the default Java package.<br>
	 * <br>
	 * Examples: <br>
	 * <code>CONFIG_FILE_LOCATION = "/hibernate.conf.xml".
	 */
	private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml";

	/** Holds a single instance of Session */
	private static final ThreadLocal threadLocal = new ThreadLocal();

	/** The single instance of hibernate configuration */
	private static final Configuration cfg = new Configuration();

	/** The single instance of hibernate SessionFactory */
	private static org.hibernate.SessionFactory sessionFactory;

	/**
	 * Returns the ThreadLocal Session instance. Lazy initialize the
	 * <code>SessionFactory</code> if needed.
	 *
	 * @return Session
	 * @throws HibernateException
	 */
	public static Session currentSession() throws HibernateException {
		Session session = (Session) threadLocal.get();

		if (session == null || !session.isOpen()) {
			if (sessionFactory == null) {
				try {
					cfg.configure(CONFIG_FILE_LOCATION);
					sessionFactory = cfg.buildSessionFactory();
				} catch (Exception e) {
					System.err.println("%%%% Error Creating SessionFactory %%%%");
					e.printStackTrace();
				}
			}
			session = (sessionFactory != null) ? sessionFactory.openSession()
					: null;
			threadLocal.set(session);
		}

		return session;
	}

	/**
	 * Close the single hibernate session instance.
	 *
	 * @throws HibernateException
	 */
	public static void closeSession() throws HibernateException {
		Session session = (Session) threadLocal.get();
		threadLocal.set(null);

		if (session != null) {
			session.close();
		}
	}

	/**
	 * Default constructor.
	 */
	private HibernateUtil() {
	}
}

2、 Hibernate使用事务

Hibernate对JDBC进行了轻量级的封装,它本身在设计时并不具备事务处理功能。Hibernate将底层的JDBCTransaction或JTATransaction进行了封装,再在外面套上Transaction和Session的外壳,其实是通过委托底层的JDBC或JTA来实现事务的处理功能的。

package edu.eurasia.hibernate;

import java.util.Iterator;
import org.hibernate.Session;
import org.hibernate.Transaction;

public class SimpleTransaction {
	public static void main(String[] args) {
		SimpleTransaction simpleTran = new SimpleTransaction();
		simpleTran.tran();
	}

	// 演示事务使用的方法
	public void tran() {
		// 得到当前事务
		Session session = HibernateUtil.currentSession();
		// 声明事务
		Transaction tx = null;
		try {
			// HQL查询语句
			String hql = "from UserInfo";
			// 事务的开始
			tx = session.beginTransaction();
			// 事务的中间操作
			Iterator it = session.createQuery(hql).list().iterator();
			while (it.hasNext()) {
				UserInfo userinfo = (UserInfo) it.next();
				System.out.println(userinfo.getUsername()+"  "+userinfo.getPassword());
			}
			// 提交事务
			tx.commit();
		} catch (Exception ex) {
			if (tx != null) {
				try {
					// 回滚事务
					tx.rollback();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		} finally {
			// 关闭session
			session.close();
		}
	}
}

3、MySQL数据库,UserInfo类,映射文件UserInfo.hbm.xml和hibernate.cfg.xml配置文件见:

第十九天 慵懒的投射在JDBC上的暖阳 —Hibernate的使用(一)

4、还需要添加一个slf4j-nop-1.6.2.jar文件。工程结构如下:

实际运用中,经常需要将当前线程和session绑定.一般的用法为使用ThreadLocal: 在HibernateUtil类中封装hibernate的管理.通过openSession取得session,并将其放入ThreadLocal变量中.
这样业务逻辑中仅需通过工具类取得当前线程对应的session.使用完毕后,调用工具类closeSession方法将session关闭,当前线程的ThreadLocal变量置为NULL. 保证线程归还线程池复用后,ThreadLocal为空,以免出现导致其它线程访问到本线程变量。

而后,Hibernate的SessionFactory提供获取session的新方法getCurrentSession (获得与当前线程绑定的session). 内部通过代理封装,此方式得到的session不仅和当前线程绑定,也无需手动开关.
默认在事务提交之后,session自动关闭。

末了,引入Spring之后.sessionfactory的创建等都交给spring管理.Spring也提供了HibernateTemplate, HibernateDaoSupport这样的封装方法。用户可以不再考虑session的管理,事务的开启关闭.只需配置事务即可。

第三十一天 慵懒的投射在JDBC上的暖阳 —Hibernate的使用(四)

时间: 2024-10-06 05:00:59

第三十一天 慵懒的投射在JDBC上的暖阳 —Hibernate的使用(四)的相关文章

第二十五天 慵懒的投射在JDBC上的暖阳 —Hibernate的使用(四)

6月4日,晴天."晴日暖风生麦气,绿阴幽草胜花时."      "道"是只有中国人才懂得并孜孜以求的特殊的宇宙存在感的体验.全世界只有中文才能阐释"道"的全部涵义.然而所谓阐释,并不重在定义,更多的还是感受. "道"既在"虚无"之内,又超越了"虚无",成为中国文化最平常但又最玄妙的一种境界. 老庄认为:道是宇宙的本体,即是宇宙万物的老祖宗.    老外认为:Tao is the sour

三十一、Git中的fetch和pull

Git中从远程的分支获取最新的版本到本地有这样2个命令: 1. git fetch:相当于是从远程获取最新版本到本地,不会自动merge     git fetch origin master git log -p master..origin/master git merge origin/master 以上命令的含义:   首先从远程的origin的master主分支下载最新的版本到origin/master分支上   然后比较本地的master分支和origin/master分支的差别  

[原创]ActionScript3游戏中的图像编程(连载三十一)

2.2.4 Photoshop转Flash的投影角度换算 继续往下看,Photoshop不透明度选项下面是投影角度,默认值是120°,而Flash里角度是45°,两者相差将近90°,投影角度却相近,为什么?让我们把Flash的投影滤镜也设置成120°.(图 2.20) 图 2.20 角度值等于120的Flash投影 投影跑左边去了,x方向与Photoshop里的投影位置截然相反.经观察,Flash投影的角度与ActionScript的坐标系完全一致,它等于当前方向与水平线的夹角,顺时针为正,逆时

【FastDev4Android框架开发】RecyclerView完全解析之下拉刷新与上拉加载SwipeRefreshLayout(三十一)

转载请标明出处: http://blog.csdn.net/developer_jiangqq/article/details/49992269 本文出自:[江清清的博客] (一).前言: [好消息]个人网站已经上线运行,后面博客以及技术干货等精彩文章会同步更新,请大家关注收藏:http://www.lcode.org 话说RecyclerView已经面市很久,也在很多应用中得到广泛的使用,在整个开发者圈子里面也拥有很不错的口碑,那说明RecyclerView拥有比ListView,GridVi

centos 邮件服务 第三十一节课

centos   邮件服务  第三十一节课 上半节课 下半节课 f

ActionScript3游戏中的图像编程(连载三十一)

2.2.4 Photoshop转Flash的投影角度换算 继续往下看,Photoshop不透明度选项下面是投影角度,默认值是120°,而Flash里角度是45°,两者相差将近90°,投影角度却相近,为什么?让我们把Flash的投影滤镜也设置成120°.(图 2.20) 图 2.20 角度值等于120的Flash投影 投影跑左边去了,x方向与Photoshop里的投影位置截然相反.经观察,Flash投影的角度与ActionScript的坐标系完全一致,它等于当前方向与水平线的夹角,顺时针为正,逆时

微信小程序把玩(三十一)wx.uploadFile(object), wx.downloadFile(object) API

原文:微信小程序把玩(三十一)wx.uploadFile(object), wx.downloadFile(object) API 反正我是没有测通这两个API!!!!不知道用的方式不对还是其他的!!!先记录下回头再说... 主要方法: wx.uploadFile(OBJECT)上传 wx.downloadFile(OBJECT)下载 wxml <button type="primary" bindtap="listenerButtonDownLoadFile"

QT开发(三十一)——NotePad实例开发

QT开发(三十一)--NotePad实例开发 一.界面开发 NotePad使用主窗口作为顶层窗口组件,使用QMainWindow作为基类,QMainWindow内部封装了菜单栏.工具栏.中央组件.停靠组件.状态栏等.QMainWindow内置了布局管理器,基本的组件布局如下: 使用二阶构造模式构建NotePad界面. MainWindow::MainWindow() {     resize(800, 600); }   MainWindow::~MainWindow() {   }   Mai

三十一、Java图形化界面设计——布局管理器之GridLayout(网格布局)

摘自http://blog.csdn.net/liujun13579/article/details/7772491 三十一.Java图形化界面设计--布局管理器之GridLayout(网格布局) 网格布局特点: l  使容器中的各组件呈M行×N列的网格状分布. l  网格每列宽度相同,等于容器的宽度除以网格的列数. l  网格每行高度相同,等于容器的高度除以网格的行数. l  各组件的排列方式为:从上到下,从左到右. l  组件放入容器的次序决定了它在容器中的位置. l  容器大小改变时,组件