一、 Hibernate介紹??? Hibernate是基于對(duì)象/關(guān)系映射(ORM,Object/Relational Mapping)的一個(gè)解決方案。ORM方案的思想是將對(duì)象模型表示的對(duì)象映射到關(guān)系型數(shù)據(jù)庫(kù)中,或者反之。Hibernate目前是ORM思想在 Java中最成功、最強(qiáng)大的實(shí)現(xiàn)。它于2001年的年末發(fā)布第一個(gè)版本,立即引起了廣泛的注意。2003年6月,Hibernate2發(fā)表,并且獲得 Jolt大獎(jiǎng),進(jìn)而被JBoss吸納成為它的一個(gè)子項(xiàng)目。2005年3月,Hibernate 3發(fā)表,其中做了一些比較重大的改進(jìn)。本文以Hibernate3為基礎(chǔ)編寫(xiě)。
??? 另外,Hibernate除了可以在J2EE容器中運(yùn)行外,還可以運(yùn)行在Java應(yīng)用程序中。本文就是以Java應(yīng)用程序?yàn)槔齺?lái)介紹它。
二、配置開(kāi)發(fā)環(huán)境??? 本文以一個(gè)Java應(yīng)用程序(Java Application)為例,介紹如何使用Hibernate來(lái)進(jìn)行數(shù)據(jù)庫(kù)操作。??? 在進(jìn)行Hibernate開(kāi)發(fā)之前,需要首先獲得Hibernate類庫(kù)、相應(yīng)數(shù)據(jù)庫(kù)的JDBC驅(qū)動(dòng)類庫(kù)。Hibernate類庫(kù)可以從http://www.hibernate.org中下載,目前的版本是3.0。而JDBC驅(qū)動(dòng)可以根據(jù)不同的數(shù)據(jù)庫(kù)來(lái)選擇,在這個(gè)例子中,使用的是Oracle數(shù)據(jù)庫(kù),那么相應(yīng)的JDBC驅(qū)動(dòng)可以從Oracle安裝目錄\ora92\jdbc下獲得。其他的數(shù)據(jù)庫(kù)請(qǐng)根據(jù)相關(guān)的說(shuō)明獲得。
??? 下載Hibernate包后,可以將它解壓到一個(gè)文件夾,此處假設(shè)為C:\hibernate-3.0,然后將C:\hibernate-3.0\下的 hibernate.jar和C:\hibernate-3.0\lib下的那些第三方類庫(kù)也放到環(huán)境變量CLASSPATH中。(通常,只需要 dom4j、cglig、commons-logging、commons-collections、log4j、ehcache、asm、jta、 antlr這些類庫(kù)就可以了)
??? 做完這些配置后,就可以在此基礎(chǔ)上進(jìn)行基于Hibernate的Java程序開(kāi)發(fā)了。
三、開(kāi)發(fā)基于Hibernate的應(yīng)用??? 現(xiàn)在假設(shè)我們?cè)贠racle數(shù)據(jù)庫(kù)中創(chuàng)建了一個(gè)表Student,它的字段如下表所示:
字段?說(shuō)明Student_ID?學(xué)員編號(hào),整型,PK,自動(dòng)增長(zhǎng)Student_Name?學(xué)員姓名,字符串類型Student_Age?學(xué)員年齡,整型如果我們?cè)贠racle中定義這個(gè)數(shù)據(jù)庫(kù)表,我們可以定義一個(gè)創(chuàng)建數(shù)據(jù)庫(kù)表的SQL腳本如下:create table Student(?Student_ID? number(6) NOT NULL PRIMARY KEY,?Student_Name varchar2(10) NOT NULL,?Student_Age number(2) NOT NULL);
??? 另外,因?yàn)樵贠racle中沒(méi)有“自動(dòng)增長(zhǎng)”類型的字段,所以通常情況下我們需要定義一個(gè)sequence來(lái)作為自動(dòng)增長(zhǎng)類型字段的數(shù)據(jù)。在這里,我們也可以定義一個(gè)sequence來(lái)給Student_ID字段提供數(shù)據(jù)。創(chuàng)建sequence的SQL腳本如下:
CREATE SEQUENCE student_sequence INCREMENT BY 1START WITH 1000NOMAXVALUENOCYCLECACHE 10;
??? 我們?cè)谶@里創(chuàng)建了一個(gè)student_sequence,準(zhǔn)備用來(lái)作為Student_ID字段的值。
??? 接著,我們需要一個(gè)hibernate.cfg.xml或者屬性文件hibernate.properties來(lái)指定Hibernate所使用的數(shù)據(jù)庫(kù)以及用戶名、密碼等其他相關(guān)的配置,我們?cè)诖耸褂脁ml文件,它的內(nèi)容如下:
源文件:hibernate.cfg.xml<!DOCTYPE hibernate-configuration PUBLIC?"-//Hibernate/Hibernate Configuration DTD 3.0//EN"?"<hibernate-configuration>?<session-factory><!--程序執(zhí)行的時(shí)候是否顯示真正的sql語(yǔ)句-->??<property name="show_sql">true</property>??<!--使用的SQL對(duì)應(yīng)的“方言”,此處是Oracle9的“方言”--><property name="dialect">org.hibernate.dialect.Oracle9Dialect</property>??<!--連接數(shù)據(jù)庫(kù)的Driver--><property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>??<!--數(shù)據(jù)庫(kù)連接url--><property name="connection.url">jdbc:oracle:thin:@localhost:1521:nitpro</property>??<!--用戶名--><property name="connection.username">system</property><!--密碼-->??<property name="connection.password">manager</property>?</session-factory></hibernate-configuration>
??? 做完前面的這些準(zhǔn)備工作后,下面就讓我們進(jìn)入激動(dòng)人心的Hibernate編程吧!
??? 首先,我們需要定義一個(gè)用于表示“學(xué)生”對(duì)象的Student類:
源文件:Student.javapublic class Student{??? private int student_id;??? private String student_name;??? private int student_age;??? ??? public int getStudent_id()??? {??????? return student_id;??? }??? public String getStudent_name()??? {??????? return student_name;??? }??? public int getStudent_age()??? {??????? return student_age;;??? }??? public void setStudent_id(int id)??? {??????? this.student_id = id;??? }??? public void setStudent_name(String name)??? {??????? this.student_name = name;??? }??? public void setStudent_age(int age)??? {??????? this.student_age = age;??? } }
??? 這個(gè)類很簡(jiǎn)單,就是一個(gè)典型的JavaBean的定義:有三個(gè)屬性:student_id、student_name和student_age,分別對(duì)應(yīng)數(shù)據(jù)庫(kù)表Student中的三個(gè)字段,并且在這個(gè)類中定義了對(duì)應(yīng)各個(gè)屬性的setter/getter方法。
??? 接下來(lái),我們需要給這個(gè)類定義一個(gè)XML映射文件“Student.hbm.xml”,文件內(nèi)容如下:
源文件:Student.hbm.xml<?xml version="1.0" encoding="utf-8"?><!DOCTYPE hibernate-mapping???? PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"???? "<hibernate-mapping>???? ??? <class name="Student" table="Student">???????? ??????? <id name="student_id" column="student_id" type="java.lang.Integer">???????????? ??????????? <generator class="native">???????? ??????????????? <param name="sequence">student_sequence</param>??????????? </generator>??????? </id>???????? ??????? <property name="student_name" column="Student_Name"?type="java.lang.String"/>??????? <property name="student_age" column="Student_Age" type="java.lang.Integer"/>??? </class></hibernate-mapping>
??? 注意,在這個(gè)xml文件中,我們首先使用class元素定義了我們定義的Java類和數(shù)據(jù)庫(kù)表之間的關(guān)系,在這里,我們定義的Java類和數(shù)據(jù)庫(kù)表名稱都 是Student,然后,我們使用id元素定義了主鍵名稱、類型等,它有一個(gè)子元素generator來(lái)說(shuō)明主鍵的產(chǎn)生方式,此處指定的是 “native”,表示根據(jù)數(shù)據(jù)庫(kù)來(lái)選擇,比如,對(duì)于Oracle數(shù)據(jù)庫(kù),它會(huì)去尋找一個(gè)sequence(默認(rèn)情況下,它會(huì)去尋找一個(gè)名為 “hibernate_sequence”的sequence),我們可以用參數(shù)param來(lái)指定一個(gè)sequence。而property用來(lái)指定 Student.java類中的屬性和Student數(shù)據(jù)庫(kù)表之間的對(duì)應(yīng)關(guān)系,以及各個(gè)字段的數(shù)據(jù)類型。在這個(gè)例子中,我們指定的數(shù)據(jù)類型是Java語(yǔ)言 中的數(shù)據(jù)類型(此時(shí)需要指定引用類型數(shù)據(jù)),我們也可以使用Hibernate中自定義的數(shù)據(jù)類型,限于篇幅,在本文中不一一講解。
??? 然后,我們需要在hibernate.cfg.xml中加入這個(gè)文件的映射,可以在</session-factory>之前加入下面的語(yǔ)句:
<mapping resource="Student.hbm.xml"/>最后,我們需要編寫(xiě)一個(gè)測(cè)試類來(lái)測(cè)試一下,能否通過(guò)Hibernate和前面我們定義的相關(guān)程序,完成對(duì)數(shù)據(jù)庫(kù)的操作。我們編寫(xiě)一個(gè)測(cè)試類如下:源文件:Test.javaimport org.hibernate.*;import org.hibernate.cfg.*;
public class Test{??? public static void main(String[] args)??? {??????? try??????? {??????????? //通過(guò)Configuration獲得一個(gè)SessionFactory對(duì)象SessionFactory sf = new Configuration().configure().buildSessionFactory();??????????? //打開(kāi)一個(gè)Session??????????? Session session = sf.openSession();??????????? //開(kāi)始一個(gè)事務(wù)??????????? Transaction tx = session.beginTransaction();??????????? //創(chuàng)建一個(gè)Student對(duì)象??????????? Student stu = new Student();??????????? //通過(guò)Student的setter方法改變它的屬性??????????? //注意student_id不用我們?cè)O(shè)置??????????? stu.setStudent_name("zhangsan");??????????? stu.setStudent_age(18);??????????? //通過(guò)session的save()方法將Student對(duì)象保存到數(shù)據(jù)庫(kù)中??????????? session.save(stu);??????????? //提交事務(wù)??????????? tx.commit();??????????? //關(guān)閉會(huì)話??????????? session.close();??????? }??????? catch(Exception e)??????? {??????????? e.printStackTrace();??????? }??? }??? }
??? 編譯并運(yùn)行這個(gè)程序,如果前面的配置和程序都沒(méi)有問(wèn)題,應(yīng)該可以正確的往數(shù)據(jù)庫(kù)表Student中插入一條數(shù)據(jù),并且在控制臺(tái)上能夠得到如下輸出(只列出部分輸出內(nèi)容):
Hibernate: select student_sequence.nextval from dualHibernate: insert into Student (Student_Name, Student_Age, student_id) values (?,?,?)
??? 可以看到,雖然我們自己沒(méi)有編寫(xiě)SQL語(yǔ)句進(jìn)行插入數(shù)據(jù)的操作,但是其實(shí)Hibernate還是要使用SQL語(yǔ)句來(lái)進(jìn)行數(shù)據(jù)庫(kù)的操作,只是這個(gè)過(guò)程對(duì)程序員來(lái)說(shuō)是透明的。
posted on 2007-03-13 14:30 Bill111 閱讀(593) 評(píng)論(0) 編輯 收藏