1. 程式人生 > >Hibernate(ORMapping) 上手例項與配置過程

Hibernate(ORMapping) 上手例項與配置過程

利用一晚上的時間配置了一下Hibernate,做了一個簡單的demo練習實現對資料庫的增刪改查,接下來我一步步的分析並且會指出每一步大家該注意的地方。
首先引進jar包:

這裡寫圖片描述

接下來,我們來看一下目錄:

這裡寫圖片描述

好了,現在就開始我們的工作:
1 . 建立實體類User,和資料庫中的表有對應關係,實現每個屬性的get和set方法(有三個屬性),並實現可序列化。

package User;
import java.io.Serializable;

public class User implements Serializable {

    public User() {
        //預設的構造方法
} private Integer id; private String loginName; private String loginPwd; public String getLoginPwd() { return loginPwd; } public void setLoginPwd(String loginPwd) { this.loginPwd = loginPwd; } public String getLoginName() { return loginName; } public
void setLoginName(String loginName) { this.loginName = loginName; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } }

2.寫Hibernate的對映檔案,在這個檔案中寫資料庫表和實體類的對映關係。
以下是一個簡單的對映檔案的配置。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernat mapping DTD3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="com.hibtest1.entity.User" table="users" catalog="bookshop"> <id name="id" type="java.lang.Integer"> <column name = "Id"/><!-- 指定主鍵 --> <generator class = "native"></generator> <!-- generator用來指定主鍵的生成策略,常用值為native和assigned --> </id> <property name="loginName" type="java.lang.String"> <column name="LoginName" length="50"/> </property> <property name="loginPwd" type="java.lang.String"> <column name="LoginPwd" length="16"/> </property> </class> </hibernate-mapping> <!-- 是Hibernate的對映檔案,告知Hibernate框架實體類Users對映到資料庫中的哪個表,以及屬性和欄位的對應關係 --> <!-- 配置了從User實體類到資料庫users表的對映,每個class中配置一個實體類的對映資訊 -->

3.最後寫hibernate.cfg.xml,即hibernate的配置檔案,在這個檔案中寫連線資料庫的相關資訊和hibernate的引數,並將對映檔案載入進來。

<?xml version="1.0" encoding="UTF-8"?>
<!-- hibernate的配置檔案 -->
<!-- 需要配置連線資料庫的相關資訊和hibernate的引數 -->
<!-- 資料庫的相關資訊包括驅動,username,password,url等 -->
<!-- dialect引數必須配置,用來配置Hibernate使用的不同資料庫型別 -->
<!-- show_sql表示程式執行時在控制檯輸出執行的sql語句 -->
<!DOCTYPE hibernate-configution PUBLIC 
       "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
       "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

       <hibernate-configution>
       <session-factory>

           <property name="show_sql">true</property>
           <property name="eclipse.connection.profile">bookshop</property>
           <property name="connection.url">jdbc:mysql://localhost:3306/bookshop</property>
           <property name="connection.username">root</property>
           <property name="connection.password">12345</property>
           <property name="driver_class">com.mysql.jdbc.Driver</property>
           <property name="dialect">org.hibernate.dialect.MySQLDialect</property>

           <mapping resource="com.hibtest1/entity/User.hbm.xml"/>
    <!-- 宣告載入之前寫的資料庫和表的對映檔案User.hbm.xml -->   


       </session-factory>
       </hibernate-configution>

4.到此,所有準備工作已經做完,接下來我們要編寫測試類,實現向資料庫中新增資料,並且一起經歷整個Hibernate操作處理的過程。

(1) TestAdd.java

package User;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class TestAdd {

    public static void main(String[] args) {
        new TestAdd().addUser();
    }

    public void addUser() {
        //建立持久化物件,並賦初值(例項化實體類)
        User user = new User();
        user.setLoginName("huqianmenfg");
        user.setLoginPwd("12345");

        //初始化,讀取配置檔案hibernate.cfg.xml
        Configuration config = new Configuration().configure();
        //讀取建立sessionFactory
        SessionFactory sessionFactory = config.buildSessionFactory();
        //開啟session
        Session session = sessionFactory.openSession();
        //事務處理
        Transaction tx=null;
        try {
            //開始一個事務
            tx = session.beginTransaction();
            //持久化操作,儲存user物件資訊
            session.save(user);
            //提交事務
            tx.commit();
        } catch(Exception e) {
             if(tx != null) {
                 tx.rollback();
                 //回滾
             }
        } finally {
            session.close();
        }
    }
}
/*
 * 注意: 除了持久化物件的建立過程以及賦值過程之外,所有的操作步驟都是固定的,整個hibernate的處理過程就是這樣的
 * Hibernate的處理過程:讀取配置檔案,根據Configuration建立sessionFactory,用來生產session,接著就是生產session的過程。
 * 最後進行事務提交和處理的過程。事務提交的過程中,如果提交成功,則提交資料,否則回滾。
 * 
 * 需要注意的是:Session的save方法必須在事務環境中完成,並需要使用commit方法來提交事務,提交成功後資料才會被寫入資料庫。
 * */
