Hibernate学习小记

来源:互联网 发布:spd博士软件下载 编辑:程序博客网 时间:2024/05/07 04:00


/**
  by metaphy
  2005-12-26
  v0.01
*/

昨天面试,被打击的不轻,9道基础题目,错了4道,其中一个就是关于hibernate的;这种接触过就会,没接触过就不会的题目,我看不出能考察出什么东西;但公司就是如此的不讲道理,会就是水平高,反之就低,仔细想想,真是行业的悲哀。

一、开发环境
OS:WindowsXP
JDK:1.4.2
Database:SqlServer2000 (sp3)
JDBC驱动:Microsoft
Hibernate:2.1(hibernate2.jar,889k)
Eclipse:3.0
(需要有数据库的知识和Eclipse的知识)

装好DB后,顺手建立一个表,安装JDBC的jar包,将其加入工程;随后,写了一个测试类:
[code]
//DbTest
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class DbTest{
 public static void main(String args[]){
  try{
   Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
   Connection conn =DriverManager.getConnection("jdbc:microsoft:sqlserver://localhost:1433;User=sa;Password=sa;DatabaseName=gtest");
   Statement stmt=conn.createStatement();
   String sql="select * from  department";
   ResultSet rs = stmt.executeQuery(sql);
   while(rs.next()) {
    System.out.println("records:/t"+rs.getString("department_name"));
   }
   rs.close();
   stmt.close();
   conn.close();
  } catch(Exception ex) {
   System.err.println(ex.getMessage());   
  }
  /*写到这,不禁想起网上的那篇“你擦了吗”的帖子,嘿嘿,测试用的例子嘛,先这样写吧*/
 }
}
[/code]
编译,运行,一切正常;数据库的记录清楚的打印出来了。

到这里,有必要说一下我在Eclipse下面所建工程的结构及数据库结构:
hibapp- |-src (源文件)
 |-lib (库文件,现在包括3个jdbc驱动,一个hibernate2.jar)
 |-bin (output directort)

p.s.由于hibernate 内部运行的时候需要许多的关联库(一般是apache的公共包),所以,相关的涉及到的jar包都需要包含进来;
我的最终的jar目录(有的没有用到的我也给加进来了):

307,930 cglib-full-2.0.2.jar
118,726 commons-beanutils.jar
165,119 commons-collections.jar
109,096 commons-digester.jar
 63,980 commons-lang.jar
 31,605 commons-logging.jar
 46,865 commons-validator.jar
486,522 dom4j.jar
 53,232 ehcache-0.9.jar (注:编译的时候,让这个弄的很郁闷,找了半天,才发现需要这个包)
935,212 hibernate2.jar
604,048 ifxjdbc.jar
146,718 jdom.jar
104,076 jolt.jar
  8,812 jta.jar
352,291 log4j-1.2.9.jar
286,707 msbase.jar
 67,024 mssqlserver.jar
 58,903 msutil.jar
 13,091 odmg-3.0.jar


数据库gtest
--表 department
CREATE TABLE [dbo].[department] (
 [department_id] [int] IDENTITY (1, 1) NOT NULL ,
 [department_name] [varchar] (50) COLLATE Chinese_PRC_CI_AS NOT NULL
) ON [PRIMARY]
GO

二、Hibernate配置
Hibernate的本质是一个“ORM”映射框架;对于上面例子(DbTest)中的数据库链接硬编码,hibernate采用配置文件的办法来管理,在进行config的时候从中读取信息,信息不外乎数据库链接url,用户名/密码,数据库名等,当然还有一些其他的配置信息,如下:
[code]
//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>
 <!-- SessionFactory 配置 -->
 <session-factory>
  <!-- 数据库URL -->
  <property name="hibernate.connection.url">
   jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=gtest
  </property>
  <!-- 数据库JDBC驱动 -->
  <property name="hibernate.connection.driver_class">
   com.microsoft.jdbc.sqlserver.SQLServerDriver
  </property>
  <!-- 数据库用户名 -->
  <property name="hibernate.connection.username">
   sa
  </property>
  <!-- 数据库用户密码 -->
  <property name="hibernate.connection.password">
   sa
  </property>
  <!--dialect 每个数据库都有其对应的Dialet以匹配其平台特性 -->
  <property name="dialect">
   net.sf.hibernate.dialect.SQLServerDialect
  </property>
  <!-- 是否将运行期生成的SQL输出到日志以供调试 -->
  <property name="hibernate.show_sql">
   True
  </property>
  <!-- 是否使用数据库外连接 -->
  <property name="hibernate.use_outer_join">
   True
  </property>
  <!-- 事务管理类型,这里我们使用JDBC Transaction -->
  <property name="hibernate.transaction.factory_class">
   net.sf.hibernate.transaction.JDBCTransactionFactory
  </property>
  <!--映射文件配置,注意配置文件名必须包含其相对于根的全路径 -->
  <mapping resource="test/hib/tables/Department.hbm.xml"/>
 </session-factory>
