2015年6月30日 星期二

簡易Hibernate入門(NetBeans+Servlet+MySQL)

Hibernate是一個基於資料庫物件化的一個框架(framework),它將資料庫裡的表格(Table)中的每一行紀錄實做成一個Java Bean型式的類別,而其中的屬性對應到了紀錄中的每欄位(Column),且擁有各自的Getter與Setter方法。

利用Hibernate我們可以以物件化的方式操控Database及以物件的方式得到查詢結果。在這裡我們要實作一個簡單的使用了Hibernate的Servlet,利用NetBeans的功能,可以使我們容易地實作Hibernate的許多細節。

一、在這邊我們使用MySQL作為我們的資料庫。首先先在MySQL中建立一個名為guest_database的資料庫,其中建立一個名為guest_list的Table,有三個欄位,分別是id、name、age、birth_date,tyep分別是varchar、varchar、int、date。我們先加入幾條紀錄,如下圖所示:


二、接下來我們要在NetBeans中建立資料庫的連接,在NetBeans中選擇Services面板-->Databases(按右鍵)-->New Connection,

在Driver下拉表中選擇MySQL,並輸入想要連接的資料庫資訊,如下圖:
接著的Database Scheme可以跳過,到如下圖頁面可看到Input connection name中的值,非常類似JDBC的DriverManager.getConnection()方法中要當輸入參數的值,按下Finish後建立資料庫連接。

三、接著我們創建一個新的Java Web Application,在framework選擇頁面中選用Hibernate,並選擇剛剛建立的資料庫連接,

四、建立好Java Web專案後,可以看到有一個hibernate.cfg.xml檔,就是Hibernate的配置檔,裡面有關於資料庫連接的各種設定,為了session可以正常運作,記得在其中加上一行
<property name="hibernate.current_session_context_class">thread</property>
接著我們創建一個名為guestDatabaseFunction的Package,並在裡面建立一個HibernateUtil,可利用NetBeans的功能建立,其中包含了可獲取SessionFactory的getSessionFactory()方法。
五、接下來我們利用NetBeans幫我們創建一個Hibernate Reverse Engineering Wizard,名稱就叫hibernate.reveng
在以下頁面中,在Configuration File選擇Hibernate配置文件(hibernate.cfg.xml),成功讀取到資料庫後,在Available Tables中會出現其中的Table,選取要使用的Table並按Add鈕將其移到Selected Tables中(如果在Available Tables找不到Table,可能是hibernate.cfg.xml內容有誤,或是把資料庫重新連接即可),這樣就會創建一個hibernate.reveng.xml文件,其中描述了要用的資料庫即Table。

六、接下來,我們要利用NetBeans在guestDatabaseFunction創建一個Hibernate Mapping Files and POJOs from Database,
其中會用到之前建立過的hibernate.cfg.xml(含Database連接訊息)和hibernate.reveng.xml(含Database與Table訊息)。

按下Finish後,我們可以看到在guestDatabaseFunction套件中多了幾個檔案,GuestList.hbm.xml中包含了資料表(Table)與物件類別(GuestList)的對應關係,它將Table中的每一個欄位對應到GuestList的每個屬性。
而GuestList中包含了對每個屬性的Getter與Setter方法。


七、現在我們基本都已經建立完成了,可以對hibernate.cfg.xml按右鍵並選擇Run HQL Query開始HQL(Hibernate Query Language)界面來練習HQL的查詢語法並確認資料庫連接,

例如試著打上 "from GuestList",即可在Result中看到Table中的紀錄,要注意的是HQL並不等於SQL,其中GuestList不是Table的名稱,而是物件化的物件名稱,即GuestList.java。

八、現在試著建立一個名為GuestDatabaseHelper類別,用來方便開啟Session及查詢,其中自行撰寫內容如下,包括了利用HibernateUtil的getSessionFactory()方法取得sessionFactory再取得session,和使用id來篩選紀錄的getGuestByID_Using_HQL()、getGuestByID_Using_Criteria()查詢方法,這兩個查方法作用一樣,但是一個是使用HQL語法進行查詢、一個是使用Criteria的方式進行查詢(HQL及Criteria可參考 開源框架:Hibernate Gossip):
package guestDatabaseFunction;

import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;

public class GuestDatabaseHelper {

    //使用HQL語法進行查詢的方法
    public List getGuestByID_Using_HQL(String id) {
        Session session = null;
        List<GuestList> list = null;
        try {
            //session = HibernateUtil.getSessionFactory().getCurrentSession();
            session = HibernateUtil.getSessionFactory().openSession();
            org.hibernate.Transaction tx = session.beginTransaction();
            Query q = session.createQuery("from GuestList where id='" + id + "'");
            list = (List<GuestList>) q.list();

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (session != null && session.isOpen()) {
                session.close();
            }
        }
        return list;
    }

    //使用Criteria方式進行查詢的方法
    public List getGuestByID_Using_Criteria(String id) {
        Session session = null;
        List<GuestList> list = null;
        try {
            //session = HibernateUtil.getSessionFactory().getCurrentSession();
            session = HibernateUtil.getSessionFactory().openSession();
            org.hibernate.Transaction tx = session.beginTransaction();
            Criteria criteria = session.createCriteria(GuestList.class);
            criteria.add(Restrictions.eq("id", id));
            list = (List<GuestList>) criteria.list();

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (session != null && session.isOpen()) {
                session.close();
            }
        }
        return list;
    }
}

九、最後我們利用一個Servlet來驗證結果,建立一個Servlet並在processRequest()中加入以下內容:
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");

        //使用HQL語法進行查詢的方法
        //GuestDatabaseHelper guestDatabaseHelper = new GuestDatabaseHelper();
        //List<GuestList> guestInfoList = guestDatabaseHelper.getGuestByID_Using_HQL("1");
                
        //使用Criteria方式進行查詢的方法
        GuestDatabaseHelper guestDatabaseHelper = new GuestDatabaseHelper();
        List<GuestList> guestInfoList = guestDatabaseHelper.getGuestByID_Using_Criteria("3");
        
        try (PrintWriter out = response.getWriter()) {
            /* TODO output your page here. You may use following sample code. */
            out.println("<!DOCTYPE html>");
            out.println("<html>");
            out.println("<head>");
            out.println("<title>使用Hibernate進行查詢之Servlet</title>");
            out.println("</head>");
            out.println("<body>");
            out.println("<h1>查詢如下</h1>");
            for (GuestList guestInfo : guestInfoList) {
                out.println("<h1>Id: " + guestInfo.getId() + "</h1>");
                out.println("<h1>Name: " + guestInfo.getName() + "</h1>");
                out.println("<h1>Age: " + guestInfo.getAge() + "</h1>");
                out.println("<h1>BirthDate: " + guestInfo.getBirthDate() + "</h1>");
            }
            out.println("</body>");
            out.println("</html>");
        }
    }

一開始使用HQL的查詢方式,執行或佈署這個Web專案並進入上述的Servlet後,應該可以在畫面上看到id為1的紀錄被篩選並顯示在網頁畫面上,如下圖:

如果選用Criteria的查詢方式,則結果畫面應為下圖:


附上源始碼:

沒有留言 :

張貼留言