執行最後的測試類,就可以實現將user使用者資料新增到資料庫中,方便簡單!!!

以上完成了用hibernate實現向資料庫中新增資料的過程,接下來我們來實現查詢、修改和刪除資料的過程。

(2)TestDelete.java

package User;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class TestDelete {

    public static void main(String[] args) {

    }
    private void testDelete() {
        //讀取配置檔案
        Configuration config = new Configuration();
        //建立sessionFactory
        SessionFactory sessionFactory = config.buildSessionFactory();
        //開啟session
        Session session = sessionFactory.openSession();
        Transaction tx = null;
        //載入要刪除的資料,和查詢的方法一樣(其實本質就是查詢到需要刪除的值,都用的是session.get());
        //也是根據主鍵進行查詢,方便後期的刪除過程。
        User user = (User)session.get(User.class, new Integer(1));
        //注意刪除的過程需要加事務處理和 try-catch 異常處理機制
        try {
            //開啟一個事務
            tx = session.beginTransaction();
            //進行刪除操作
            session.delete(user);
            //提交這個事務
            tx.commit();
        } catch(Exception e) {
            if(tx != null) {
                tx.rollback();//回滾
            }
            e.printStackTrace();
        } finally {
            session.close();//在 finally 中關閉 session
        }

    }
}
/*
 *注意: 實現刪除功能的方法都是private void 型別的方法。
 * */

(3) TestUpdate.java

package User;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class TestUpdate {

    public static void main(String[] args) {

    }

    private void testUpdate() {
        //載入配置檔案
        Configuration config = new Configuration();
        //建立sessionFactory
        SessionFactory sessionFactory = config.buildSessionFactory();
        //得到session
        Session session = sessionFactory.openSession();
        //得到需要修改的資料,根據主鍵查詢即可
        User user = (User)session.get(User.class, new Integer(2));
        Transaction tx = null;
        //直接在外部修改資料
        user.setLoginName("qianmenghu");
        //以下是事務處理
        try {
            //開啟事務
            tx = session.beginTransaction();
            //執行修改操作
            session.update(user);
            //提交事務
            tx.commit();
        } catch(Exception e) {
            if(tx != null) {
                tx.rollback();//出錯即回滾
            }
            e.printStackTrace();
        } finally {
            session.close();
        }

    }
}
/*
 * 注意:執行修改操作的時候需要在事務的外部修改資料。直接用user.set方法就可以實現。
 * 其他的步驟都和之前的操作一樣,修改也要進行事務處理
 * 除了查詢不需要進行事務處理之外,別的(新增、刪除、修改),只要是對資料有相應的改動的操作,都需要進行事務處理。
 * 獲取操作資料的方式都是相同的。
 * */

接下來是實現查詢的功能,查詢功能中不需要進行事務處理,直接根據主鍵查詢即可。

(4) TestLoad.java

package User;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

/*
 * 查詢功能:根據主鍵將一條資料從資料庫中查詢出來
 * */
public class TestLoad {

    public static void main(String[] args) {

    }
    private void testLoad() {
        //初始化,讀取配置檔案
        Configuration config = new Configuration().configure();
        //開啟sessionFactory
        SessionFactory sessionFactory = config.buildSessionFactory();
        //建立session
        Session session = sessionFactory.openSession();
        //載入資料
        User user = (User)session.get(User.class, new Integer(1));
        //在控制檯輸出使用者名稱和密碼
        System.out.println(user.getLoginName()+" "+user.getLoginPwd());
    }
}
/*
 * 注意: 查詢過程中,直接讀取配置檔案,開啟sessionFactory,建立session即可。
 * 建立完session之後就可以根據主鍵查詢資料,採用session.get(User.class, new Integer(1))
 * 查詢過程中不需要事務處理過程,只有在修改或者新增資料的過程中才需要進行事務處理。
 * 還有就是session.get()的第一個引數是通過反射得到user物件的所有屬性值,get方法調完之後就可以在控制檯顯示屬性的資訊。
 */

