posts - 70,comments - 408,trackbacks - 0

      冬眠温暖,"冬天"快乐,一夜的冬雨在静静中把冬衣轻轻换上,Hibernate,就东面一样,在程序"冬天"里给我们带来一丝温暖,Hibernate的名字真的很优美,当我曾经第一天知道有一种技术叫"冬眠".我就深深的喜欢上了这种技术.所以产生了一种想法,把这种技术以最简单明了的方式记录自己的Blog上,一方面能帮助一些刚刚学习它的朋友,另一方面也能让自己对Hibernate的理解更加深刻.希望大家多多支持我,多光临我的Blog.好了下面言归正传,Hibernate是JAVA应用和关系型数据库中间的一座桥梁.它负责把JAVA对象和关系型数据库映射在一起,其实简单的理解Hibernate可以理解成一种中间件,向下封装了JDBC对数据库的操作,向上提供了面向对象的数据库访问API.今天我们不谈理论,往往学习一种技术进来就谈一些很深的理论会让人学的晕头转向,我的学习方式向来都是先搞定一个简单明了的小例子,然后在回头看理论,到时候总能有事半功倍的感觉.简单的说一下Hibernate的流程:
      1)创建Hibernate配置文件
      2)创建持久化类
      3)创建对象和关系型数据库的映射文件
      4)通过Hibernate的API访问数据库

      好了.既然流程知道了.我们就一步一步来做吧,首先创建一个JAVA工程(JAVA工程和WEB工程相比,更加简单直观),然后我们引入必须要有的包,hibernate2包,log4j的包,dom4j的包,MSSQL的3个驱动包,然后创建Hibernate的配置文件,和其他的properties一样,都是以键=值的形式表示的.当然你也可以选择用XML的形式来创建hibernate的配置文件,这里用properties方式做演示,名字叫hibernate.properties.为了理解起来容易些,我们使用最简单的数据库MS SQL Server 2000:

首先要设置方言,方言的意思就是不同的数据库,有不同的语言规范,就跟我们现实中的北京话于广东话的差距一样.
hibernate.dialect=net.sf.hibernate.dialect.SQLServerDialect
然后设置数据库的驱动类.
hibernate.connection.driver_class=com.microsoft.jdbc.sqlserver.SQLServerDriver
设置数据库的路径
hibernate.connection.url=jdbc:sqlserver://127.0.0.1:1433;charset=GBK;selectMethod=cursor;databaseName=TEMPDB
数据库登录名
hibernate.connection.username=sa
数据库密码
hibernate.connection.password=555
最后设置的属性是是否在控制台打印SQL语句,这里我们设置为true,因为方便调试,默认是false
hibernate.show_sql=true
备注:在Hibernate软件包的etc目录下,有一个hibernate.properties文件,里边有各种关系型数据库的配置样例.

      OK,配置文件创建完了.就是这么简单,现在我们来创建一个持久化类.其实说白了持久化类超级简单,就是我们曾经用的JAVABEAN嘛,写几个字段Eclipse都能自动生成相关的方法,不过Hibernate的持久化类要 implements一个接口,就是Sreializable接口.下面是持久化类的例子,这里省略了大多数的get,set方法,到时候自己加上就OK了.
public class Customer implements Serializable {
  private Long id;
  private String name;
  private String email;
  private String password;
  private int phone;
  public Long getId(){
    return id;
  }
  public void setId(Long id){
    this.id = id;
  }
  ........
}

      OK持久化类也一样简单,下面我们要做的事情更简单,就是到我们的数据库中,创建一个和持久化类字段对应的表.例子如下:
create database TEMPDB;

create table CUSTOMERS (
  ID bigint not null primary key,
  NAME varchar(15) not null,
  EMAIL varchar(128) not null,
  PASSWORD varchar(8) not null, 
  PHONE  int
)

      数据库搞定了.下面来完成一件比较重要的事情,就是创建对象-关系映射文件.,Hibernate采用XML格式的文件来指定对象和关系型数据库之间的映射,在运行的时候Hibernate将根据这个映射文件来生成各种SQL语句.下面我们创建一个Customer.hbm.xml的文件,这个文件和Customer.class放在同一个目录下.
