解說(shuō)Hibernate的工作原理實(shí)例
大家可能對(duì)Hibernate 有大概了解,但Hibernate 原理到底是什么,不一定清楚,這篇文章主要通過(guò)一個(gè)實(shí)例說(shuō)明Hibernate 原理。希望對(duì)大家的學(xué)習(xí)有所幫助。
我們知道如果用java連接數(shù)據(jù)庫(kù)我們首先想到的就是JDBC,那么Hibernate 原理是什么呢?hibernate可以理解為是一個(gè)中間件它負(fù)責(zé)把java程序的sql語(yǔ)句接收過(guò)來(lái)發(fā)送到數(shù)據(jù)庫(kù),而數(shù)據(jù)庫(kù)返回來(lái)的信息hibernate接收之后直接生成一個(gè)對(duì)象傳給java。
在說(shuō)Hibernate 原理之前,先說(shuō)說(shuō)Hibernate的文件吧。
假設(shè)一個(gè) student 的學(xué)生表:
sql語(yǔ)句:
- create table student(id Number(10),name varchar2(20))
接下來(lái)呢.我們需要有兩個(gè)hibernate特有的文件。一個(gè)是以.cfg.xml結(jié)尾的文件.一個(gè)是以.hbm.xml結(jié)尾的文件。 這兩個(gè)文件做什么用的呢?
.cfg.xml 的作用就是連接數(shù)據(jù)庫(kù),文件內(nèi)部其實(shí)就是一個(gè)由user,password,url,driver組成的一個(gè)連接庫(kù)的基本信息。
文件的內(nèi)容是這樣的:
- xml version='1.0' encoding='UTF-8'?>
- PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
- <hibernate-configuration>
- <session-factory>
- <property name="connection.username">111< SPAN>property>
- <property name="connection.url">jdbc:oracle:thin:@127.0.0.1:1521:ris< SPAN>property>
- <property name="dialect">org.hibernate.dialect.Oracle9Dialect< SPAN>property>
- <property name="connection.password">111< SPAN>property>
- <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver< SPAN>property>
- <mapping resource="Student.hbm.xml"/>
- < SPAN>session-factory>
- < SPAN>hibernate-configuration>
這個(gè)文件的全稱應(yīng)該是"你的應(yīng)用名字.cfg.xml"。當(dāng)前例子建立的項(xiàng)目名稱是one.cfg.xml 。
簡(jiǎn)單分析一下這個(gè)文件:
里面的那些 property 是一些連接需要的東西。其中dialect 這個(gè)是hibernate的方言屬性值,對(duì)于不同的數(shù)據(jù)庫(kù),方言的值dialect是不同的,那么下面就列出在不同的數(shù)據(jù)庫(kù)中如何設(shè)置該dialect值(參見(jiàn)下表):
RDBMS |
方言 |
DB2 |
org.hibernate.dialect.DB2Dialect |
DB2 AS/400 |
org.hibernate.dialect.DB2400Dialect |
DB2 OS390 |
org.hibernate.dialect.DB2390Dialect |
PostgreSQL |
org.hibernate.dialect.PostgreSQLDialect |
MySQL |
org.hibernate.dialect.MySQLDialect |
MySQL with InnoDB |
org.hibernate.dialect.MySQLInnoDBDialect |
MySQL with MyISAM |
org.hibernate.dialect.MySQLMyISAMDialect |
Oracle (any version) |
org.hibernate.dialect.OracleDialect |
Oracle 9i/10g |
org.hibernate.dialect.Oracle9Dialect |
Sybase |
org.hibernate.dialect.SybaseDialect |
Sybase Anywhere |
org.hibernate.dialect.SybaseAnywhereDialect |
Microsoft SQL Server |
org.hibernate.dialect.SQLServerDialect |
SAP DB |
org.hibernate.dialect.SAPDBDialect |
Informix |
org.hibernate.dialect.InformixDialect |
HypersonicSQL |
org.hibernate.dialect.HSQLDialect |
Ingres |
org.hibernate.dialect.IngresDialect |
Progress |
org.hibernate.dialect.ProgressDialect |
Mckoi SQL |
org.hibernate.dialect.MckoiDialect |
Interbase |
org.hibernate.dialect.InterbaseDialect |
Pointbase |
org.hibernate.dialect.PointbaseDialect |
FrontBase |
org.hibernate.dialect.FrontbaseDialect |
Firebird |
org.hibernate.dialect.FirebirdDialect |
跟住繼續(xù)講 Student.hbm.xml 這個(gè)文件。這個(gè)文件是對(duì)數(shù)據(jù)庫(kù)的表的映射文件,我們用這個(gè)文件指出哪個(gè)類對(duì)應(yīng)著哪個(gè)表,而且還指出哪個(gè)類中的屬性對(duì)應(yīng)著表中的哪個(gè)字段。
文件的內(nèi)容是這樣的:
- xml version="1.0"?>
- PUBLIC"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
- <hibernate-mapping>
- <class name="src.Student" table="student">
- <id name="id" column="id">
- <generator class="increment"/>
- < SPAN>id>
- <property name="name" column="name"/>
- < SPAN>class>
- < SPAN>hibernate-mapping>
到此這個(gè)文件就結(jié)束了。特別說(shuō)一下這個(gè)id 的問(wèn)題。我們看到文件里面有個(gè)
這個(gè)文件解釋一下了
到這里這兩個(gè)特殊的文件就介始完了。下面就開(kāi)始講我們的 java 類了。主要有兩個(gè):一個(gè)是Pojo類,一個(gè)是我們的Test類。
Pojo類其實(shí)就是簡(jiǎn)單的一個(gè)javaBean。(Plain Old Java Objects, 簡(jiǎn)單潔凈Java對(duì)象)。看下面的代碼:
- package src;
- public class Student{
- private int id;
- private String name;
- public void setId(int id){
- this.id=id;
- }
- public void setName(String name){
- this.name=name;
- }
- public int getId(){
- return id;
- }
- public String getName(){
- return name;
- }
- }
就是這么簡(jiǎn)單的一個(gè)類。就是和數(shù)據(jù)庫(kù)的字段對(duì)應(yīng)然后取值的。
下面是我們關(guān)鍵的Test類:
- package src;
- import org.hibernate.*;
- import org.hibernate.cfg.*;
- public class Test{
- public static void main(String bb[]){
- try{
- SessionFactory sf=new Configuration().configure().BuildSessionFactory();
- Session s=sf.opension();
- Transaction ts=s.beginTransaction();
- for(int i=0;i<3;i++){
- Student st=new Student();
- st.setName("begin go "+ i);
- s.save(st);
- }
- ts.commit();
- s.close();
- }catch(Exception e){
- e.printStackTrace();
- }
- }
- }
這里的第一句 SessionFactory sf=new Configuration().configure().BuildSessionFactory(); 得到configuration的實(shí)例.這個(gè)開(kāi)始要和最前面的哪個(gè).cfg.xml對(duì)應(yīng)著看了。
我們?nèi)〉脤?shí)例,然后通過(guò)configure()讀取mapping對(duì)應(yīng)的.hbm.xml文件的信息。然后我們通過(guò)BuildSessionFactory得到SessionFactory對(duì)象,然后我們?cè)谕ㄟ^(guò)opensession() 建立連接 .Session 就是指一個(gè)session被建立。這個(gè)需要有servlet的基礎(chǔ)理解,這里等于是一個(gè)connection被建立好。
下面通過(guò)session對(duì)象開(kāi)啟事務(wù)(Transaction)這個(gè)相當(dāng)于conn.setAutoCommit(false);先不遞交最后通過(guò)另外一個(gè)方法遞交。我們看到下面我們循環(huán)里把咱們寫好的Student實(shí)例化了。既然實(shí)例化了我們就能用里面的方法了。
每次都要session來(lái)save一下。一個(gè)對(duì)象set之后要保存,很好理解吧,保存在了session中。最后遞交commit(); 這個(gè)方法實(shí)際上是實(shí)現(xiàn)了兩個(gè)作用
- conn.commit();
- conn.setAutoCommit(true);
這樣才能把我們的數(shù)據(jù)放進(jìn)數(shù)據(jù)庫(kù)中。 很奇怪沒(méi)有sql語(yǔ)句吧.最后提醒一下.想想hibernate的特性.我們對(duì)數(shù)據(jù)庫(kù)的操作就是對(duì)對(duì)象的操作.這就是OR-Mapping。呵呵,實(shí)例分析結(jié)束。
【編輯推薦】