以上就是按照順序實現增刪改查的功能的過程和實現,我們可以發現,hibernate已經為我們封裝好了這幾種操作的介面,我們直接用session呼叫介面即可,只需要一句話就能完成增刪改查操作,而不是像以前一樣需要寫sql語句自己完成增刪改查過程。極大的簡化了程式設計師的編碼工作。

接下來是福利:(哈哈哈哈—)

我們可以在 eclipse中自動新增hibernate支援(通過配置直接新增),從而可以自動生成hibernate實體類和hibernate配置檔案,配置完資料庫的相關資訊之後還可以直接生成對映檔案。

1 . 我們自己實現的過程中,在測試類中需要讀取配置資訊,讀取解析對映資訊,建立session工廠最終生成session例項,最後呼叫session介面的方法實現增刪改查操作。
2 . 但是當我們利用eclipse自動新增hibernate支援的時候,會自動建立工廠,我們只需要建立session例項即可。
3 . 接下來,我們在2的基礎上,直接寫一個BaseHibernateDao類,將資料的增刪改查方法都寫進去。
4 .寫介面,寫實現,實現繼承BaseHibernateDao類,調方法實現功能。

(1)BaseHibernate.java

package User;

public interface BaseHibernate {
    public  void add(User user);
    public User get(Integer id);
    public void delete(User user);
    public void update(User user);
}

(2)BaseHibernateImpl.java

package User;

public class BaseHibernateImpl extends BaseHibernateDao implements BaseHibernate {

    @Override
    public void add(User user) {

        super.add(user);
    }

    @Override
    public User get(Integer id) {
        return (User)super.get(User.class, id);
    }

    @Override
    public void delete(User user) {

        super.delete(user);
    }

    @Override
    public void update(User user) {

        super.update(user);
    }

}

(3)BaseHibernateDao.java

package User;

import java.io.Serializable;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

//是一個抽象類,抽象類的作用?為什麼要寫成抽象類?
public abstract class BaseHibernateDao {

    /* 新增資料 */
    // protected型別,無返回值,引數是 Object 型別(傳進來user物件)
    protected void add(Object object) {
        Transaction tran = null;
        // 獲取session
        // 如果eclipse自動建立一個HibernateSessionFactory的話,這裡可以直接用
        // 即 Session session = HibernateSessionFactory.getSession();

        //常規方法獲取session
        Configuration config = new Configuration().configure();
        SessionFactory sessionFactory = config.buildSessionFactory();
        Session session = sessionFactory.openSession();

        //事務處理
        try {
            tran = session.beginTransaction();
            session.save(object);
            tran.commit();
        } catch(Exception e) {
            if(tran != null) {
                tran.rollback();//回滾
            }
            e.printStackTrace();
        } finally {
            session.close();
        }
    }

    //新增沒有返回值,但是查詢有返回值,返回值型別是Object,引數型別是按照id升序排列的所有物件
    protected Object get(Class cla, Serializable id) {
        Object object = null;
        Configuration config = new Configuration().configure();
        SessionFactory sessionFactory = config.buildSessionFactory();
        Session session = sessionFactory.openSession();
        try {
            object = session.get(cla, id);
        } catch(Exception e) {
            e.printStackTrace();
        } finally {
            session.close();
        }
        return object;
    }

    //刪除資料,沒有返回值
    protected void delete(Object object) {
        Transaction tran = null;
        Configuration config = new Configuration().configure();
        SessionFactory sessionFactory = config.buildSessionFactory();
        Session session = sessionFactory.openSession();
        try {
            tran = session.beginTransaction();
            session.delete(object);
            tran.commit();
        } catch(Exception e) {
            if(tran != null) {
                tran.rollback();
            }
            e.printStackTrace();
        } finally {
            session.close();
        }
    }

    //修改資料,無返回值
    protected void update(Object object) {
        Transaction tran = null;
        Configuration configuration = new Configuration().configure();
        SessionFactory sessionFactory = configuration.buildSessionFactory();
        Session session = sessionFactory.openSession();

        try {
            tran = session.beginTransaction();
            session.update(object);
            tran.commit();
        } catch(Exception e) {
            if(tran != null) {
                tran.rollback();
            }
            e.printStackTrace();
        } finally {
            session.close();
        }
    }
}
//在這個類中,實現了增刪改查四種方法,我們為了方便呼叫,寫一個介面,然後寫一個實現類去實現這個介面,
//在實現類中繼承本類,利用本類中的方法去實現功能。此後操作的時候就直接呼叫介面就可以實現增刪改查的功能。

至此,eclipse自動新增hibernate的支援,完整實現對資料的增刪改查。我們的工作就先告一段落!
待更!!!