Hibernate——配置並訪問數據庫


  Hibernate,對於java來說很重要的一個東西,用於持久層。之前看了很多配置的,都不行,自己來寫一個配置成功的。

  環境:jdk1.8,eclipse-jee-oxygen,mysql-connector-java-5.1.46,hibernate 5.2.

  首先要確保你的jdk,eclipse和mysql裝好。然后下載jar包,mysql和hibernate的jar包。

   然后安裝JBoss插件,eclipse中Help-----eclipse market里面輸入JBoss並搜索,找到JBoss之后,install,這里只需要對應hibernate的那些即可。

  

  

  Confirm之后,accept,安裝即可。

 

 

  先簡單敘述一下開發流程,后面有詳細地說明每一步在干什么以及為什么要這么做。

  1.准備開發環境,數據庫中創建數據庫及表。

  2.創建持久化類

  3.設計映射文件,也就是利用hibernate講POJO映射到數據庫。

  4.創建hibernate配置文件Hibernate.cfg.xml。

  5.編寫輔助工具HibernateUtil類,用來實現對Hibernate的初始化並提供獲得Session的方法,這一步是我們這次需要的,具體要看你的項目是否需要。

  6.編寫DAO層。

  7.編寫Service層。

  8.編寫測試類,並用Junit測試。

 

  先上一張完整的目錄:

  

 

  1.創建項目

創建Dynamic Web Project項目,命名為MyHibernate,在項目上右鍵,New---Other,在里面找Hibernate,選擇Hibernate Configuration File(cfg.xml)。

  

點擊Next按鈕,在彈出的對話框中選擇配置文件保存的目錄,一般默認在src目錄,同時需要輸入配置文件的名稱,一般默認為hibernate.cfg.xml即可。繼續Next,在彈出的對話框中填寫數據庫方言(Database dialect)、數據庫驅動(Driver class)、數據庫URL、用戶名、密碼等。MySQL數據庫的配置如下:

單擊Finish,配置文件就創建成功了,后面有需要可以繼續編輯該文件。

 

  2.創建數據庫及表。

  在MySQL中創建一個名為mysqldb的數據庫,在該數據庫中創建一張名為USER的表。創建USER表的語句如下:

create table user(
id int(11),
name varchar(20),
password varchar(12),
type varchar(6),
primary key(id));

 

  3.編寫POJO映射類User.java

  

package org.hibernate.entity;  
  
public class User {  
  
    private int id;//持久化類的標識屬性,映射到數據表中的主鍵列  
    private String name;  
    private String password;  
    private String type;  
    public User() {  
        // TODO Auto-generated constructor stub  
    }  
    public int getId() {  
        return id;  
    }  
    public void setId(int id) {  
        this.id = id;  
    }  
    public String getName() {  
        return name;  
    }  
    public void setName(String name) {  
        this.name = name;  
    }  
    public String getPassword() {  
        return password;  
    }  
    public void setPassword(String password) {  
        this.password = password;  
    }  
    public String getType() {  
        return type;  
    }  
    public void setType(String type) {  
        this.type = type;  
    }  
      
}  

 

  4.編寫映射文件User.hbm.xml

  這一步可以通過設置直接生成。右鍵org.hibernate.entity包,new----other,找到hibernate,選擇生成hbm.xml。這里只選擇自己需要的POJO類生成hbm.xml。

生成之后的內容:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2018-3-16 9:16:18 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
    <class name="org.hibernate.entity.User" table="USER">
        <id name="id" type="int">
            <column name="ID" />
            <generator class="assigned" />
        </id>
        <property name="name" type="java.lang.String">
            <column name="NAME" />
        </property>
        <property name="password" type="java.lang.String">
            <column name="PASSWORD" />
        </property>
        <property name="type" type="java.lang.String">
            <column name="TYPE" />
        </property>
    </class>
</hibernate-mapping>

 

