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的支援,完整實現對資料的增刪改查。我們的工作就先告一段落!
待更!!!