Hibernate做为一个非常优秀且已经被大量使用的数据库持久层工具已经越来越成熟了。 本文主要是针对使用Hibernate的开发者,本章节主要是说明在《Hibernate开发指南》中所使用到的开发环境的初步设置, 并使用一个简单的例子以说明Hibernate已经正常运行。
本文所主要使用的工具有:
我们先来配置数据库,同时记下数据库开发时所需要的相关信息。
我在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之后你需要记下以下信息:
初次使用这个插件时会有许多人无从下手,主要是不知从哪里使用这个插件。 首先要打开这个插件提供的两个视图:Database Access View
和Database Data View
。 通过菜单上的窗口>显示视图>其它来选择这两个视图:
打开Database Access View视图,我们来配置Oracle的驱动,用鼠标右键点Oracle Thin Driver>修改驱动程序信息:
这里:
这里:
需要我们再选择Shemas,从下拉列表中选择HD
,按确定
按钮。 如果能看到选择Shemas对话框,哪么说明你的数据库配置就没有什么问题了。 我们可以在Database Access View中看到库中的表及表结构:
我们先建立一个项目,为后续的深入开发做准备,这个项目是一个简单的框架,导入Tomcat部署支持、建立与Struts和Hibernate的库路径。
再为项目加入Struts支持:
在弹出的对话框中按下图输入信息:
这样就为Web应用项目加入了Struts支持,这一步会自动为项目加入Struts的支持包和Struts需要使用的TLD文件(Tag Lib说明文件)。之后我们可以看到:
Hibernate中有大量的jar,不建议大家全部加入,以下是你必须加入的jar包(这些包除hibernate2.jar在根下其它都在lib子目录中):
将之前准备好的Oracle驱动包也加入到Web项目中。主要是这两个文件:
下图是配置到最后所有的包的列表,也请大家一一核对:
数据库的连接配置很简单,在项目的src目录下建立一个xml文件,名为hibernate.cfg.xml。这个文件的内容为:
net.sf.hibernate.dialect.Oracle9Dialect oracle.jdbc.driver.OracleDriver hd abc jdbc:oracle:thin:@localhost:1521:hdorc 1 25 50 30 true
我们对这里的各个property元素一一说明:
在Database Access View中选择SYSUSER表,在菜单中选择生成HBM文件:
在向导对话框中按下图输入相关信息:
按完成按钮后,就会在com.huangdong.demo.dao包中生成SysUser类和SysUser.hb.xml文件。
由于在Java中使用java.util.Date有很多不方便的地方,所以我将lastlogin的映射后的java属性改为了calendar。
这是修改后的SysUser.hbm.xml文件:
这是修改后的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时输入的参数和选项:
在下一步的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。
接下来我们建立一个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; }
第一次我写这个代码时感到非常的意外,总感觉应该再多写点什么,但是真的是这样,我们只用了这么几句话就向数据库加入了一条记录。
这就很简单了,更改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( ""); out.println(""); out.println("A Servlet "); out.println(" "); //调用Test Add TestHibernate test = new TestHibernate(); out.println("TestAdd:" + test.TestAdd() + ""); out.println(" "); out.println(""); out.flush(); out.close(); }
如果TestAdd方法执行成功则会在页面上返回True,否则会返回False。下面我们就来测试一把。
如果之前按本文配置好了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信息: Hibernate 2.1.1 2003-12-26 15:10:37 net.sf.hibernate.cfg.Environment 信息: hibernate.properties not found 2003-12-26 15:10:37 net.sf.hibernate.cfg.Environment 信息: 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 信息: 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 信息: 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包。
另外本文中的所有代码在以下环境中由作者实际测试完全没有问题: