Hibernate簡介
Hibernate是一個開放源代碼的對象關係映射框架,它對JDBC進行了非常輕量級的對象封裝,使得Java程序員可以隨心所欲的使用對象編程思維來操縱數據庫。 Hibernate可以應用在任何使用JDBC的場合,既可以在Java的客戶端程序使用,也可以在Servlet/JSP的Web應用中使用,最具革命意義的是,Hibernate可以在應用EJB的J2EE架構中取代CMP,完成數據持久化的重任。
那麼爲什麼要使用hibernate呢?
使用hibernate是爲了簡化開發,從設計上來說,目的是爲了解決面嚮對象語言操作關係型數據庫出現的不匹配問題(模型不匹配、阻抗不匹配):
Java面嚮對象語言,對象模型,主要的概念有:繼承、關聯、多態等;數據庫是關係模型,主要概念有:表、外鍵、主鍵等。
這個問題可以通過jdbc手工實現這種映射,但是這種映射工作量比較大,特別當對象模型比較複雜的時候,比如說有繼承,有關聯的時候,用jdbc實現會非常的複雜,所以最終引入了ORM(Object Relation Mapping,對象關係映射)框架來解決,主流的ORM框架有Hibernate、TopLink、OJB等。
Hibernate開發環境搭建
這裏使用的hibernate版本是3.5.3
1.引入相關的jar文件:一般包括hibernate3.jar、antlr-2.7.6.jar、commons-collections-3.1.jar、dom4j-1.6.1.jar、javassist-3.9.0.GA.jar、jta-1.1.jar、slf4j-api-1.5.8.jar和slf4j-nop-1.5.8.jar。
2.編寫映射文件(可以從hibernate解壓路徑下面的project\tutorials\eg下面拷貝User.hbm.xml),然後根據自己的需要在此基礎上修改。
3.編寫配置文件(可以從hibernate解壓路徑下面的project\etc下面拷貝hibernate.cfg.xml),然後在這個基礎上根據自己的實際需要去修改。
注意:配置文件有XML和properties兩個格式的,即hibernate.cfg.xml和hibernate.properties,這兩個文件的作用一樣,提供一個即可,推薦XML格式,剛纔拷貝的那個hibernate.cfg.xml就是一個例子。
在配置文件中需要指定:
數據庫的URL、用戶名、密碼、JDBC驅動、方言等等。
啓動時hibernate會在CLASSPATH下面找這個文件。
開發流程
使用hibernate的時候會牽扯到幾種文件:java文件(java類|對象)、映射文件和數據庫表結構ddl文件。這三個文件一般有一個,就可以創建出其他的兩個。有以下幾種流程:
1.由Domain Object->mapping->db(官方推薦)
2.由db開始,用工具生成mapping和Domain Object(使用較多)
2.由映射文件開始
Domain Object的限制
1.默認的構造方法(必須有)
2.有無意義的標示符id(主鍵)
3.非final的,對懶加載有影響
例如:
public class User {
private int id;
private String username;
private Date birthday;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}
映射文件示例(User.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">
<hibernate-mapping
package="zhchljr.domain">
<class name="User">
<id name="id">
<generator class="native"/>
</id>
<property name="username"></property>
<property name="birthday"></property>
</class>
</hibernate-mapping>
這是個簡單的例子,配置文件的詳細說明,參見hibernate官方文檔。
相關的一些代碼
1.初始化代碼(只做一次,可以放在工具類的static塊中)
Configuration cfg = new Configuration();
cfg.configure();//當配置文件的名字和默認的不一樣時,可以在這裏指定。
SessionFactory sessionFactory = cfg.buildSessionFactory();
2.通用代碼
Session s = null;
Transaction tx = null;
try {
s = sessionFactory.openSession();
tx = s.beginTransaction();
//操作數據的代碼,save、update、delete、get等
tx.commit();
} catch (HibernateException e) {
if(tx != null) {
tx.rollback();
throw e;//這裏最好能拋出異常
}
} finally {
if(s != null) {
s.close();
}
}
Session的幾個主要方法
1.save,persist 保存數據,persist在事務外不會產生sql語句。
2.delete 刪除對象
3.update 更新對象,如果數據庫中沒有記錄,會報異常
4.get 根據ID,會立即查詢數據庫
5.load 根據ID,返回的是代理,不會立即訪問數據庫
6.saveOrUpdate,merge 根據ID和version的值來確定是save,還是update,調用merge,你的對象還是脫管的。
7.lock把對象變成持久對象,但不會同步對象的狀態。
對象狀態
瞬時(transient):數據庫中沒有數據與之對應,超過作用域會被JVM垃圾回收器回收,一般是new出來且與session沒有關聯的對象
持久(persistent):數據庫中有數據與之對應,當前與session有關聯,並且相關聯的session沒有關閉,事務沒有提交。持久對象狀態發生改變,在事務提交時會影響到數據庫(hibernate能檢測到)
脫管(detached):數據庫中有數據與之對應,但當前沒有session與之相關聯。脫管對象狀態發生改變,hibernate不能檢測到。
判斷對象狀態的兩個依據:是否在數據庫中有記錄,是否與session相關聯。
對象之間狀態的轉換如下圖所示:
HQL和Criteria
1.HQL(Hibernate Query Language)
面向對象的查詢語言,與SQL不同,HQL中的對象名是區分大小寫的(除了java類和屬性其他部分不區分大小寫);HQL中查詢的是對象,而不是表,並且支持多態;HQL主要通過Query來操作,Query的創建方式如下:
Query q = session.createQuery(hql);
(1)from Person
(2)from User user where user.username=:username
(3)from User user where user.username=:username and user.birthday<:birthday
2.Criteria
Criteria是一種比HQL更面向對象的查詢方式;Criteria的創建方式如下:
Criteria crit = s.createCriteria(DomainClass.class);
簡單屬性條件添加,如:
crit.add(Restrictions.eq("username", name));
crit.add(Restrictions.eqProperty(propertyName, otherPropertyName));