Hibernate开发指南
| ||
前言Hibernate做为一个非常优秀且已经被大量使用的数据库持久层工具已经越来越成熟了。 本文主要是针对使用Hibernate的开发者,本章节主要是说明在《Hibernate开发指南》中所使用到的开发环境的初步设置, 并使用一个简单的例子以说明Hibernate已经正常运行。 本文所主要使用的工具有:
软件配置我们先来配置数据库,同时记下数据库开发时所需要的相关信息。 Oracle相关配置参数我在Oracle中建立了一个单独的用户:HD,设置其密码为:abc。为该用户分配好相应的数据库空间, 细致的配置方法和信息不再多说,总之你需要得到类似下面的信息以备开发时所使用:
ojdbc14.jar ,JDK1.4使用的多语言支持包与JDK1.2相同都是 nls_charset12.jar 。
在数据库中我们建立一些表以用于程序开发,以一个简单的用户管理为例我们先建立一个简单的用户表(sysuser):
CREATE TABLE "HD"."SYSUSER" ("USERID" VARCHAR2(32) NOT NULL,
"USERNAME" VARCHAR2(20) NOT NULL, "USERPASWORD" VARCHAR2(20)
NOT NULL, "LASTLOGIN" DATE, PRIMARY KEY("USERID"),
UNIQUE("USERNAME"))
TABLESPACE "USERS"
Tomcat安装Tomcat的安装则非常简单了,从Tomcat网站上下载相关的安装包,解到相关的目录就可以了。安装Tomcat之后你需要记下以下信息:
配置Hibernate for Eclipse的插件Tanghan Plugin初次使用这个插件时会有许多人无从下手,主要是不知从哪里使用这个插件。 首先要打开这个插件提供的两个视图:
打开Database Access View视图,我们来配置Oracle的驱动,用鼠标右键点Oracle Thin Driver > 修改驱动程序信息:
这里:
这里:
需要我们再选择Shemas,从下拉列表中选择 配置MyEclipse从 MyEclipse的网站 上下载到最新的MyEclipse的试用版以及Struts相关的TLD和Lib包。 安装完MyEclipse后,配置Tomcat的使用。主要是配置清楚tomcat的相关路径就可以了:
需要注意的是tomcat一定要使用一个JDK,而不是JRE,在tomcat的配置树中可以选择一个JDK以供Tomcat启动使用:
接下来将从网站上下载的Struts包解开到文件系统中(也可以手工将Struts 1.1包中的lib和tld拆出),在MyEclipse中配置好Struts 1.1的相关包:
这些配置完成我们就可以建立一个简单的项目了。 建立初始的Struts项目我们先建立一个项目,为后续的深入开发做准备,这个项目是一个简单的框架,导入Tomcat部署支持、建立与Struts和Hibernate的库路径。 为Web应用加入Struts支持再为项目加入Struts支持:
在弹出的对话框中按下图输入信息:
这样就为Web应用项目加入了Struts支持,这一步会自动为项目加入Struts的支持包和Struts需要使用的TLD文件(Tag Lib说明文件)。之后我们可以看到: 为Web应用加入Hibernate支持Hibernate中有大量的jar,不建议大家全部加入,以下是你必须加入的jar包(这些包除hibernate2.jar在根下其它都在lib子目录中):
下图是配置到最后所有的包的列表,也请大家一一核对: 配置Hibernate的配置文件配置Hibernate数据库连接配置数据库的连接配置很简单,在项目的 src目录 下建立一个xml文件,名为 hibernate.cfg.xml 。这个文件的内容为: <?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN" "http://hibernate.sourceforge.net/hibernate-configuration-2.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="dialect">net.sf.hibernate.dialect.Oracle9Dialect</property>
<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="connection.username">hd</property>
<property name="connection.password">abc</property>
<property name="connection.url">jdbc:oracle:thin:@localhost:1521:hdorc</property>
<property name="connection.pool.size">1</property>
<property name="statement_cache.size">25</property>
<property name="jdbc.fetch_size">50</property>
<property name="jdbc.batch_size">30</property>
<property name="show_sql">true</property>
<!-- Mapping files -->
<mapping resource="com/huangdong/demo/dao/SysUser.hbm.xml"/>
</session-factory>
</hibernate-configuration>
我们对这里的各个property元素一一说明:
配置Hibernate表映射在Database Access View中选择SYSUSER表,在菜单中选择生成HBM文件:
在向导对话框中按下图输入相关信息:
按完成按钮后,就会在com.huangdong.demo.dao包中生成SysUser类和SysUser.hb.xml文件。 由于在Java中使用java.util.Date有很多不方便的地方,所以我将lastlogin的映射后的java属性改为了calendar。 这是修改后的SysUser.hbm.xml文件: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd"> <hibernate-mapping> <class name="com.huangdong.demo.dao.SysUser" table="SYSUSER"> <id column="userid" length="32" name="userid" type="string"> <generator class="uuid.hex"/> </id> <property column="username" length="20" name="username" not-null="true" type="string" unique="true"/> <property column="userpasword" length="20" name="userpasword" not-null="true" type="string"/> <property column="lastlogin" length="7" name="lastlogin" type="calendar"/> </class> </hibernate-mapping> 这是修改后的SysUser.java文件: package com.huangdong.demo.dao;
import java.io.Serializable;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
/** @author Hibernate CodeGenerator */
public class SysUser implements Serializable {
/** identifier field */
private String userid;
/** persistent field */
private String username;
/** persistent field */
private String userpasword;
/** nullable persistent field */
private java.util.Calendar lastlogin;
/** full constructor */
public SysUser(java.lang.String username, java.lang.String userpasword, java.util.Calendar lastlogin) {
this.username = username;
this.userpasword = userpasword;
this.lastlogin = lastlogin;
}
/** default constructor */
public SysUser() {
}
/** minimal constructor */
public SysUser(java.lang.String username, java.lang.String userpasword) {
this.username = username;
this.userpasword = userpasword;
}
public java.lang.String getUserid() {
return this.userid;
}
public void setUserid(java.lang.String userid) {
this.userid = userid;
}
public java.lang.String getUsername() {
return this.username;
}
public void setUsername(java.lang.String username) {
this.username = username;
}
public java.lang.String getUserpasword() {
return this.userpasword;
}
public void setUserpasword(java.lang.String userpasword) {
this.userpasword = userpasword;
}
public java.util.Calendar getLastlogin() {
return this.lastlogin;
}
public void setLastlogin(java.util.Calendar lastlogin) {
this.lastlogin = lastlogin;
}
public String toString() {
return new ToStringBuilder(this)
.append("userid", getUserid())
.toString();
}
public boolean equals(Object other) {
if ( !(other instanceof SysUser) ) return false;
SysUser castOther = (SysUser) other;
return new EqualsBuilder()
.append(this.getUserid(), castOther.getUserid())
.isEquals();
}
public int hashCode() {
return new HashCodeBuilder()
.append(getUserid())
.toHashCode();
}
}
建立测试用的Servlet创建Servlet框架使用新建Servlet的向导我们来建立一个测试用的Servlet,下图是新建Servlet时输入的参数和选项:
在下一步的XML Wizard对话框中记得将 Display Name 和 Description 的“Test System Function Servlet”都清除,如下图所示:
这样就建立了一个初始的Servlet框架。 编写数据库连接获取类我们编写一个单独的类,用于从SessionFactory中获取数据库连接session。这个类名为HibernateUtil,我们将其放于com.huangdong.demo.util包中,具体的代码如下: package com.huangdong.demo.util;
import net.sf.hibernate.HibernateException;
import net.sf.hibernate.Session;
import net.sf.hibernate.SessionFactory;
import net.sf.hibernate.cfg.Configuration;
public class HibernateUtil {
private static final SessionFactory sessionFactory;
static {
try {
sessionFactory =
new Configuration().configure().buildSessionFactory();
} catch (HibernateException ex) {
throw new RuntimeException(
"Exception building SessionFactory: " + ex.getMessage(),
ex);
}
}
public static final ThreadLocal session = new ThreadLocal();
public static Session currentSession() throws HibernateException {
Session s = (Session) session.get();
// Open a new Session, if this Thread has none yet
if (s == null) {
s = sessionFactory.openSession();
session.set(s);
}
return s;
}
public static void closeSession() throws HibernateException {
Session s = (Session) session.get();
session.set(null);
if (s != null)
s.close();
}
}
我们可以通过currentSession方法来获取数据库连接,如果系统中有可用的session就会反回可用的,如果没有时才会创建一个新的session。当session操作完成后,需要操作者使用closeSession方法释放使用的session。 建立测试Bean接下来我们建立一个TestHibernate的Java Bean,主要加入一些Hibernate的测试方法,以下是建立该类所输入的相关信息:
我们为该类加入一个向数据库中增加数据的方法: public boolean TestAdd() {
try {
Session session = HibernateUtil.currentSession();
Transaction tx = session.beginTransaction();
SysUser user = new SysUser();
user.setUsername("丫丫");
user.setUserpasword("uhkuhkqepdwqi");
user.setLastlogin(Calendar.getInstance());
session.save(user);
tx.commit();
HibernateUtil.closeSession();
} catch (HibernateException e) {
e.printStackTrace();
return false;
}
return true;
}
第一次我写这个代码时感到非常的意外,总感觉应该再多写点什么,但是真的是这 样,我们只用了这么几句话就向数据库加入了一条记录。 在Servlet中调用TestAdd方法这就很简单了,更改TestServlet.java类的doGet方法,初始化TestHibernate类,并调用TestAdd方法就可以了: public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html; charset=GBK");
PrintWriter out = response.getWriter();
out.println(
"<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">");
out.println("<HTML>");
out.println(" <HEAD><TITLE>A Servlet</TITLE></HEAD>");
out.println(" <BODY>");
//调用Test Add
TestHibernate test = new TestHibernate();
out.println("TestAdd:" + test.TestAdd() + "<p>");
out.println(" </BODY>");
out.println("</HTML>");
out.flush();
out.close();
}
如果TestAdd方法执行成功则会在页面上返回True,否则会返回False。下面我们就来测试一把。 测试我们第一个基于Servlet的Hibernate应用启动Tomcat如果之前按本文配置好了Tomcat的部署,哪么这里就不会有任何问题,如图操作则会进入Eclipse的调试视图:
在Debug视图中看到所有的线程启动,并在控制台窗口中看到“Starting Coyote HTTP/1.1 on port 8080”则说明Tomcat启动成功并侦听了8080端口,如下图:
打开浏览器,在地址栏中输入: http://localhost:8080/Demo/servlet/TestServlet 如果返回的页面如下图所示,则代表数据库更新成功:
同时在Eclipse的控制台中我们可以看到Hibernate的log输出,说明了它工作的细节情况 : 2003-12-26 15:10:37 net.sf.hibernate.cfg.Environment <clinit>
信息: Hibernate 2.1.1
2003-12-26 15:10:37 net.sf.hibernate.cfg.Environment <clinit>
信息: hibernate.properties not found
2003-12-26 15:10:37 net.sf.hibernate.cfg.Environment <clinit>
信息: using CGLIB reflection optimizer
2003-12-26 15:10:37 net.sf.hibernate.cfg.Configuration configure
信息: configuring from resource: /hibernate.cfg.xml
2003-12-26 15:10:37 net.sf.hibernate.cfg.Configuration getConfigurationInputStream
信息: Configuration resource: /hibernate.cfg.xml
2003-12-26 15:10:38 net.sf.hibernate.cfg.Configuration addResource
信息: Mapping resource: com/huangdong/demo/dao/SysUser.hbm.xml
2003-12-26 15:10:38 net.sf.hibernate.cfg.Binder bindRootClass
信息: Mapping class: com.huangdong.demo.dao.SysUser -> SYSUSER
2003-12-26 15:10:39 net.sf.hibernate.cfg.Configuration doConfigure
信息: Configured SessionFactory: null
2003-12-26 15:10:39 net.sf.hibernate.cfg.Configuration secondPassCompile
信息: processing one-to-many association mappings
2003-12-26 15:10:39 net.sf.hibernate.cfg.Configuration secondPassCompile
信息: processing one-to-one association property references
2003-12-26 15:10:39 net.sf.hibernate.cfg.Configuration secondPassCompile
信息: processing foreign key constraints
2003-12-26 15:10:39 net.sf.hibernate.dialect.Dialect <init>
信息: Using dialect: net.sf.hibernate.dialect.Oracle9Dialect
2003-12-26 15:10:39 net.sf.hibernate.cfg.SettingsFactory buildSettings
信息: JDBC result set fetch size: 50
2003-12-26 15:10:39 net.sf.hibernate.cfg.SettingsFactory buildSettings
信息: Use outer join fetching: true
2003-12-26 15:10:39 net.sf.hibernate.connection.DriverManagerConnectionProvider configure
信息: Using Hibernate built-in connection pool (not for production use!)
2003-12-26 15:10:39 net.sf.hibernate.connection.DriverManagerConnectionProvider configure
信息: Hibernate connection pool size: 20
2003-12-26 15:10:39 net.sf.hibernate.connection.DriverManagerConnectionProvider configure
信息: using driver: oracle.jdbc.driver.OracleDriver at URL: jdbc:oracle:thin:@localhost:1521:hdorc
2003-12-26 15:10:39 net.sf.hibernate.connection.DriverManagerConnectionProvider configure
信息: connection properties: {user=hd, password=abc, pool.size=1}
2003-12-26 15:10:39 net.sf.hibernate.transaction.TransactionManagerLookupFactory getTransactionManagerLookup
信息: No TransactionManagerLookup configured (in JTA environment, use of process level read-write cache is not recommended)
2003-12-26 15:10:45 net.sf.hibernate.cfg.SettingsFactory buildSettings
信息: Use scrollable result sets: true
2003-12-26 15:10:45 net.sf.hibernate.cfg.SettingsFactory buildSettings
信息: JDBC 2 max batch size: 30
2003-12-26 15:10:45 net.sf.hibernate.cfg.SettingsFactory buildSettings
信息: echoing all SQL to stdout
2003-12-26 15:10:45 net.sf.hibernate.cfg.SettingsFactory buildSettings
信息: Query language substitutions: {}
2003-12-26 15:10:45 net.sf.hibernate.cfg.SettingsFactory buildSettings
信息: cache provider: net.sf.ehcache.hibernate.Provider
2003-12-26 15:10:45 net.sf.hibernate.cfg.Configuration configureCaches
信息: instantiating and configuring caches
2003-12-26 15:10:46 net.sf.hibernate.impl.SessionFactoryImpl <init>
信息: building session factory
2003-12-26 15:10:47 net.sf.hibernate.impl.SessionFactoryObjectFactory addInstance
信息: no JNDI name configured
Hibernate: insert into SYSUSER (username, userpasword, lastlogin, userid) values (?, ?, ?, ?)
在最后我们可以看到Hibernate生成的数据库操作语句。走到这里可以说你已经成功的运行了许多东西。让我们再列出来,请你一一考虑一下它们是如何被你运行和部署起来的,它们有什么:
留在最后的话本文只是简单的给大家介绍了开发基于Java的Web应用的基础环境,同时介绍了一系列的开发工具和组件。 这些工具还有更多的功能,这里就不再一一介绍了,请大家多参考Eclipse、MyEclipse的说明文档,它们还有许多丰富的功能。 对于Struts和Hibernate这两个强大的组件最在后续的文章中再慢慢说明。 如果你对本文有什么意见和建议请 联系我 ,告诉我你的想法,另外也可以到 技术天空BBS的Java版 中讨论与Java相关的各种技术。 你可以从 这里 下载到完整的Eclipse Project包。 另外本文中的所有代码在以下环境中由作者实际测试完全没有问题:
|
浙公网安备 33010602011771号