下面以一個(gè)簡(jiǎn)單的例子描述hibernate的使用。
軟件配置:jdk1.6+hibernate4.1+oracle10g
1.hibernate包下載
先到hibernate官網(wǎng)下載hibernate的開(kāi)發(fā)包hibernate-search-4.1.1.Final-dist.zip,解壓縮此包,dist\lib目錄下是開(kāi)發(fā)所需的jar包。
2.在eclipse中創(chuàng )建java項目
項目創(chuàng )建后,需要引入依賴(lài)的jar包:
hibernate包:required下全部jar包,provided下的hibernate-jpa-2.0-api-1.0.1.Final.jar和jta-1.1.jar包
oracle包:ojdbc6.jar
日志包(可選,如果不添加則看不到hibernate的日志輸出):slf4j-api-1.6.3.jar、logback-core-1.0.0.jar、logback-classic-1.0.0.jar
創(chuàng )建包:test,test.hibernate,test.model
3.創(chuàng )建數據庫表
本示例使用oracle,其他數據庫的特性和sql可參考一下代碼稍作改變即可:
創(chuàng )建House表:
- CREATE TABLE House
- (
- id NUMBER(8) NOT NULL,
- name VARCHAR2(50),
- address VARCHAR2(50) NOT NULL
- )
- ;
-
-
- ALTER TABLE House ADD CONSTRAINT PK_House
- PRIMARY KEY (id)
- USING INDEX
- ;
-
- CREATE SEQUENCE SEQ_House_id
- INCREMENT BY 1
- START WITH 1
- NOMAXVALUE
- MINVALUE 1
- NOCYCLE
- NOCACHE
- NOORDER
- ;
創(chuàng )建Person表:
- CREATE TABLE Person
- (
- id NUMBER(8) NOT NULL,
- name VARCHAR2(50),
- age NUMBER(3)
- )
- ;
-
-
- ALTER TABLE Person ADD CONSTRAINT PK_Person
- PRIMARY KEY (id)
- USING INDEX
- ;
4.編寫(xiě)hibernate配置文件
在src目錄下創(chuàng )建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>
- <property name="connection.url">jdbc:oracle:thin:@localhost:1521:orcl</property>
- <property name="connection.username">hi</property>
- <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
- <property name="dialect">org.hibernate.dialect.Oracle10gDialect</property>
- <property name="connection.password">hi</property>
- <property name="transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>
-
- <property name="current_session_context_class">thread</property>
- <!-- this will show us all sql statements -->
- <property name="hibernate.show_sql">true</property>
-
- <!-- mapping files -->
- <span style="color: #ff6600;"><mapping resource="test/model/House.hbm.xml"/></span>
- <span style="color: #ff6600;"><mapping class="test.model.Person"/></span>
- </session-factory>
- </hibernate-configuration>
注意看上面的mapping節點(diǎn):第一個(gè)使用的是mapping映射文件,第二個(gè)使用java注解映射方式。這兩個(gè)文件將在后面創(chuàng )建。
5.編寫(xiě)SessionFactoryUtil類(lèi)
在test.hibernate包下建立SessionFactoryUtil類(lèi),此類(lèi)用于獲取session:
- package test.hibernate;
-
- import org.hibernate.Session;
- import org.hibernate.SessionFactory;
- import org.hibernate.cfg.AnnotationConfiguration;
-
- public class SessionFactoryUtil {
-
- private static org.hibernate.SessionFactory sessionFactory;
- private SessionFactoryUtil() {
- }
-
- static {
- // 使用xml文件或者注解方式加載hibernate配置
- sessionFactory = new AnnotationConfiguration().configure()
- .buildSessionFactory();
- // 只是用xml文件方式加載hibernate配置
- // sessionFactory = new Configuration().configure().buildSessionFactory();
- }
-
- public static SessionFactory getInstance() {
- return sessionFactory;
- }
-
- /**
- * 打開(kāi)會(huì )話(huà)但不綁定到會(huì )話(huà)上下文中
- * @return the session
- */
- public Session openSession() {
- return sessionFactory.openSession();
- }
-
- /**
- * 從會(huì )話(huà)上下文中返回會(huì )話(huà),如果上下文中不存在會(huì )話(huà)示例則先創(chuàng )建一個(gè)會(huì )話(huà)示例并保存到上下文中,然后再返回。
- * <br>
- * 會(huì )話(huà)上下文與hibernate配置中的current_session_context_class屬性值有關(guān)。
- * @return the session
- */
- public Session getCurrentSession() {
- return sessionFactory.getCurrentSession();
- }
-
- /**
- * 關(guān)閉會(huì )話(huà)工廠(chǎng)
- */
- public static void close() {
- if (sessionFactory != null)
- sessionFactory.close();
- sessionFactory = null;
- }
- }
6.創(chuàng )建映射文件和類(lèi)
本例示范兩種方式的映射,mapping文件和java注解方式。
House采用mapping文件映射方式,Person采用java注解映射方式。
在test.model包下新建House類(lèi)(POJO):
- package test.model;
-
- public class House {
- private Integer id;
- private String name;
- private String address;
- /**
- * @return the id
- */
- public Integer getId() {
- return id;
- }
- /**
- * @param id the id to set
- */
- public void setId(Integer id) {
- this.id = id;
- }
- /**
- * @return the name
- */
- public String getName() {
- return name;
- }
- /**
- * @param name the name to set
- */
- public void setName(String name) {
- this.name = name;
- }
- /**
- * @return the address
- */
- public String getAddress() {
- return address;
- }
- /**
- * @param address the address to set
- */
- public void setAddress(String address) {
- this.address = address;
- }
- /* (non-Javadoc)
- * @see java.lang.Object#toString()
- */
- @Override
- public String toString() {
- return "House [id=" + id + ", name=" + name + ", address=" + address
- + "]";
- }
-
- }
同時(shí)在此包下新建House.hbm.xml映射文件,通過(guò)此文件描述House類(lèi)和數據庫中的House表之間的映射關(guān)系:
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD
- 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
- <hibernate-mapping>
- <class name="test.model.House" table="house">
- <id name="id" column="id">
- <generator class="sequence">
- <param name="sequence"><span style="color: #ff6600;">SEQ_HOUSE_ID</span></param>
- </generator>
- </id>
- <property name="name" column="name" />
- <property name="address" column="address" />
- </class>
- </hibernate-mapping>
house表在數據庫中使用名為SEQ_HOUSE_ID的序列作為主鍵id的值。如果表的主鍵生成方式不同,generator節點(diǎn)需要修改,網(wǎng)上有很多相關(guān)資料。
在test.model包下新建Person類(lèi)(POJO),并添加注解來(lái)表述語(yǔ)數據庫中Person表的映射關(guān)系,不做特殊說(shuō)明時(shí),默認數據庫中的名車(chē)和類(lèi)中名稱(chēng)一致。
- package test.model;
-
- import javax.persistence.AttributeOverride;
- import javax.persistence.Column;
- import javax.persistence.Entity;
- import javax.persistence.Id;
- import javax.persistence.Table;
-
- @Entity
- @Table(name="PERSON")//表名稱(chēng)和類(lèi)名稱(chēng)相同時(shí)可以不添加此注解來(lái)說(shuō)明
- public class Person {
- @Id
- private Integer id;
- private String name;
- @AttributeOverride(column = @Column, name = "AGE")//字段名稱(chēng)和屬性名稱(chēng)相同可以不添加此注解來(lái)說(shuō)明
- private int age;
-
- /**
- * @return the id
- */
- public Integer getId() {
- return id;
- }
- /**
- * @param id the id to set
- */
- public void setId(Integer id) {
- this.id = id;
- }
- /**
- * @return the name
- */
- public String getName() {
- return name;
- }
- /**
- * @param name the name to set
- */
- public void setName(String name) {
- this.name = name;
- }
- /**
- * @return the age
- */
- public int getAge() {
- return age;
- }
- /**
- * @param age the age to set
- */
- public void setAge(int age) {
- this.age = age;
- }
- }
7.編寫(xiě)測試方法
- package test;
-
- import org.hibernate.Session;
- import org.hibernate.Transaction;
-
- import test.hibernate.SessionFactoryUtil;
- import test.model.House;
- import test.model.Person;
-
- public class Test {
- // private static Logger logger = LoggerFactory.getLogger(Test.class);//slf4j logging
-
- public static void main(String[] args) {
- Session session = SessionFactoryUtil.getInstance().getCurrentSession();
- Transaction tx = session.beginTransaction();
-
- House house = new House();//瞬態(tài)
- house.setName("forest honey");
- house.setAddress("beijing");
-
- session.save(house);//持久態(tài)
-
- //對持久態(tài)對象進(jìn)行修改
- house.setAddress("yj1212");
-
- Person person = new Person();//瞬態(tài)
- person.setId(1);
- person.setAge(24);
- person.setName("張三");
- session.save(person);//持久態(tài)
-
- session.delete(person);//session關(guān)閉后此person便會(huì )成為托管態(tài)對象
-
- tx.commit();//提交事務(wù),提交后會(huì )自動(dòng)關(guān)閉session
-
- // session.close();
- }
- }
執行上面的main方法,控制臺輸出:
- Hibernate: select SEQ_HOUSE_ID.nextval from dual
- Hibernate: insert into house (name, address, id) values (?, ?, ?)
- Hibernate: insert into PERSON (age, name, id) values (?, ?, ?)
- Hibernate: update house set name=?, address=? where id=?
- Hibernate: delete from PERSON where id=?
測試類(lèi)中紊亂的“業(yè)務(wù)邏輯”代碼只是為了說(shuō)明hibernate的使用方式,請忽略!呵呵。
hibernate擁有緩存機制,其中session便是一級緩存,還可以配置二級緩存。要想充分利用hibernate的優(yōu)勢,還需要深入了解hibernate的session,事務(wù),緩存,延遲加載,以及各種對象尤其是session的生命周期等。后續再慢慢總結。