5.編寫hibernate.cfg.xml文件

  剛才新建了一個xml文件,里面有一些配置,現在需要增加一些內容。更改之后的內容:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.password">314159</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/mysqldb</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        
        <property name="hibernate.hbm2ddl.auto">update</property>  
        <!-- 在控制台輸出運行時生成的SQL語句,方便調試 -->  
        <property name="show_sql">true</property>  
        <!-- 連接池大小 -->  
        <property name="connection.pool_size">1</property>  
        <!-- 列出所有映射文件 -->  
        <mapping resource="org/hibernate/entity/User.hbm.xml" />  
    </session-factory>
</hibernate-configuration>

 

6.編寫輔助工具類HibernateUtil.java

package org.hibernate.entity;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;

public class HibernateUtil {

    private static SessionFactory sessionFactory;
    // 創建線程局部變量threadLocal,用來保存Hibernate的Session
    private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
    // 使用靜態代碼塊初始化Hibernate
    static {
        try {
            // 讀取配置文件方式1,hibernate4.3之前 //            Configuration cfg = new Configuration().configure();
//            // 創建服務注冊對象
//            StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
//                    .applySettings(cfg.getProperties()).build();
//            // 創建會話工廠對象SessionFactory
//            sessionFactory = cfg.buildSessionFactory(serviceRegistry);
//            
            // 讀取配置文件方式2,hibernate4.3之后
            ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().configure("/hibernate.cfg.xml").build();
            //創建會話工廠對象
            sessionFactory = new MetadataSources(serviceRegistry).buildMetadata().buildSessionFactory();
        } catch (Throwable ex) {
            throw new ExceptionInInitializerError(ex);
        }
    }

    // 獲得SessionFactory的實例
    public static SessionFactory getsSessionFactory() {
        return sessionFactory;
    }

    // 獲得ThreadLocal對象管理的Session
    public static Session getsSession() throws HibernateException {
        Session session = (Session) threadLocal.get();
        if (session == null || !session.isOpen()) {
            if (sessionFactory == null) {
                rebuildSessionFactory();
            }
            // 通過SessionFactory對象創建Session對象
            session = (sessionFactory != null) ? sessionFactory.openSession() : null;
            // 將Session對象保存到線程局部變量threadLocal中
            threadLocal.set(session);
        }
        return session;
    }

    // 關閉Session實例
    public static void closeSession() {
        // 從線程局部變量threadLocal中獲取之前存入的Session實例
        Session session = (Session) threadLocal.get();
        threadLocal.set(null);
        if (session != null) {
            session.close();
        }
    }

    // 重建SessionFactory
    public static void rebuildSessionFactory() {
        Configuration configuration = new Configuration();  
        configuration.configure("/hibernate.cfg.xml");
        StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
                .applySettings(configuration.getProperties()).build();
        sessionFactory = configuration.buildSessionFactory(serviceRegistry);
    }

    // 關閉緩存和連接池
    public static void shutdown() {
        getsSessionFactory().close();
    }
}

這里面有一個地方要注意,就是上面的紅色注釋,創建SessionFactory的方式因為hibernate版本有點不一樣,如果選擇了不適合的版本,在后面Junit測試的時候,會報“org.hibernate.MappingException: Unknown entity:XXXXXXXXXXXXXXX"的錯。

7.編寫DAO層接口UserDAO.java

package org.hibernate.dao;

import java.util.List;

import org.hibernate.entity.User;

public interface UserDAO {

    public void save(User user);

    public User findByIdGet(int id);

    public User findByIdLoad(int id);

    public List<User>  findByHQL(String hql);

    public void delete(User user);

    public void update(User user);
}

 

8.編寫DAO層實現類UserDAOImpl

package org.hibernate.dao;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.entity.HibernateUtil;
import org.hibernate.entity.User;


public class UserDAOImpl implements UserDAO {

    // 添加用戶,需要事務管理
    @Override
    public void save(User user) {
        // 創建Session實例
        Session session = HibernateUtil.getsSession();
        // 創建Transaction實例
        Transaction tx = session.beginTransaction();

        try {
            // 使用Session的save方法將持久化對象保存到數據庫
            session.save(user);
            // 提交事務
            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
            // 出現異常,回滾事務
            tx.rollback();
        } finally {
            // 關閉Session連接
            HibernateUtil.closeSession();
        }

    }

    // 根據id查找用戶 ,可以不需要事務管理 Get方式
    @Override
    public User findByIdGet(int id) {
        User user = null;
        Session session = HibernateUtil.getsSession();
        // 使用session的get方法獲取指定id的用戶
        user = (User) session.get(User.class, id);
        if (user == null || "".equals(user)) {
            System.out.println("查詢id為:" + id + "無結果....");
        }
        session.close();
        return user;
    }

    // 根據id查找用戶 ,可以不需要事務管理 Load方式
    @Override
    public User findByIdLoad(int id) {
        User user = null;
        Session session = HibernateUtil.getsSession();
        // 使用session的方法獲取指定id的用戶
        user = (User) session.load(User.class, id);
        if (user == null || "".equals(user)) {
            System.out.println("查詢id為:" + id + "無結果....");
        }
        session.close();
        return user;
    }

    // 根據HQl語句查詢
    @Override
    public List<User> findByHQL(String hql) {
        List<User> list = new ArrayList<>();
        Session session = HibernateUtil.getsSession();
        list = session.createQuery(hql).list();
        session.close();
        return list;
    }

    // 刪除用戶 ,需要事務管理
    @Override
    public void delete(User user) {
        Session session = HibernateUtil.getsSession();
        Transaction tx = session.beginTransaction();
        try {
            session.delete(user);
            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        } finally {
            HibernateUtil.closeSession();
        }
    }

    // 修改用戶
    @Override
    public void update(User user) {
        Session session = HibernateUtil.getsSession();
        Transaction tx = session.beginTransaction();
        try {
            session.update(user);
            tx.commit();
        } catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        } finally {
            HibernateUtil.closeSession();
        }
    }
}

 到這里整個Hibernate項目就完成了,下面需要的是測試。

 

9.編寫測試類UserTest.java

這里用Junit測試,如果沒有導入Junit的要先導入。在HibernateDemo項目名稱上右擊,選擇Properties,在彈出的窗口左側選擇Java Build Path選項,然后在右側界面中選擇Libraries標簽,點擊Add Library按鈕,在彈出的窗口中選擇Junit,如下圖所示。

然后點擊Next,在version一欄選擇Junit 4,然后點擊Finish。這樣Junit包就引入到項目中了。

接下來在項目中新建org.hibernate.test包,在包名上右擊,依次選擇New->Junit Test Case菜單,在彈出的窗口中填寫測試類的名稱和需要測試的類的名稱(這個需要填寫完整包名),如下圖所示:

點擊Next按鈕,可以選擇需要測試的方法,根據需要選擇即可。

 

這時候會生成一個UserTest類,里面包含的是一些空方法,我們要測哪些就給哪些加上方法體。

例如重寫testSave,下面是重寫之后的類:

package org.hibernate.test;

import static org.junit.Assert.*;

import org.hibernate.dao.UserDAO;
import org.hibernate.dao.UserDAOImpl;
import org.hibernate.entity.User;
import org.junit.Test;

public class UserTest {

    @Test
    public void testSave() {
        UserDAO userDAO=new UserDAOImpl();  
        try{  
            User u=new User();  
            // 設置User對象的各個屬性  
            u.setId(20);  
            u.setName("zhangsan");  
            u.setPassword("123456");  
            u.setType("admin");  
            // 使用UserDAOImpl的save方法將User對象存入到數據庫  
            userDAO.save(u);  
        }catch(Exception e){  
            e.printStackTrace();  
        } 
    }

    @Test
    public void testFindByIdGet() {
        fail("Not yet implemented");
    }

    @Test
    public void testFindByIdLoad() {
        fail("Not yet implemented");
    }

    @Test
    public void testFindByHQL() {
        fail("Not yet implemented");
    }

    @Test
    public void testDelete() {
        fail("Not yet implemented");
    }

    @Test
    public void testUpdate() {
        fail("Not yet implemented");
    }

}

接下來在UserTest.java文件名稱上右擊,依次選擇Run As ->Junit Test菜單。再查看數據庫中就會發現多了一條記錄。

這里可能有報錯,像上面說的

