论坛首页 Java企业应用论坛

Hibernate学习笔记(一)

浏览 5578 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2004-07-06  
开始学习Hibernate,通过Hibernate本身的文档似乎比较难入门,昨天试了半天也没成功。在论坛里找了一些网友的入门级例子,可似乎都写得有点丢三落四,也是,细节谁能写得那么清楚,只有自己调试中遇到问题才能慢慢体会。后来总算找到一个还算完整的例子,是Tomcat下Servlet的,运行成功。有了一块敲门砖,入门突然变得容易多了。很幸运,一天就入了门。

    今早起来继续调试昨天看起来还有些不完整的例子,在回帖中找是否别人也遇到过类似的问题,零零散散加起来,终于又成功了!此后势如破竹,连着调成功了好几个例子,很是开心!

    既然是笔记,当然要有些实质性内容啦!下面就开始:

    数据库是MYSQL,使用EMS MANAGER做客户端,很是方便。数据库驱动是很久之前搞定的,有点忘了,但是MYSQL的文档里还是写得比较清楚的,应该稍微看下就会了。

    例子都是用Jbuilder+hibernate做的,用Jbuilder新建工程,随便叫个名字。写一个Cat持久化类:

package test;
    
    public class Cat {

  private String id;
  private String name;
  private char sex;
  private float weight;

  public Cat(); {
  }

  public String getId(); {
    return id;
  }

  public 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;
  }
}

然后在test包里new一个映射文件Cat.hbm.xml:

