调通了第一个Hibernate程序

来源:互联网 发布:淘宝延长收货再退款 编辑:程序博客网 时间:2024/05/21 13:29
几天没学习了,终于今天下午有空。早想看看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使用流程的印象。

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=293283

 
原创粉丝点击