</hibernate-configuration>
[/code]

通用的配置文件配好后,我们需要对类-表的映射配置文件,hibernate提供了一个自动生成工具Middlegen,用起来也很简单(需要ant),当然需要修改一些配置,鉴于个人环境的不同,可能遇到的问题也不一样;偶省略过程以免误导(上过当),只把最后的结果写下:
[code]
//Department.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
    "
http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd" >
   
<hibernate-mapping>
<!--
    Created by the Middlegen Hibernate plugin 2.1

    http://boss.bekk.no/boss/middlegen/
    http://www.hibernate.org/
-->

<class
    name="test.hib.tables.Department"
    table="department"
>
    <id
        name="departmentId"
        type="int"
        column="department_id"
    >
        <generator class="native" />
    </id>

    <property
        name="departmentName"
        type="java.lang.String"
        column="department_name"
        not-null="true"
        length="50"
    />

    <!-- Associations -->
</class>
</hibernate-mapping>

//这个是POJO(plain ordinary java object)
//Department.java
package test.hib.tables;

import java.io.Serializable;

public class Department implements Serializable {
    private int departmentId ;
    private String departmentName ;
   
    public int getDepartmentId() {
        return departmentId;
    }
    public void setDepartmentId(int departmentId) {
        this.departmentId = departmentId;
    }
    public String getDepartmentName() {
        return departmentName;
    }
    public void setDepartmentName(String departmentName) {
        this.departmentName = departmentName;
    }
}
[/code]

三、Hibernate开发
映射与POJO 写好后,就该练习一些基本的增删查改的东西了;下面是个基本的练习:
[code]
package test.hib.bizlogic;

import java.io.File;
import java.util.List;

import net.sf.hibernate.HibernateException;
import net.sf.hibernate.Session;
import net.sf.hibernate.SessionFactory;
import net.sf.hibernate.Transaction;
import net.sf.hibernate.cfg.Configuration;
import test.hib.tables.Department;

public class BizDepartment {
    Configuration config ;
    SessionFactory sessionFactory ;
    Session session ;
   
    public BizDepartment(){
        try {
            File file = new File("D://ecampus//hibapp//src//test//hib//tables//hibernate.cfg.xml");
     //这里用硬编码配置config;据说将文件路径加入环境变量Path,可以直接这样写:
     //config = new Configuration().configure(); 不过我试验了一下,发现不行
     config = new Configuration().configure(file);
     sessionFactory = config.buildSessionFactory();
        }catch(Exception e){
            e.printStackTrace() ;
        }       
    }
   
    public Department departmentFind(String depName){
        Department dep = null ;
        String hql = " from Department where department_name ='"+ depName +"'"  ;
        try {
            session = sessionFactory.openSession();
     List list = session.find(hql) ;
     if (list!=null && list.size()>0){
         dep = (Department) list.get(0);
     }
            session.flush();
            session.close();
        }catch (HibernateException e){
            e.printStackTrace();
        }
        return dep ;
    }
   
    public void departmentAdd(Department dep){
        try {
            session = sessionFactory.openSession();
      Transaction tx= session.beginTransaction();
      if (dep != null && dep.getDepartmentName()!=null){
          session.save(dep);
          tx.commit();
          session.flush() ;       
      }
      session.close();
        } catch (HibernateException e) {
            e.printStackTrace();
        }
    }
   
    public void departmentModify(Department dep){
        try {
            session = sessionFactory.openSession();
      Transaction tx= session.beginTransaction();
      if (dep != null && dep.getDepartmentName()!=null){
          session.update(dep) ;
          tx.commit();
          session.flush() ;       
      }
      session.close();
        } catch (HibernateException e) {
            e.printStackTrace();
        }
    }
   
    public void departmentDelete(Department dep){
        try {
            session = sessionFactory.openSession();
      Transaction tx= session.beginTransaction();
      if (dep != null ){
          session.delete(dep);
          tx.commit();
          session.flush() ;       
      }
      session.close();
        } catch (HibernateException e) {
            e.printStackTrace();
        }
    }
   
    public static void main(String[] args) {
        BizDepartment bd = new BizDepartment();
        String depName = "测试部" ;
        Department dep = bd.departmentFind(depName) ;
        if (dep!=null){
            System.out.println(depName+ "ID :" + dep.getDepartmentId()) ;
            dep.setDepartmentName(depName+"_修改");
            bd.departmentModify(dep);
        }
       
        //bd.departmentDelete(dep) ;       
    }
}
[/code]

编译通过,ok!~

p.s.
在学习一个新的技术的时候,一定要同时参考几种(3种以上)资料,切忌只看一篇文章并照着它的例子做;因为你要知道的是其后的道理,而不仅仅是怎么做;并且许多例子因为种种原因,并不能一下就能运行成功