引入相關的包
注:實驗時出現了報錯信息,需要加入新的jar包
hibernate-jpa-2.0-api-1.0.0.Final.jar
而上述的ejb3-persistence.jar是與其重複衝突的(ejb3-persistence.jar本來就是屬於實現了jpa標準的annotation的實現),故還需要把ejb3的jar包刪掉。
又由於Hibernate3.5集成了annotations,故可以刪除
hibernate-commons-annotations.jar,hibernate-annotation.jar,hibernate-entitymanager.jar。不刪除往往會出現比較奇怪的錯誤。
(2)創建相關的數據庫和表
(3)配置文件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>
<!-- Database connection settings -->
<property name="connection.driver_class">
com.mysql.jdbc.Driver</property>
<property name="connection.url">
jdbc:mysql://localhost/hibernate</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<!-- JDBC connection pool (use the built-in) -->
<!--<property name="connection.pool_size">1</property>
-->
<!-- SQL dialect -->
<property name="dialect">
org.hibernate.dialect.MySQLDialect</property>
<!-- Enable Hibernate's automatic session context management -->
<!--<property name="current_session_context_class">thread</property>
--><!-- Disable the second-level cache -->
<property name="cache.provider_class">
org.hibernate.cache.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<!--<property name="hbm2ddl.auto">update</property>
-->
<mapping
resource="com/yilong/hibernate/model/Student.hbm.xml"/>
<!— -註解方式
<mapping class="com.yilong.hibernate.model.Husband"/>
<mapping class="com.yilong.hibernate.model.Wife"/>
--!>
</session-factory>
</hibernate-configuration>
(4)建立相關的類(class)
(5)建立該類的映射文件 class.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="com.yilong.hibernate.model">
<class name="Student" table="student" >
<id name="id" column="id"></id>//表示主鍵
<property name="name"></property>
<property name="age"></property>
</class>
</hibernate-mapping>
或者使用annotation註解的方法:
@Entity//實體與表的對應
public class Teacher {
private int id;
private String name;
private String title;
@Id//表示該字段爲表中的主鍵
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 getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
分別位於包:
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
說明:hibernate有自己的Annotation實現,在org.hibernate包,但是推薦使用實現了jpa接口的Annotation的實現。
可見,已經不再依賴hibernate,而是實現了jpa接口的一種annotation的具體實現。
歷史:SUN公司設計出的ejb2.0、ejb2.1比較不成熟,使用比較不方便,於是有人設計了Hibernate並很快流行起來。SUN公司見Hibernate使用方便,就把設計Hibernate的人聘請了過來設計出了ejb3,並定義了一套具體的標準jpa。Hibernate爲了支持官方版的標準,定義了Hibernate Annotation。
注:annotation爲hibernate對JPA接口的一種實現方式。Annotation的註解可以放在成員變量上,也可以放在get方法上,但是寫在成員變量field上似乎破壞了private屬性的意義,故一般寫在get方法上面。要保持field和set、get方法的一致性。“約定優於配置”。
<property name="hbm2ddl.auto">update</property>表示是否設置hbm(hibernate mapping)到ddl(data definition language)的轉換。常用的設置爲:
<property name="hbm2ddl.auto">create</property>
其中update表示如果不存在指定的表的時候,自動進行創建,然後更新,有則只進行更新;而create則不論情況直接創建(有就先刪除再創建),再進行更新,但是如果只是改變表中的數據類型的時則不會自動進行創建。如果沒有設置該屬性,如果遇到不存在指定的表,那麼就會報錯。除此之外,設置了該屬性在程序運行時還會生成sql語句,也可以在xml配置中不設置,改爲在程序中設置:
new SchemaExport(new AnnotationConfiguration().configure())
.create(true, true);
注:create方法中
第一個參數設置爲true,則表示會print the DDL to the console
第二個參數設置爲true,則表示會export the script to the database
另外:
<property name="show_sql">true</property>表示是否在命令行輸出sql語句<property name="format_sql">true</property>表示是否格式化sql語句的輸出,是兩個比較常設置的基本配置。
使用註解的方式往往會出現一下幾個問題:
問題一:實體名和表名不一樣時。可以用@Table(name=”表名”)說明,即例如:
@Entity
@Table(name=”_Teacher”)
如果使用xml文件的形式,則可以使用table=”表名”說明,即例如:
<class name="Student" table="student" >
需要注意的是使用xml文件的形式,如果不設置<property>屬性,則不會自動對該屬性進行映射,而使用annotation沒加註解的屬性默認幫你進行映射,相當於加上了@Basic註解。
問題二:字段名和屬性名不同。使用@Column(name=”_字段名”)進行說明。例如:@Column(name=”_name”)。同樣地,對於使用xml文件的情況,則可以使用column屬性進行映射:
<id name="id" column="id"></id>
或者<property name=”name” column=”_id”></property>
問題三:某些字段不需要persistence的情況。
Annotation使用註解:@Transient(透明的);xml不寫即可。
問題四:映射日期與時間類型,指定時間精度。
private Date birthDate;
默認情況下,在teacher.setBirthDate(new Date())後,會在數據庫中記錄時間和日期,而有的時候需要指定存儲的時間精度:
@Temporal(value=”TemporalType.TIMESTAMP”)//記錄時間和日期
@Temporal(TemporalType.DATE)//只記錄日期(可以省略value)對應數據庫DATE
@Temporal(TemporalType.TIME)//只記錄時間
對應用xml方式實現如下:
<property name=”birthDate” type=”date”></property>
<property name=”birthDate” type=”time”></property>
注意:在hibernate註解中如果屬性值的名字屬於value,那麼可以省略,即默認value。
問題五:hibernate的枚舉類型。
Hibernate對一些常用的基本類型(int, char, long等)與一些常用類(Date, String, Timestamp等)內置了轉換器,使得數據庫裏面的類型能順利地與實體類的屬性對應上。但是有些時候,需要自己定義一個轉換器,比較常見的就是枚舉類型,hibernate用xml映射枚舉類型比使用annotation進行映射麻煩。
使用xml配置:
l 先定義一個實現了UserType接口的類(如:EnumType),表示該類型是用戶自定義的;
l 然後實現接口的方法,通過重寫equals方法測試屬性是否進行了更改;
l 。。。。。。(比較複雜)
使用annotation(比較簡單),只需要添加@Enumrated註解:
@Enumerated(EnumType.STRING)
或者:@Enumerated(EnumType.ORDINAL)
不同之處在於生成的數據庫的對應字段的類型不同:
EnumType.STRING:
EnumType.ORDINAL:
其中ZhiCheng是enum類型的對象:
具體設置值:
(6)創建session,並調用相關的方法執行sql語句
方法一:使用xxx.hbm.xml配置
Student s = new Student();
s.setId(1);
s.setName("yilong");
s.setAge(22);
Configuration cfg = new Configuration();
SessionFactory sf = cfg.configure().buildSessionFactory();
Session session = sf.openSession();
session.beginTransaction();
session.save(s);
session.getTransaction().commit();
session.close();
sf.close();
方法二:使用註解的方式(寫在get方法的上面)
Teacher t = new Teacher();
t.setId(2);
t.setName("yilong");
t.setTitle("中級");
Configuration cfg = new AnnotationConfiguration();
SessionFactory sf = cfg.configure().buildSessionFactory();
Session session = sf.openSession();
session.beginTransaction();
session.save(t);
session.getTransaction().commit();
session.close();
sf.close();
而對於此,hibernate也對創建sessionFactory對象設計了一個輔助類HibernateUtil。由於SessionFactory只需要實例化一次即可,故該類設計成單例模式,可直接調用:
SessionFactory sessionFactory = HibernateUtil.getSessionFactory() 以下是該類的具體內容:
由上圖不難看出,hibernate起着O/R Mapping的作用,即將面向關係型的數據庫設計改成了面向對象的數據庫設計。
一些常見的O/R Mapping Frameworks包括:hibernate、toplink、jdo、ibatis、jpa(意願一統天下)