<?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="test.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="varchar(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" sql-type="varchar(16);" not-null="true"/>
        </property>

        <property name="sex"/>

        <property name="weight"/>

    </class>

</hibernate-mapping>

呵呵,从映射文件里已经可以看出怎么建数据库中的表了:

create database,假设名为quickstart,
create table, 名为Cat,几个字段如下:

Column |         Type          | Modifiers
--------+-----------------------+-----------
 cat_id | varchar(32);         | not null
 name   | varchar varying(16); | not null
 sex    | char(1);          |
 weight | float                  |
Indexes: cat_pkey primary key btree (cat_id);

回到Jbuilder

写一个HibernateUtil类来帮助管理Session:

package test;

import net.sf.hibernate.*;
import net.sf.hibernate.cfg.*;
class HibernateUtil {

  private static final SessionFactory sessionFactory;

  static {
    try {
      Configuration conf= new Configuration();.addClass(Cat.class);;

    sessionFactory = conf.buildSessionFactory();;

      //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();;
    }
  }

然后在Cat类中直接写一个Main方法来进行测试,当然也可以单独写一个测试类:

public static void main(String[] args); {
    Session session = null;
    try {
      session = HibernateUtil.currentSession();;
    }
    catch (HibernateException ex); {
    }

    Transaction tx = null;
    try {
      tx = session.beginTransaction();;
    }
    catch (HibernateException ex1); {
    }

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

    try {
      session.save(princess);;

      tx.commit();;

      HibernateUtil.closeSession();;
    }
    catch (HibernateException ex2); {
    }

  }

好了!把上面三段代码合并都写在Cat.java里,如下:

package test;

import net.sf.hibernate.*;
import net.sf.hibernate.cfg.*;

//import HibernateUtil.*;

public class Cat {

  private String id;
  private String name;
  private char sex;
  private float weight;

  public Cat(); {
  }

  public String getId(); {
    return id;
  }

  public 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;
  }

  public static void main(String[] args); {
    Session session = null;
    try {
      session = HibernateUtil.currentSession();;
    }
    catch (HibernateException ex); {
    }

    Transaction tx = null;
    try {
      tx = session.beginTransaction();;
    }
    catch (HibernateException ex1); {
    }

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

    try {
      session.save(princess);;

      tx.commit();;

      HibernateUtil.closeSession();;
    }
    catch (HibernateException ex2); {
    }

  }

}

class HibernateUtil {

  private static final SessionFactory sessionFactory;

  static {
    try {
      Configuration conf= new Configuration();.addClass(Cat.class);;

    //在表中插入第一条数据

    sessionFactory = conf.buildSessionFactory();;

      //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();;
    }
  }
}


后面要做的是把Hibernate.properties考到Jbuilder编译的class目录下,注意不要放在test包里,需要修改一下缺省的Hibernate.properties,对Mysql进行配置:

将缺省的HypersonicSQL全部注释掉(前面加"#"号),将Mysql的配置全部打开,如下:

## MySQL

hibernate.dialect net.sf.hibernate.dialect.MySQLDialect
hibernate.connection.driver_class org.gjt.mm.mysql.Driver
hibernate.connection.driver_class com.mysql.jdbc.Driver
hibernate.connection.url jdbc:mysql:///quickstart
hibernate.connection.username javauser
hibernate.connection.password javadude

头三行不用动,后三行跟着数据库走,前面建的库叫quickstart,所以当然url就是jdbc:mysql:///quickstart了,用户名和密码就是你mysql的设置。

好了!大功告成!编译test包,运行!

呵呵,当然不会那么顺利啦!首先会报找不到log4j的错误:

log4j:WARN No appenders could be found for logger (net.sf.hibernate.cfg.Environment).

log4j:WARN Please initialize the log4j system properly.

解决这个问题的办法就是把Hibernate下的log4j.properties文件也考到class目录下。

再编译运行,哦!找不到影射文件Cat.hbm.xml。可名名刚才建了啊!呵呵,原来影射文件要跟编译后的持久化类Cat.class放在一起,而新建的时候只是放在src目录下,考过去就ok。可这样也太麻烦了,以后得次次考。下面有个省事的:
在Jbuilder中Project->project properties->resource 选中xml文件,选中copy->ok
再编译test包,Cat.hbm.xml自动就去class/test目录下了!

再运行,哦!又找不到Mysql的驱动, com.mysql.jdbc.Driver,这个需要Project->project properties->Path,在Required Libraries中把 你的路径/com/mysql/jdbc加进来,再运行,God!还是找不到!昨天我被这个问题弄了一晚上也没弄出来,查论坛里大家都说加进来就好了,我却不行,很是郁闷,结果今早一开机,就ok了!!原来设完这项后要重启Jbuilder 才能生效!!!

好了!这次成功了!到Mysql里去看,表里已经加了一条数据了!!

又试了下中文,不行,进到数据库里就成了??,取出来也是??。解决中文问题的办法是先设置Mysql的编码:

c:/windows下有个my.ini文件,加一行:
default-character-set=gbk
注意小写gbk,否则mysql不能正常启动。存盘,重启mysql。

然后在Hibernate.properties里把这行改为:
hibernate.connection.url jdbc:mysql:///quickstart?useUnicode=true&characterEncoding=gb2312

再运行!中文问题就顺利解决了!

按照Hibernate本身文档里的例子,目前还没有做成功,还不太明白中间服务器和Hibernate的关系,应该是只在中间层需要和客户端传输如Servlet, JSP等B/S结构里才需要中间服务器吧!Java本身通过Hibernate与数据库打交道应该是完全不用的,就象上面的例子。而文档中在Tomcat中的第一个例子采用tomcat目录下的conf目录中的server.xml+后面的hibernate.cfg.xml来配置与数据库的连接,等同与前面Hibernate.properties中的内容,试了下,要么找不到hibernate.cfg.xml,要么找不到Cat.hbm.xml,不知道怎么回事。另外,例子最后也没有说部署到Tomcat中去啊!而且例程本身是个Application,没有Servlet/JSP,即使部署了怎么访问呢?这些都是目前的疑问,总之是对Tomcat的部署以及Tomcat与Hibernate的关系还不甚了了,相信以后慢慢回明白的!
   发表时间:2004-07-06  
老哥,同感啊,呵呵。
研究这个东西的入门文档,很多文档都是不小心将细节部分给忘记了,结果后来者看起来比较痛苦一点。
0 请登录后投票
   发表时间:2004-07-06  
建议楼主到ibm上面去搜索一下hibernate文章,然后stepbystep,你上面所说的问题就可以都解决了
0 请登录后投票
   发表时间:2004-07-07  
对了老手来说差一点没什么问题,对于新手来说差一点可能就一直通过不了,楼主提的这几个问题我都遇见过,不知楼主把这些方法拿到eclipse中试验过没有,我怎么一直不成功?(在JBuilder中成功了)
hotmanhh 写道
老哥,同感啊,呵呵。
研究这个东西的入门文档,很多文档都是不小心将细节部分给忘记了,结果后来者看起来比较痛苦一点。
0 请登录后投票
   发表时间:2004-07-07  
downpour 写道
建议楼主到ibm上面去搜索一下hibernate文章,然后stepbystep,你上面所说的问题就可以都解决了


呵呵,是的,对老手来说这些都不算什么啦,而新手恐怕也不知道ibm有资料。不过今天你告诉我,非常感谢啦!
0 请登录后投票
   发表时间:2004-07-07  
其实hibernate上手不算很难   只是网上资源太少了
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics