初識Hibernate

來源:互聯網
上載者:User

標籤:分享   理解   興趣   cat   window   config   標籤   ber   開啟   

1.問題

這兩天弄一個項目,串連了mysql。第一天訪問資料庫沒問題,第二天就報錯,異常如下:

Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

這裡只摘取一段,很是頭疼。去網上查,大多是說mysql的wait_timeout預設為8小時,mysql資料庫中是28800s。如果在wait_timeout秒期間內,資料庫連接一直處於等待狀態,那麼mysql就將該串連關閉,這時你的java應用的串連池仍然合法的持有該串連的引用。所以你第二天操作資料時,會報錯。

2.解決

一開始按照網上的思路是更改mysql資料庫的wait_timeout欄位,最大值是24天/365天(windows/linux)。或者改mysql的設定檔——my.ini/my.cnf(windows/linux)。可是後來想了想,這樣過一段時間又會報錯,該怎麼解決呢。於是後決定試試看hibernate,看看通過這個架構還會導致問題出現嗎

3.Hibernate配置

首先引入jar:

少一個基本會出現各種各樣的問題,mysql-connector千萬記得。

接著在src目錄下寫設定檔:hibernate.cfg.xml

這裡要注意url裡面的值,useUnicode=true&

它與jdbc的寫法不同,他需要用& 代替;  不然會報錯。

接著我們建個包,在這個包裡面寫個pojo對應資料庫欄位。同時還要寫個對應pojo的映射xml:

user類沒什麼好說的,跟自己資料庫欄位對應即可

這個xml具體配置如下:

class標籤下面name對應的是pojo,table是表名。

id是映射的唯一標識,也就是表中的主鍵。要注意的是<generator>標籤裡的class屬性。我這裡寫的assigned,意思是使用者自訂id,即給定一個id

還有其他6個屬性,感興趣的可以百度,這裡就不做介紹了。

4.寫一個Util類擷取Session

package com.hibernate.DBUtil;import org.hibernate.HibernateException;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.cfg.Configuration;public class HibernateUtil {    private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();    private static SessionFactory sessionFactory = null; // SessionFactory對象    static {        try {            Configuration cfg = new Configuration().configure(); // 載入Hibernate設定檔              sessionFactory = cfg.buildSessionFactory();        } catch (Exception e) {            System.err.println("建立會話工廠失敗");            e.printStackTrace();        }    }    // 擷取Session    public static Session getSession() throws HibernateException {        Session session = (Session) threadLocal.get();        if (session == null || !session.isOpen()) {            if (sessionFactory == null) {                rebuildSessionFactory();            }            session = (sessionFactory != null) ? sessionFactory.openSession() : null;            threadLocal.set(session);        }        return session;    }    /**     * 重建會話工廠     */    public static void rebuildSessionFactory() {        try {            Configuration cfg = new Configuration().configure(); // 載入Hibernate設定檔              sessionFactory = cfg.buildSessionFactory();        } catch (Exception e) {            System.err.println("建立會話工廠失敗");            e.printStackTrace();        }    }    // 擷取SessionFactory對象    public static SessionFactory getSessionFactory() {        return sessionFactory;    }    // 關閉Session    public static void closeSession() throws HibernateException {        Session session = (Session) threadLocal.get();        threadLocal.set(null);        if (session != null) {            session.close(); // 關閉Session        }    }}

這裡有必要說一下ThreadLocal。因為session是線程不安全的,為瞭解決並發的問題,防止資料汙染,我們在建立session時把她放進ThreadLocal裡,這是一個新思路。並不像之前的加synchronized,要程式員自己在各個不同的地方加,這樣會顯的很煩亂。具體ThreadLocal介紹這裡貼一個部落格,個人覺得理解的很到位:http://blog.csdn.net/lufeng20/article/details/24314381  ThreadLocal源碼內的情況也確實如他所說。

5.CRUD

上面配置好了hibernate,下面來寫一些方法來操作資料庫

具體方法如下:

package com.hibernate.DBUtil;import org.hibernate.Session;import com.hibernate.Entity.User;public class HibernateORM {    private HibernateUtil hibernateinit = null;    private Session session = null;    public void insert(Object obj) {        // Hibernate的持久化操作        try {            session = hibernateinit.getSession(); // 擷取session            session.beginTransaction(); // 開啟事務            session.save(obj); // 執行資料庫添加操作            session.getTransaction().commit();// 事務提交            System.out.println("資料添加成功");        } catch (Exception e) {            session.getTransaction().rollback();            System.out.println("資料添加失敗");            e.printStackTrace();        } finally {            hibernateinit.closeSession();        }    }    //get方法是在不確定資料庫是否存在該資訊的情況下擷取detail    public void getDetail() {        try {            session = hibernateinit.getSession();            User user = (User) session.get(User.class, new Integer("4"));            System.out.println("使用者ID:" + user.getId() + ",使用者姓名:" + user.getName());            System.out.println("第一次裝載對象");            User user2 = (User) session.get(User.class, new Integer("4"));            System.out.println("第二次裝載對象");        } catch (Exception e) {            System.out.println("get()方法對象裝載失敗!");            e.printStackTrace();        } finally {            hibernateinit.closeSession();        }    }        //load方法是在給定ID的情況下擷取detail    public void loadDetail(){        try {            session = hibernateinit.getSession();            User user = new User();            session.load(user, new Integer("1"));   //裝載對象            System.out.println("使用者ID:" + user.getId() + ",使用者姓名:" + user.getName());        } catch (Exception e) {            System.out.println("load()方法對象裝載失敗!");            e.printStackTrace();        }finally {            hibernateinit.closeSession();        }    }        public void delete(){        try {            session = hibernateinit.getSession();            session.beginTransaction();            User user = (User)session.get(User.class, new Integer("3"));            session.delete(user);            session.flush();            session.getTransaction().commit();            System.out.println("對象刪除成功!");        } catch (Exception e) {            session.getTransaction().rollback();            System.out.println("對象刪除失敗!");            e.printStackTrace();        }finally {            hibernateinit.closeSession();        }            }        public void update(){        try {            session = hibernateinit.getSession();            session.beginTransaction();            User user = (User) session.get(User.class, new Integer("4"));            user.setName("233");            session.flush();            session.getTransaction().commit();            System.out.println("對象修改成功");        } catch (Exception e) {            session.getTransaction().rollback();            System.out.println("對象修改失敗");            e.printStackTrace();        }finally {            hibernateinit.closeSession();        }    }    }

簡單的寫了一下,這裡要注意,在增刪改這些操作上,要加事務,不然會報一個Transaction的錯誤。

最後寫一個test測試一下:

自己試了裡面一些方法,發現控制台輸出了SQL語句和執行結果:

確實和資料庫能對應起來,CRUD操作也都沒有問題。

6.昨天寫好這些東西後,對資料庫操作了一番發現沒有問題,今天看看會不會出現通過JDBC操作mysql的wait_timeout問題。結果沒有出現,這個方法應該可以不通過修改mysql資料庫從而解決。下面還要進行長時間觀察,看看有沒有這個問題,這裡先做一個記錄。

初識Hibernate

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.