先说下实验项目环境:
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,还有很多需要探索,我会继续跟帖说明,大家一起学习吧!