<?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>
  <class name="com.Customer" table="CUSTOMERS">
    <id name="id" column="ID" type="long">
      <generator class="increment"/>
    </id>
    <property name="name"  column="NAME"  type="string" not-null="true" /> 
    <property name="email"     column="EMAIL"     type="string" not-null="true" />
    <property name="password"  column="PASSWORD"  type="string" not-null="true"/>
    <property name="phone"     column="PHONE"     type="int" /> 
  </class>
</hibernate-mapping>

      首先<class 标签的name属性指定的是类名,table属性指定的和这个类映射的表名.<id 标签的<generator 子标签指定对象标识符生成器,他负责在对象里产生表的唯一标识符.<property标签的name属性指定持久化类中属性的名字,clumn属性顾名思义,列的意思,这里是指定了数据库中的字段.type属性指定Hibernate的映射类型,Hibernate映射类型是JAVA类型和SQL类型之间的桥梁,先简单的知道JAVA里的String和数据库里的varchar这里配置为string,而JAVA里的int和数据库里的int配置为int.还有N多我们以后深入使用Hibernate的时候在深入的了解就OK了.现在知道简单的足以.最后说一下<property标签的not-null属性是设置这个字段是否为空.值得我们关注的是,在实际的项目开发中,我们不应该以来Hibernate或者数据库来做数据的验证.全部在业务罗基层处理好就OK了.下面说一下Hibernate采用XML文件来配置对象-关系映射的优点:
   1)Hibernate既不会渗透到上层的业务模型中,也不会泄漏到下层的数据模型中
   2)软件开发人员可以独立设计业务模型,数据库设计人员可以独立设计数据模型,互相不受拘束.
   2)对象-关系映射不依赖于任何代码,提高了程序的灵活性,使得维护更加方便.

      这里说一下映射文件的类型定义DTD,在我们的Customer.hbm.xml中,文件开头就声明了DTD类型,DTD的意思就是对XML文件的语法做定义,在实际编程中,我们引入正确的DTD规范,让我们编写XML非常方便.每一种XML文件都有独自的DTD文件.Hibernate的DTD文件下载地址是:http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd,在Hibernate的软件包src\net\sf\hibernate目录下也提供了hibernate-mapping-2.0.dtd文件.

      
下面看一个重点吧,通过Hibernate的API操作数据库:
public class BusinessService{
  public static SessionFactory sessionFactory;
  static{
    try{
      // Create a configuration based on the properties file we've put
      // in the standard place.
      Configuration config = new Configuration();
      config.addClass(Customer.class);
      // Get the session factory we can use for persistence
      sessionFactory = config.buildSessionFactory();
    }catch(Exception e){e.printStackTrace();}
  }

  public void findAllCustomers(ServletContext context,OutputStream out) throws Exception{
    // Ask for a session using the JDBC information we've configured
    Session session = sessionFactory.openSession();
    Transaction tx = null;
    try {
      tx = session.beginTransaction();
      List customers=session.find("from Customer as c order by c.name asc");
      for (Iterator it = customers.iterator(); it.hasNext();) {
         printCustomer(context,out,(Customer) it.next());
      }

      // We're done; make our changes permanent
      tx.commit();

    }catch (Exception e) {
      if (tx != null) {
        // Something went wrong; discard all partial changes
        tx.rollback();
      }
      throw e;
    } finally {
      // No matter what, close the session
      session.close();
    }
  }
  public void saveCustomer(Customer customer) throws Exception{
     // Ask for a session using the JDBC information we've configured
    Session session = sessionFactory.openSession();
    Transaction tx = null;
    try {
      tx = session.beginTransaction();
      session.save(customer);
      // We're done; make our changes permanent
      tx.commit();

    }catch (Exception e) {
      if (tx != null) {
        // Something went wrong; discard all partial changes
        tx.rollback();
      }
      throw e;
    } finally {
      // No matter what, close the session
      session.close();
    }
  }