1.“org.hibernate.MappingException: Unknown entity:XXXXXXXXXXXXXXX”這個是因為SessionFactory獲取的方式不對,因為hibernate的版本問題,根據上面對應的紅色注釋改一下就好了。

2.ERROR: Field 'id' doesn't have a default value。這個是因為字段的問題,自動生成的User.hbm.xml可能不太一樣。

<id name="id" type="int">
            <column name="ID" />
            <generator class="assigned" />
        </id>

這里的generator對應的是數據庫中的id字段是否自動增長,assigned就是我寫進去20就是20,如果有的自動生成了native,表示的是從1開始自增,如果數據庫中沒有相應的設定的話可能會報錯,所以這里注意一下。

 

參照原文地址:http://blog.csdn.net/fxdaniel/article/details/42420779

到這里整個項目的創建到測試都完成了,現在來說一下我對每個步驟在干什么和為什么要這么做的理解。

 

1.創建項目。這里由於使用了JBoss,所以簡化了很多。hibernate.cfg.xml是hibernate中非常重要的一個xml文件,里面是一些hibernate的配置,其中session-factory最重要。試想一下我們以前用JDBC連接數據庫時候的操作,加載驅動、url、用戶名、密碼等等,這里也是一樣,你既然要操作數據庫,最根本的就是連接數據庫,所以hibernate的根就是在這個xml中,這里面讓jvm知道用的驅動、url、用戶名、密碼、以及數據庫方言(也就是數據庫種類mysql啊還是oracle還是sqlserver啊)。hibernate簡化了jdbc中一系列操作,直接通過xml配置文件來配置這些信息。

2.編寫POJO類(持久化類)。首先要明確hibernate是服務於持久層,什么是持久層,持久層就是存儲數據的,在一個項目中,數據要持久地保存。操作數據庫實際上是在操作我們面向的對象也就是POJO類,比如我們有一堆桌子,面向對象設計這個桌子,桌子的重量啊,形狀啊等信息會被看作是桌子的屬性,而數據庫里存的也是這些東西。

3.生成映射文件User.hbm.xml。數據庫和我們的類(也就是POJO類)是對應的,但是即使我們知道對應,jvm不知道啊,怎么讓他知道,用mapping來匹配。一個POJO類對應一個table,既然對應了,那POJO里面的屬性和table的字段肯定也是要對應的,因為屬性和字段表示的都是桌子的實際性質。所以映射文件的配置,就是讓jvm知道那個POJO類對應哪個table。所以看看這個xml里面的配置,是不是和數據庫中的字段配置很相似。

4.編寫hibernate.cfg.xml文件。一開始生成了一個xml文件,但是這個xml只是在有數據庫的時候生成的,但是我們要具體操作哪一個表的時候,xml就不知道了。現在我們的目的是添加一個user進入,那也就是說我們要操作user類,user類對應數據庫里的user表,但是jvm現在只知道要操作mysql數據庫,而上一步里面,我們讓jvm知道了user類和user表是對應的,可是user表在哪個數據庫里面存着呢?mysql還是oracle?mysql下的db還是oracle下的db?很自然的,現在只需要讓jvm把mysql數據庫和mapping對應起來,而這個mapping就是user類和user表的映射。現在整個邏輯通了,操作user類---映射到mysql數據庫--映射到user表。

5.編寫輔助工具類。剛才我們說的那些東西,都是保存在hibernate.cfg.xml下面,而那下面的標簽是<session-factory>,這個SessionFactory是很重要也很重的一個東西,既然剛才說的東西都保存在這里面,我們用的時候肯定也都是從這里面取,所以這個輔助工具類的就是為了取處這個SessionFactory。

6.編寫DAO層接口。在三層視圖層、業務層、持久層的邏輯中,DAO也就是database access object,直接面向數據庫。成熟的編程方式是先寫接口,再寫實現類。所以DAO層接口和實現分開。

7.DAO層實現類。這個就是利用取出的SessionFactory,再取出SessionFactory中我們需要的元素,操作這些元素也就是直接面向了數據庫,通過這個實現類來完成我們的目的。

8.一個Junit測試類。沒啥說的,測試項目。

 

希望通過這個配置來理解簡單的hibernate原理。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM