先说下实验项目环境:
hibernate项目jar包
hibernate-3.2.6.ga.jar
proxool-0.9.0RC3.jar
JDK1.6
Mysql数据库
项目介绍
主要是通过Hibernate所谓数据库的持久层,其中用连接池proxool来管理Hibernate的Session。
项目搭建
1.创建hibernateDemo项目
2.添加hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="proxool.pool_alias">proxoolPool</property> <property name="proxool.xml">proxool.xml</property> <property name="connection.provider_class"> org.hibernate.connection.ProxoolConnectionProvider </property> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="show_sql">true</property> <property name="format_sql">false</property> </session-factory> </hibernate-configuration>3.添加proxool.xml
<?xml version="1.0" encoding="utf-8"?> <something-else-entirely> <proxool> <!-- 连接池名称 与 hibernate 设置的 proxool.pool_alias 参数要一致 --> <alias>proxoolPool</alias> <!-- proxool只能管理由自己产生的连接 --> <driver-url> jdbc:mysql://127.0.0.1:3306/web3_plus?characterEncoding=UTF-8 </driver-url> <driver-class>com.mysql.jdbc.Driver</driver-class> <driver-properties> <property name="user" value="root"/> <property name="password" value="12344"/> </driver-properties> <!-- proxool自动侦察各个连接状态的时间间隔(毫秒), 侦察到空闲的连接就马上回收,超时的销毁 --> <house-keeping-sleep-time>120000</house-keeping-sleep-time> <!-- 指因未有空闲连接可以分配而在队列中等候的最大请求数, 超过这个请求数的用户连接就不会被接受 --> <maximum-new-connections>20</maximum-new-connections> <!-- 最少保持的空闲连接数 --> <prototype-count>5</prototype-count> <!-- 允许最大连接数,超过了这个连接,再有请求时,就排在队列中等候 ,最大的等待请求数由maximum-new-connections决定 --> <maximum-connection-count>300</maximum-connection-count> <!-- 最小连接数 --> <minimum-connection-count>10</minimum-connection-count> <!-- 同时最大连接数 --> <simultaneous-build-throttle>30</simultaneous-build-throttle> <!-- 一次产生连接的数量 --> <prototype-count>10</prototype-count> <!-- 连接最大时间活动 默认5分钟 --> <maximum-active-time>36000000</maximum-active-time> <!-- 连接最大生命时间 默认4小时 --> <maximum-connection-lifetime>43200000</maximum-connection-lifetime> </proxool> </something-else-entirely>以上就已经配置好了hibernate的基础环境。
4.创建Hibernate的SessionFactory,进行初始化Hibernate。
/* * 文 件 名 : com.qisentech.data.hibernate.HibernateSessionFactory.java * 创建日期 : 2013-08-25 0:24:58 * 创 建 者 : qsyang */ package com.qisentech.data.hibernate; import java.util.HashMap; import java.util.Map; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; /** * * @author qsyang */ public class HibernateSessionFactory { private static boolean inited = false; private static SessionFactory factory = null; private static Configuration cfg = null; /** * 初始化 */ public static synchronized void init() { if (!inited) { try { cfg = new Configuration(); cfg.configure("hibernate.cfg.xml"); factory = cfg.buildSessionFactory(); inited = true; } catch (Exception ex) { log.error("初始化hibernate出错", ex); throw new RuntimeException(ex); } } else { throw new java.lang.IllegalStateException( "HibernateSessionFactory already initialized"); } } public static Session openSession() { return factory.openSession(); } public static void destory() { factory.close(); } }好了,我们需要在系统运行之前,需要调用init方法来初始化HibernateSessionFactory。
当然也可以在测试的时候在创建,不过创建sessionFactory是很耗时的。
5.下面进行创建对象测试。
TFunction 与 TToolsBox(关系是一对多)
/* * 文 件 名 : com.qisentech.webplus.entity.TFunction.java * 创建日期 : 2013-8-23 15:40:01 * 创 建 者 : qsyang */ package com.qisentech.webplus.entity; import java.util.List; /** * <p>Title: </p> * * <p>Description: </p> * * @author qsyang * @version 1.0 */ public class TFunction { private int id; private String name; private String img; private int sort; private boolean isSystem; private List<TToolsBox> toolsBoxList; /** * @return the id */ public int getId() { return id; } /** * @param id the id to set */ public void setId(int id) { this.id = id; } /** * @return the name */ public String getName() { return name; } /** * @param name the name to set */ public void setName(String name) { this.name = name; } /** * @return the img */ public String getImg() { return img; } /** * @param img the img to set */ public void setImg(String img) { this.img = img; } /** * @return the sort */ public int getSort() { return sort; } /** * @param sort the sort to set */ public void setSort(int sort) { this.sort = sort; } /** * @return the isSystem */ public boolean isIsSystem() { return isSystem; } /** * @param isSystem the isSystem to set */ public void setIsSystem(boolean isSystem) { this.isSystem = isSystem; } /** * @return the toolsBoxList */ public List<TToolsBox> getToolsBoxList() { return toolsBoxList; } /** * @param toolsBoxList the toolsBoxList to set */ public void setToolsBoxList(List<TToolsBox> toolsBoxList) { this.toolsBoxList = toolsBoxList; } }
/* * 文 件 名 : com.qisentech.webplus.entity.TToolsBox.java * 创建日期 : 2013-7-30 16:53:25 * 创 建 者 : qsyang */ package com.qisentech.webplus.entity; /** * <p>Title: </p> * * <p>Description: </p> * * @author qsyang * @version 1.0 */ public class TToolsBox { private int id; private String name; private String implClass; private int functionId; private String img; private int sort; private String url; private boolean isValid; private String target; /** * @return the id */ public int getId() { return id; } /** * @param id the id to set */ public void setId(int id) { this.id = id; } /** * @return the name */ public String getName() { return name; } /** * @param name the name to set */ public void setName(String name) { this.name = name; } /** * @return the implClass */ public String getImplClass() { return implClass; } /** * @param implClass the implClass to set */ public void setImplClass(String implClass) { this.implClass = implClass; } /** * @return the img */ public String getImg() { return img; } /** * @param img the img to set */ public void setImg(String img) { this.img = img; } /** * @return the sort */ public int getSort() { return sort; } /** * @param sort the sort to set */ public void setSort(int sort) { this.sort = sort; } /** * @return the url */ public String getUrl() { return url; } /** * @param url the url to set */ public void setUrl(String url) { this.url = url; } /** * @return the target */ public String getTarget() { return target; } /** * @param target the target to set */ public void setTarget(String target) { this.target = target; } /** * @return the isValid */ public boolean isIsValid() { return isValid; } /** * @param isValid the isValid to set */ public void setIsValid(boolean isValid) { this.isValid = isValid; } /** * @return the functionId */ public int getFunctionId() { return functionId; } /** * @param functionId the functionId to set */ public void setFunctionId(int functionId) { this.functionId = functionId; } }好了,对象创建好了之后,需要创建对应的实体配置映射文件,主要是映射对象属性和数据库表字段的关系。
T.Function.hbm.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.qisentech.webplus.entity"> <class name="TFunction" table="t_function"> <id column="Id" name="id"> <generator class="native"/> </id> <property column="Name" name="name"/> <property column="Img" name="img"/> <property column="Sort" name="sort"/> <property column="IsSystem" name="isSystem"/> <bag cascade="all" inverse="false" lazy="true" name="toolsBoxList" table="t_toolsbox"> <key column="FunctionId"/> <one-to-many class="TToolsBox"/> </bag> </class> </hibernate-mapping>T.TToolsBox.hbm.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.qisentech.webplus.entity"> <class name="TToolsBox" table="t_toolsbox"> <id column="Id" name="id"> <generator class="native"/> </id> <property column="Name" name="name"/> <property column="ImplClass" name="implClass"/> <property column="Url" name="url"/> <property column="Img" name="img"/> <property column="Sort" name="sort"/> <property column="IsValid" name="isValid"/> <property column="Target" name="target"/> <property column="FunctionId" name="functionId"/> </class> </hibernate-mapping>好了,配置文件也写好了,需要将配置文件添加到hibernate.cfg.xml中映射进来。
<mapping resource="com/qisentech/webplus/entity/T.Function.hbm.xml"/> <mapping resource="com/qisentech/webplus/entity/T.TToolsBox.hbm.xml"/>6.开始做获取第一个对象测试
数据库t_function表数据如下:
1 | 系统管理 | box_title_xtgl.gif | 10 | 1 |
2 | 基础功能 | box_title_jlgl.gif | 20 | 1 |
3 | 相关组件 | box_title_xgzj.gif | 30 | 1 |
数据库t_toolsbox表数据如下:
1 | 个人信息 | NULL | box_xgmm.gif | 50 | main.jsp | 1 | _self | 1 |
2 | 人员管理 | NULL | box_idsgl.gif | 50 | index.jsp | 1 | _self | 2 |
3 | 院系管理 | NULL | box_yxsz.gif | 50 | test.jsp | 1 | _blank | 3 |
Session的get方法测试:
Session session = null; try { session = HibernateSessionFactory.openSession(); Object obj = session.get(TFunction.class, id); return obj == null ? null : (TFunction) obj; } catch (HibernateException ex) { throw ex; }finally{ session.close(); }Session的load方法测试:
Session session = null; try { session = HibernateSessionFactory.openSession(); Object obj = session.load(TFunction.class, id); return (TFunction) obj; } catch (HibernateException ex) { throw ex; }finally{ session.close(); }小插曲:Hibernate get和load区别?
1.从返回结果上对比:
load方式检索不到的话会抛出org.hibernate.ObjectNotFoundException异常
get方法检索不到的话会返回null
2.从检索执行机制上对比:
get方法和find方法都是直接从数据库中检索 而load方法的执行则比较复杂首先查找session的persistent Context中是否有缓存,如果有则直接返回 如果没有则判断是否是lazy,如果不是直接访问数据库检索,查到记录返回,查不到抛出异常 如果是lazy则需要建立代理对象,对象的initialized属性为false,target属性为null 在访问获得的代理对象的属性时,检索数据库,如果找到记录则把该记录的对象复制到代理对象的target上,并将initialized=true,如果找不到就抛出异常。
简单总结
总之对于get和load的根本区别,一句话,hibernate对于load方法认为该数据在数据库中一定存在,可以放心的使用代理来延迟加载,如果在使用过程中发现了问题,只能抛异常;而对于get方法,hibernate一定要获取到真实的数据,否则返回null。
关于Hibernate,还有很多需要探索,我会继续跟帖说明,大家一起学习吧!