  public void loadAndUpdateCustomer(Long customer_id,String address) throws Exception{
    // Ask for a session using the JDBC information we've configured
    Session session = sessionFactory.openSession();
    Transaction tx = null;
    try {
      tx = session.beginTransaction();

      Customer c=(Customer)session.load(Customer.class,customer_id);
      c.setAddress(address);
      // We're done; make our changes permanent
      tx.commit();

    }catch (Exception e) {
      if (tx != null) {
        // Something went wrong; discard all partial changes
        tx.rollback();
      }
      throw e;
    } finally {
      // No matter what, close the session
      session.close();
    }
  }
  public void deleteAllCustomers() throws Exception{
    // Ask for a session using the JDBC information we've configured
    Session session = sessionFactory.openSession();
    Transaction tx = null;
    try {
      tx = session.beginTransaction();
      session.delete("from Customer as c");
      // We're done; make our changes permanent
      tx.commit();

    }catch (Exception e) {
      if (tx != null) {
        // Something went wrong; discard all partial changes
        tx.rollback();
      }
      throw e;
    } finally {
      // No matter what, close the session
      session.close();
    }
  }

  private void printCustomer(ServletContext context,OutputStream out,Customer customer)throws Exception{
   if(out instanceof ServletOutputStream)
           printCustomer(context,(ServletOutputStream) out,customer);
       else
          printCustomer((PrintStream) out,customer);
  }
  private void printCustomer(PrintStream out,Customer customer)throws Exception{
   //save photo
    byte[] buffer=customer.getImage();
    FileOutputStream fout=new FileOutputStream("photo_copy.gif");
    fout.write(buffer);
    fout.close();

    out.println("------以下是"+customer.getName()+"的个人信息------");
    out.println("ID: "+customer.getId());
    out.println("口令: "+customer.getPassword());
    out.println("E-Mail: "+customer.getEmail());
    out.println("电话: "+customer.getPhone());

  }
  private void printCustomer(ServletContext context,ServletOutputStream out,Customer customer)throws Exception{
    //save photo
    byte[] buffer=customer.getImage();
    String path=context.getRealPath("/");
    FileOutputStream fout=new FileOutputStream(path+"photo_copy.gif");
    fout.write(buffer);
    fout.close();

    out.println("------以下是"+customer.getName()+"的个人信息------"+"<br>");
    out.println("ID: "+customer.getId()+"<br>");
    out.println("口令: "+customer.getPassword()+"<br>");
    out.println("E-Mail: "+customer.getEmail()+"<br>");
    out.println("电话: "+customer.getPhone()+"<br>");
  }
   public void test(ServletContext context,OutputStream out) throws Exception{

    Customer customer=new Customer();
    customer.setName("我心依旧");
    customer.setEmail("it5719@163.com");
    customer.setPassword("666");
    customer.setPhone(5555555);
 
    saveCustomer(customer);

    findAllCustomers(context,out);
    loadAndUpdateCustomer(customer.getId(),"Beijing");
    findAllCustomers(context,out);

    deleteAllCustomers();
  }

  public static void main(String args[]) throws Exception {
    new BusinessService().test(null,System.out);
    sessionFactory.close();
  }

}

      OK最后一步我们还需要配置LOG4J的属性文件.下面是LOG4J的配置文件,如果想了解LOG4J,请看我的前一篇随笔,有简单明了的介绍.然后调试过这个程序看看结果.如果通过了,恭喜你,你已经进入了"冬天"正式开始了Hibernae.
#init log4j level console file
log4j.rootLogger=ERROR,console,file

#create log4j console
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%-5p %d [%t] (%F,%L) - %m%n

#create log4j file
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=debug.log
log4j.appender.file.MaxFileSize=100KB
log4j.appender.file.MaxBackupIndex=1
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%-5p %d [%t] (%F,%L) - %m%n

posted on 2007-05-15 19:33 我心依旧 阅读(2210) 评论(3)  编辑  收藏

FeedBack:
# re: "冬天"快乐,带你进入Hibernate
2007-05-16 08:44 | Swing
孙wq的书吧 挺好的  回复  更多评论
  
# re: "冬天"快乐,带你进入Hibernate
2007-05-16 09:10 | 刘甘泉
用spring 控制事务简单的多~~  回复  更多评论
  
# re: "冬天"快乐,带你进入Hibernate[未登录]
2007-06-05 17:40 | yy
Hibernate的数据获取策略有点麻烦。。。  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: