手動配置hibernate的全過程

主流的數據庫是關係型數據庫,而編程的思想是面向對象的,如何將對象存儲到關係型的數據庫中,消除對象—>關係的阻抗,ORM(Object Relation Model)對象關係模型就出現了,而hibernate就是基於ORM的框架.下面我來聊聊hibernate的手動配置過程.
配置環境:eclipse,mysql數據庫,hibernate的jar包和連接mysql數據庫用的jar包.
配置前提:在mysql數據庫中,名字爲sqdb3的數據庫,有一個叫employee的表.表的字段創建入下:

use spdb3;
create table employee(
    id int PRIMARY key auto_increment,
    username varchar(64) not null,
    email varchar(64) not null,
    hiredate date not null
);

employee表裏面的內容自己可以隨意添加.

配置的思想是先建立一個POJO對象,配置Employee.hbm.xml文件,最後配置hibernate.cfg.xml文件.先展示一下各個文件所在的位置.]
①先解釋一下POJO的作用,它是一個類(對象類),它所用擁有的屬性對應的是表中的字段,方法是set/get屬性.用來映射employee.Employee.java的代碼如下:

package com.hsp.domain;
import java.util.*;
import java.io.*;
//建議我們的domain對象的名稱就是對應
//表的首字母大寫,domain對象/javaBean/pojo
//該pojo按規範應當序列化,目的是可以唯一的標識該對象,同時可以在網絡和文件上傳輸
public class Employee implements Serializable{
    static final long serialVersionUID=1L;
    private Integer id;
    private String username;
    private String email;
    private Date hiredate;
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public Date getHiredate() {
        return hiredate;
    }
    public void setHiredate(Date hiredate) {
        this.hiredate = hiredate;
    } 
}

②在與POJO同一個目錄下的Employee.hbm.xml文件其實是一個對象關係映射文件.內容如下:

<?xml version="1.0" encoding="utf-8"?>
<!-- 映射文件需要一個dtd -->
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- 該文件用於配置domain對象和表的映射關係 -->
<hibernate-mapping package="com.hsp.domain">
    <class name="Employee" lazy="true" table="employee">
        <!-- id元素用於指定主鍵屬性 -->
        <!-- mysql的數據庫表 id 主鍵對於設置自增長 -->
        <id name="id" type="java.lang.Integer">
            <column name="id"/>
            <generator class="identity"/>
        </id>
        <!-- 對其他屬性還有配置 -->
        <property name="username" type="java.lang.String">
            <column name="username" not-null="false" />
        </property>
        <property name="email" type="java.lang.String">
            <column name="email" not-null="false"></column>
        </property>
        <property name="hiredate" type="java.util.Date">
            <column name="hiredate" not-null="false"></column>
        </property>
    </class>
</hibernate-mapping>

讓我來簡單解釋一下這個Employee.hbm.xml文件的內容,

<hibernate-mapping package="com.hsp.domain">
    <class name="Employee" lazy="true" table="employee">

這個是將對象類(Employee)和表(employee)對應起來,其中lazy表示的是懶加載,這個作用之後在解釋.

<id name="id" type="java.lang.Integer">
            <column name="id"/>
            <generator class="identity"/>
        </id>

id這個字段是用來唯一表示表中的主鍵的屬性,name表示的其實就是Employee.java中的屬性,type表示它的類型,column對應的是表中的那個字段.<generator class="identity"/>表示這個主鍵是自增長的.

③下面重頭戲閃亮登場.hibernate.cfg.xml文件
內容如下:

<?xml version='1.0' encoding='utf-8'?>  
<!DOCTYPE hibernate-configuration PUBLIC  
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"  
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">  
<hibernate-configuration>
    <session-factory name="mySessionFactory">
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/spdb3</property>
        <property name="hibernate.connection.username">root</property>
        <property name="connection.password">root</property>
        <!-- dialect翻譯爲方言 Hibernate根據你選擇的“方言”,針對每種數據庫,作調整,如生成不同的SQL語句等 -->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        <!-- 連接池默認配置.提供對數據庫操作速度 -->
        <property name="connection.pool_size">2</property>
        <!-- 自動創建|更新|驗證數據庫表結構。如果不是此方面的需求建議set value="none" -->
        <property name="hibernate.hbm2ddl.auto">update</property>
        <!-- 是否要在後臺.演示翻譯sql 語句 -->
        <property name="show_sql">true</property>
       <!-- 按照格式化的形式輸出 -->
       <property name="format_sql">true</property>
        <!-- 配置可以使用getCurrentSession 
        <property name="current_session_context_class">thread</property>
        -->
        <!-- //與實體類連接 -->
        <mapping resource="com/hsp/domain/Employee.hbm.xml" />
    </session-factory>
</hibernate-configuration>

這個文件的作用其實就是配置你所使用的數據庫,url,user,passwd,方言等.在這個文件中的參數有很多,我所瞭解的只是皮毛,大家可以看看代碼中的註釋.

④我自己還寫了一個獲得直接獲得Session的靜態的方法.HibernateUtil.java.內容如下

package com.hsp.util;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

final public class HibernateUtil {
    private static SessionFactory sessionFactory=null;
    //使用線程局部模式
    private static ThreadLocal<Session> threadLocal=new ThreadLocal<Session>();
    //私有的構造函數
    private HibernateUtil() {};
    static {
        sessionFactory=new Configuration().configure("com/hsp/config/hibernate.cfg.xml").buildSessionFactory();
    }
    //獲取全新的session
    public static Session openSession() {
        return sessionFactory.openSession();
    }
    //獲取和線程關聯的session
    public static Session getCurrentSession() {
        Session session=threadLocal.get();
        //判斷是否得到
        if(session==null) {
            session=sessionFactory.openSession();
            //把session對象設置到threadLocal,相當於該session已經和線程綁定
            threadLocal.set(session);
        }
        return session;
    }
}

在這個類中有兩個靜態的方法,其中openSession()方法是直接獲得一個session,getCurrentSession()方法是獲得一個線程安全的session(有利於事務的處理).他們之間的具體差別我就不詳細解釋了.
⑤.下面就是一個Test.java這個的作用就是來驗證是否可以用hibernate框架來進行crud操作

package com.hsp.util;

import java.util.Date;
import java.util.List;
import com.hsp.util.*;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.*;
import com.hsp.domain.Employee;

public class TestMain {
    public static void main(String[] args) {
        //獲取session
        Session session =HibernateUtil.getCurrentSession();
        //事務
        Transaction ts = null;
        try {
            //事務處理
            ts = session.beginTransaction();
            // do...
            Employee emp = (Employee) session.load(Employee.class, 1);
            //修改id爲1的username
            emp.setUsername("dddd");
            // ....doing
            //事務提交
            ts.commit();
        } catch (Exception e) {
            //如果出錯,回滾數據
            if (ts != null) {
                ts.rollback();
            }
            throw new RuntimeException(e.getMessage());
        } finally {
            // 關閉session
            if (session != null && session.isOpen()) {
                session.close();
            }
        }

    }
}

ok,在這裏給初學者普及一下事務這個概念.比如銀行轉轉,你從農行的一個賬戶中向工行的一個賬戶轉錢,其業務是這樣的,農行賬戶的錢減去100,工行賬戶的錢加100,這需要操作數據庫,將減錢和加錢的操作同時進行完成.不能減錢完成,加錢沒完成或反之這就需要事務了.它將這兩操作包裹成原子操作.要麼做完,要麼不做.當只是執行其中一個的時候,就回滾(相當於不做).

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章