您的位置:首页 > 其它

调通了第一个Hibernate程序

2005-02-19 00:54 573 查看
几天没学习了,终于今天下午有空。早想看看Hibernate,于是开始写Hibernate的第一个在Tomcat下运行的代码,使用数据库是Mysql,没有使用servlet,直接用Jsp。发现没经历过servlet编程,还就是不习惯,用jsp比servlet方便,虽然代码不好调试,但修改代码后不用reload应用,配置文件也不用写。
回到正题,其实下午就是一步一步按照Hibernate自带的手册来做的,不错,居然有中文版,对hibernate推广很有好处。
-----------------
1。照例是使用Eclipse,建立一个新的工程,我取名叫hibstart(因为最入门框架等比较多,quickstart不好区分)。
2。建立目录结构,WEB-INF,WEB-INF/bin,WEB-INF/classes,src等等,设好output路径。然后吧Hibernate必须用到的7个jar包拷到WEB-INF/bin里(dom4j, CGLIB, Commons Collections, Commons Logging, ODMG4, EHCache, Log4j,hibernate2,我还多拷了一个log4j过去。开始漏拷了一个,出现问题了,郁闷了我半天),将JDBC驱动拷到%Tomcat%/common/lib里去。
3。因为使用的是Tomcat的连接池,所以修改Tomcat/conf/sever.xml
<Resource name="jdbc/hibstart" scope="Shareable" type="javax.sql.DataSource"/>
<ResourceParams name="jdbc/hibstart">
<parameter>
<name>factory</name>
<value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
</parameter>
<parameter>
<name>maxWait</name>
<value>5000</value>
</parameter>
<parameter>
<name>maxActive</name>
<value>4</value>
</parameter>
<parameter>
<name>password</name>
<value>mypassword</value>
</parameter>
<parameter>
<name>url</name>
<value>jdbc:mysql://localhost:3306/hibernate</value>
</parameter>
<parameter>
<name>driverClassName</name>
<value>com.mysql.jdbc.Driver</value>
</parameter>
<parameter>
<name>maxIdle</name>
<value>2</value>
</parameter>
<parameter>
<name>username</name>
<value>myusername</value>
</parameter>
</ResourceParams>
关于这个的配置,实际可以通过Tomcat的管理来完成http://localhost:8080/admin/,但是好像没有定义factory那项,不知道有没有用到。JNDI就是java:comp/env/jdbc/hibstart。要测试这个连接池有没有问题,可以查考Tomcat的文档,有个测试连Mysql的连接池的例子。
4。写hibernate.cfg.xml,放到src目录下面,配置hibernate的文件
<?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="connection.datasource">java:comp/env/jdbc/hibstart</property>
<property name="show_sql">true</property>
<!-- 定义方言,可以打开net.sf.hibernate.Dialect包看看方言种类 -->
<property name="dialect">net.sf.hibernate.dialect.MySQLDialect</property>
<!-- Mapping files -->
<mapping resource="Cat.hbm.xml"/>
</session-factory>
</hibernate-configuration>
这里定义了使用的数据源,是否显示sql语句信息,方言,还有数据库映射文件。
5。定义POJO
package com.maxway.web.model;
public class Cat {
private String id;
private String name;
private char sex;
private float weight;
public Cat() {
}
public String getId() {
return id;
}
private void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public float getWeight() {
return weight;
}
public void setWeight(float weight) {
this.weight = weight;
}
}
都是只要定义好变量,就可以用Eclipse自动生成get/set方法。
6。写Cat.hbm.xml,(也放在src下,Eclipse会自动编译到WEB-INF/classes下面去)就是Cat这个POJO到数据库的映射
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<class name="com.maxway.web.model.Cat" table="CAT">
<!-- A 32 hex character is our surrogate key. It's automatically
generated by Hibernate with the UUID pattern. -->
<id name="id" type="string" unsaved-value="null" >
<column name="CAT_ID" sql-type="char(32)" not-null="true"/>
<generator class="uuid.hex"/>
</id>
<!-- A cat has to have a name, but it shouldn' be too long. -->
<property name="name">
<column name="NAME" length="16" not-null="true"/>
</property>
<property name="sex"/>
<property name="weight"/>
</class>
</hibernate-mapping>
关于generator我觉得用数据库提供的int型自增就不错,没必要用hibernate提供的,这里用的是UUID生成器。
Column |         Type          | Modifiers
--------+-----------------------+-----------
cat_id | varchar(32)           | not null
name   | varchar(32)           | not null
sex    | char(1)               |
weight | float                 |
cat_id primary key
老老实实用Mysql工具自己建的表
7。Hibernate主要就是以session接口来操纵数据库,session通过sessionFactory.openSession()创建,sessionFactory通过SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();获得,SessionFactory通常只是被初始化一次,于是创建了一个辅助类
/*
* Created on 2005-2-18
*
* 这个类不但在它的静态属性中使用了SessionFactory,
* 还使用了ThreadLocal来为当前工作线程保存Session。
*/
package com.maxway.web.util;
import net.sf.hibernate.HibernateException;
import net.sf.hibernate.Session;
import net.sf.hibernate.SessionFactory;
import net.sf.hibernate.cfg.Configuration;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* Hibernate 获取基本Session(Hibernate的工作单元)。
*
* <pre>
* SessionFactory sessionFactory = new Configuration().configure()
*   .buildSessionFactory();
* </pre>
*
* <p>
* SessionFactory负责一个数据库,也只对应一个XML配置文件(hibernate.cfg.xml)。 通过在创建
* SessionFactory之前(它是不可变的),你可以访问Configuration来设置其他属性(甚至修改映射的元数据)。 <br>
* 我们应该在哪儿创建SessionFactory,在我们的程序中又如何访问它呢? <br>
* SessionFactory通常只是被初始化一次,比如通过一个load-on-startup servlet。 <br>
* 这意味着你不应该在serlvet中把它作为一个实例变量来持有,应该放在其他地方。 <br>
* 更深入一些的说,我们需要某种单例(Singleton)模式,我们才能更容易的在程序中访问SessionFactory。 <br>
* 本类同时解决了两个问题:配置和容易地访问SessionFactory。 <br>
* </p>
*
* @author meijun
* @author hibernate.org
*/
public class HibernateUtil {
private static Log log = LogFactory.getLog(HibernateUtil.class);
private static final SessionFactory sessionFactory;
static {
try {
// Create the SessionFactory
sessionFactory = new Configuration().configure()
.buildSessionFactory();
} catch (Throwable ex) {
log.error("Initial SessionFactory creation failed.", ex);
throw new ExceptionInInitializerError(ex);
}
}
// 本地线程
public static final ThreadLocal session = new ThreadLocal();
/**
* 从本地线程获取Session,没有则创建一个,多次调用本方法获取的是同一个session
*
* @return Session
* @throws HibernateException
*/
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;
}
/**
* 关闭session
*
* @throws HibernateException
*/
public static void closeSession() throws HibernateException {
Session s = (Session) session.get();
// 删除本地线程中的session对象
session.set(null);
// 关闭实际的Session
if (s != null)
s.close();
}
}
在web.xml中配置,让这个类随着Tomcat启动
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/j2ee/dtds/web-app_2_3.dtd">
<web-app>

