首先我們進一步理解什麼是對象關係映射模型? 它將對資料庫中數據的處理轉化為對對象的處理。如下圖所示: 入門簡單實例: hiberante 可以用在 j2se 項目,也可以用在 j2ee (web項目中),而struts是web框架,所以用在 web項目。 hibernate開發方式的主要兩種方式: ...
首先我們進一步理解什麼是對象關係映射模型?
它將對資料庫中數據的處理轉化為對對象的處理。如下圖所示:
入門簡單實例:
hiberante 可以用在 j2se 項目,也可以用在 j2ee (web項目中),而struts是web框架,所以用在 web項目。
hibernate開發方式的主要兩種方式:
1.由Domain object -> mapping->db。(更加符合面向對象的編程方式,從對象入手來通過映射生成表)
2.由DB開始,用工具生成mapping和Domain object。(往往更加習慣從表的構建入手,使用更多)
我們首先用從對象映射出表,到後面再使用第二種。
步驟:
1.創建一個工程
2.引入Hibernate相關包,引入資料庫驅動包(對於sql server資料庫需要三個包msbase.jar mssqlserver.jar msutil.jar)。
除了hibernate.jar核心包還需要其他相關的庫。
3.配置hibernate.cfg.xml文件
4.開發domain對象和對象關係映射文件
5.測試
domain對象
//要序列化,唯一標識對象
public class Employee implements java.io.Serializable{
private static final long serialVersionUID = 1L;
private Integer id;
private String name;
private String email;
private java.util.Date hiredate;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public java.util.Date getHiredate() {
return hiredate;
}
public void setHiredate(java.util.Date hiredate) {
this.hiredate = hiredate;
}
}
註意對象實現了序列化,序列化就是講對象的位元組序列持久化,也能唯一標識一個對象。對於序列化的知識可參考博主孤傲倉狼的文章:
對象關係映射文件
作用是用於指定 domain對象和表的映射關係.,該文件的取名有規範:domain對象.hbm.xml,一般我們放在 和domain對象同一個文件夾下(包下)
對主鍵增長策略比較講究,對於不同的資料庫,有相應的方式。
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.xidian.domain">
<class name="Employee" table="employee">
<id name="id" column="id" type="java.lang.Integer">
<!-- id設置自增長 -->
<generator class="identity"></generator>
</id>
<!-- 對其它屬性還有配置 -->
<property name="name" type="java.lang.String">
<column name="name" length="500" not-null="false" /> //length的預設長度是255
</property>
<property name="email" type="java.lang.String" >
<column name="email" not-null="false"/>
</property>
<property name="hiredate" type="java.util.Date">
<column name="hiredate" not-null="false" />
</property>
</class>
</hibernate-mapping>
hibernate.cfg.xml文件(預設是放在src文件夾下麵,也可放在子文件夾下麵,不過就要使用重載函數載入讀取)
該文件用於配置 連接的資料庫的類型,driver,用戶名,密碼 ,url ....同時管理對象關係映射文件 ,該文件的名稱我們一般不修改.
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- hibernate 設計者,給我們提供了一寫常用的配置 -->
<!-- 配置使用的driver -->
<property name="connection.driver_class">com.microsoft.jdbc.sqlserver.SQLServerDriver
</property>
<property name="connection.username">sa</property>
<property name="connection.password">dba</property>
<property name="connection.url">jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=test</property>
<!-- 配置dialect方言,明確告訴hibernate連接是哪種資料庫 -->
<property name="dialect">org.hibernate.dialect.SQLServerDialect</property>
<!-- 顯示出sql -->
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<!-- 配置可以使用getCurrentSession -->
<property name="current_session_context_class">thread</property>
<!-- 讓hibernate給我們自動創建表 create :如果沒有該表則創建.如果有表則刪除後再創建
update:如果沒有表則創建新表,如果有表則看表結構有沒有變化 ,有變化則會創建新表 -->
<property name="hbm2ddl.auto">update</property>
<!-- 指定管理的對象映射文件 -->
<mapping resource="com/xidian/domain/Employee.hbm.xml"/>
</session-factory>
</hibernate-configuration>
測試:
package com.hsp.view;
import com.hsp.util.*;
import java.util.Date;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.*;
import com.hsp.domain.Employee;
public class TestMain {
public static void main(String[] args) {
//查詢[load]->hql語句(hibernate query language)
}
public static void addEmployee() {
//我們使用hibernate完成crud操作[這裡我們只見對象,不見表]
//現在我們不是用service ,直接測試.
//1.創建Configuration,該對象用於讀取hibernate.cfg.xml,並完成初始化
Configuration configuration=new Configuration().configure();
//2.創建SessoinFactory[這是一個會話工廠,是一個重量級的對象(非常費記憶體,要只創建一個)]
SessionFactory sessionFactory=configuration.buildSessionFactory();
//3.創建Sessoin 相當於jdbc Connection[ servelt HttpSession ,不是 jsp session]
Session session=sessionFactory.openSession();
//4.對hiberate而言,要求程式員,在進行 增加,刪除,修改的時候使用事務提交,查詢可以不用事務
Transaction transaction = session.beginTransaction();
//添加一個雇員
Employee employee=new Employee();
employee.setName("xkj");
employee.setEmail("[email protected]");
employee.setHiredate(new Date());
//insert .............
//保存
session.save(employee);//save employee就是持久化該對象 (把對象保存到了資料庫中稱為一條記錄)
//==>insert into ....[被hiberante封裝]
//提交
transaction.commit();
session.close();
}
public static void delEmp() {
//刪除
//獲取一個session
Session session=MySessionFactory.getSessionFactory().openSession();
Transaction ts=session.beginTransaction();
//刪除1.先獲取該雇員,然後刪除
Employee emp=(Employee) session.load(Employee.class, 3);
session.delete(emp);
ts.commit();
session.close();
}
Hibernate執行update語句會先查詢,如果查詢到資料庫中的數據和對象數據不一致則會指定update語句,如果查詢到沒有更改則只做查詢,沒有update語句
public static void updateEmp() {
// TODO Auto-generated method stub
//修改用戶
//獲取一個會話
Session session=MySessionFactory.getSessionFactory().openSession();
/*Transaction ts=session.beginTransaction();
//修改用戶1. 獲取要修改的用戶,2.修改
//load是通過主鍵屬性,獲取該對象實例.<--->表的記錄對應
Employee emp=(Employee) session.load(Employee.class, 3);
emp.setName("xkj8");//update...
emp.setEmail("[email protected]");
ts.commit();
session.close();*/
//如何在hibernate中回滾事務
Transaction ts=null;
try {
ts=session.beginTransaction();
Employee emp=(Employee) session.load(Employee.class, 1);
emp.setName("xkj");
emp.setEmail("[email protected]");
int i=9/0;
ts.commit();
} catch (Exception e) {
if(ts!=null){
ts.rollback();
}
throw new RuntimeException(e.getMessage());
}finally{
if(session!=null&session.isOpen()){
session.close();
}
}
}
需要強調的是在用hibernate進行添加、修改、刪除的操作的時候一定要進行事務提交,否則不提交操作請求。使用查詢的時候是不必用事務的。
由圖可以看出,我在前四項紀錄,都用了事務提交,在第五項的時候沒有使用事務,沒有成功添加紀錄,下一次事務添加則直接從第六項開始。後面第九項也一樣。
這表明雖然沒有使用事務提交不能成功對紀錄進行操作,但是主鍵序列還是一直在變化。
在使用hibernate開發項目的時候一定要保證只有一個sessionFactory,一個資料庫對應一個SessionFactory對象,我們用單例模式創建sessionFactory
final public class MySessionFactory {
private static SessionFactory sessionFactory=null;
private MySessionFactory(){
}
static {
sessionFactory=new Configuration().configure().buildSessionFactory();
}
public static SessionFactory getSessionFactory(){
return sessionFactory;
}
}
運行測試代碼後在資料庫中可看見生成了employee表。
現在我們體驗一下hibernate切換資料庫的優勢。切換資料庫之後,只需要更改配置,而不需要修改主程式的業務代碼。
切換mysql資料庫
- 首先我們把 hibernate.cfg.xml文件重新配置.
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- hibernate 設計者,給我們提供了一寫常用的配置 -->
<!-- 配置使用的driver -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<property name="connection.url">jdbc:mysql:/localhost:3306/test</property>
<!-- 配置dialect方言,明確告訴hibernate連接是哪種資料庫 -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 顯示出對於sql -->
<property name="show_sql">true</property>
<!-- 讓hibernate給我們自動創建表 create :如果沒有該表則創建. -->
<property name="hbm2ddl.auto">create</property>
<!-- 指定管理的對象映射文件 -->
<mapping resource="com/hsp/domain/Employee.hbm.xml"/>
</session-factory>
</hibernate-configuration>
2.對對象映射文件,做了相應的修改.
<!-- 對主鍵生成策略我們做了修改 -->
<id name="id" column="id" type="java.lang.Integer">
<generator class="increment"></generator>
</id>
切換oracle資料庫
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- hibernate 設計者,給我們提供了常用的配置在文檔project--etc--hibernate.property 中可以查找到配置信息-->
<!-- 配置使用的driver -->
<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="connection.username">scott</property>
<property name="connection.password">tiger</property>
<property name="connection.url">jdbc:oracle:thin:@127.0.0.1:1521:orclhsp</property>
<!-- 配置dialect方言,明確告訴hibernate連接是哪種資料庫 -->
<property name="dialect">org.hibernate.dialect.OracleDialect</property>
<!-- 顯示出對於sql -->
<property name="show_sql">true</property>
<!-- 指定管理的對象映射文件 -->
<mapping resource="com/hsp/domain/Employee.hbm.xml"/>
</session-factory>
</hibernate-configuration>
2.對對象映射文件,做了相應的修改.
<!-- id元素用於指定主鍵屬性 -->
<id name="id" column="id" type="java.lang.Integer">
<!-- 該元素用於指定主鍵值生成策略hilo native increment sequence uuid -->
<generator class="sequence">
<param name="sequence">emp_seq</param>
</generator>
</id>