<servlet>
<servlet-name>HibernateUtil</servlet-name>
<servlet-class>com.maxway.web.util.HibernateUtil</servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>
</web-app>
8。现在所有的准备配置都已经完成,开始写一个jsp文件来测试一下,下面的test.jsp实现了一个非常简单的功能,先插入一条Cat数据到库中,然后显示库中所有cat数据,所以每刷新一次就会多一条记录。
<%@ page contentType="text/html; charset=gb2312" %>
<%@ page import="com.maxway.web.util.*"%>
<%@ page import="com.maxway.web.model.Cat"%>
<%@ page import="net.sf.hibernate.*" %>
<%@ page import="java.util.Iterator"%>
<%
Session sessions = HibernateUtil.currentSession();

Transaction tx= sessions.beginTransaction();

Cat princess = new Cat();
princess.setName("Princess");
princess.setSex('F');
princess.setWeight(7.4f);

sessions.save(princess);
tx.commit();
%>
<htm>
<head>
<title>测试Hibernate</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>
<body>
<center>
<br>
<br>
<br>
<table>
<%
tx= sessions.beginTransaction();
Query query = sessions.createQuery("select c from Cat as c where c.sex = :sex");
query.setCharacter("sex", 'F');
for (Iterator it = query.iterate(); it.hasNext();) {
Cat cat = (Cat) it.next();
out.println("<tr><td>Female Cat:</td><td>" + cat.getName() +"</td></tr>");
}
tx.commit();
HibernateUtil.closeSession();
%>
</table>
</center>
</body>
</html>
最后我使用了log4j,所以还要写一个log4j.properties放在src下,eclipse自动复制到classes里去。
开Tomcat,应该有一大堆信息,但是没有Error,如果有Error,还是检查一下jar包是不是全了,配置问题等。
访问test.jsp……OK
--------------
保存的时候一条SQL语句都没写,只是在查询的时候用了Hibernate的HQL,Hibernate支持多种查询方法。
PS:本文完全参考Hibernate手册,只不过是写了一个JSP文件和相关配置文件,使手册中的例子能运行起来。写这个文章的目的是为了加深自己对Hibernate使用流程的印象。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: