hibernate簡述
1. 什么是hibernate?
2. hibernate的知識內容
3. 什么是對象持久化?對象持久化有什么用?(解決的問題)
4. 如何對象持久化?
5. 如何用數據庫的方法做對象持久化?
6. ORM(對象關系映射)是什么?有什么作用?
7. ORM從對象到表所要考慮的問題
8. 什么是ORM框架?有什么用?
9. 使用hibernate的方法做對象持久化的工作,程序員應該怎么做?
10. hibernate有什么用?
11. 程序員和hibernate的整體工作流程
2. hibernate的知識內容
3. 什么是對象持久化?對象持久化有什么用?(解決的問題)
4. 如何對象持久化?
5. 如何用數據庫的方法做對象持久化?
6. ORM(對象關系映射)是什么?有什么作用?
7. ORM從對象到表所要考慮的問題
8. 什么是ORM框架?有什么用?
9. 使用hibernate的方法做對象持久化的工作,程序員應該怎么做?
10. hibernate有什么用?
11. 程序員和hibernate的整體工作流程
什么是hibernate:
持久化的框架,屬于設計方面的內容,類庫,用來做對象持久化的,什么是對象持久化呢?
Hibernate的知識內容:
語法部分(類庫)
程序設計思想,也就是持久層的設計
什么是對象持久化?對象持久化有什么用?(解決的問題):
發現問題:
程序設計的架構: 表現層—業務層—持久層—數據庫層,其中表現層和業務層是JVM來執行,應用程序會產生許多的對象,如果斷電了,對象就消失了,也就是說在內存中的對象是不穩定的,狀態不能持久
發現問題:
將一個對象從A電腦復制到B電腦,如何做到呢?
那么有三種方法解決上面的問題:
1. 序列化: 通過網絡傳遞,或者硬盤共享
2. 存儲到數據庫中,誰想用,從數據庫中拿
3. EJB Entity Bean(實體Bean)
序列化的方法比較死板:如果當一個對象的結構比較復雜的時候,我們這時只需要一部分內容,沒有辦法,只能整個寫入到文件,整個讀取
序列化的缺點: 不能檢索,不能分離一個對象,不方便共享
所以說第一種方法只能用于做臨時的持久化,簡單的傳輸,但不適合復雜的持久化工作
第二種方法(數據庫持久化):檢索方便,分布式共享,永久數據
總結:
什么是對象持久化: 對象持久化就是把內存中的對象永久的保存起來,保護對象的狀態,方便使用
對象持久化有什么用: 1.解決掉電的問題 2.共享方便 3.保證對象安全檢索方便
如何對象持久化:
1. 對象序列化
2. 數據庫(JDBC,EJB,Hibernate)
如何用數據庫的方法做對象持久化:
1. JDBC
發現問題: 需要做大量的工作,難度大
2. EJB
使用的是其中的一個功能來做持久化,解決了使用JDBC方法的的大量工作的問題
發現問題: EJB是重量級的組件,要使用它,有兩個問題 1.成本 2.性能
發現問題: 以上兩種方式還有個共同的問題,對象不是簡單存儲在數據庫中的,比如多態的特點就不能處理 A b=new B(); B為A的子類
3. Hibernate
解決了以上的所有問題,作用:1.不用做大量的工作 2.移植性能好 3.提高了代碼的質量,簡單 4.檢索共享重用成本調試
ORM(對象關系映射)是什么?有什么作用?
發現問題:
java中的對象的屬性類型和數據庫中的字段類型是不一樣的,那么如何來存儲java中的對象呢?這就需要做對象關系的映射,也就是ORM
什么是ORM: 將內存中的對象和數據庫做轉化,這樣就實現了java與數據庫之間的訪問等功能
ORM從對象到表所要考慮的問題:
Orm的復雜問題:
1. 數據庫如何保證對象的唯一性:在內存中,兩個對象屬性值都一樣,但是內存地址不一樣,可以做區分,但是在數據庫中如何分辨呢?
2. 繼承關系如何轉化
3. 集合如何映射呢?
什么是ORM框架?有什么用?
就是一個類庫,通過這個類庫完成持久化層的設計
使用hibernate的方法做對象持久化的工作,程序員應該怎么做?
1. 將ORM方案定下來,就是類到數據庫的轉化 2.利用hibernate生成代碼
hibernate有什么用?
1. 完成jdbc的代碼
2. 管理持久化對象的狀態
3. 提供一個查詢的API
程序員和hibernate的整體工作流程
程序員:
1. 設計ORM方案
2. 寫配置文件
3. 調用Hibernate的API,向Hibernate發出命令
hibernate:
4. 讀配置文件
5. 生成jdbc代碼
6. 執行
Hibernate簡單實例
Hibernate語法:
作用: 數據庫的增刪改查 HQL面向對象的查詢語句
大致步驟:
1. 設置環境 類庫
2. 定義映射
A 定義映射的實體po
B 建立數據庫表
C 寫XML配置文件(表,數據庫)
3. 調用Hibernate API
A 管理po的狀態(增刪改,恢復po狀態)
B 檢索(查詢)
Hibernate第一個簡單的實例: 引例(frisHbn包)
1. 設置環境
hibernate配置環境需要的資源
Hibernate的jar包: lib.zip dtd.zip: dtd.zip可以不設置
2. 定義映射
建立項目:
bussiness包: entity包 Biz包業務
client包: 測試
util包: 工具
先寫持久化類: 以花為實體,建立花類,并且建立數據庫表
/**
* 建表語句:
* CREATE TABLE T_FRUIT(
FID NUMBER(10) PRIMARY KEY,
NAME VARCHAR(20) NOT NULL,
COMMENTS VARCHAR(50),
PRICE NUMBER(5) NOT NULL
);
*/
package Yuchen.fristHbn.business.entity;
//持久化類(花類),注意因為采用的是hilo的方式獲得id,所以需要有setid的方法
public class Fruit {
private Integer fid;//hibernate中的id不能識別int
private String name;
private String comments;
private int price;
public Fruit() {
super();
}
public Fruit(String name, String comments, int price) {
super();
this.name = name;
this.comments = comments;
this.price = price;
}
public String getComments() {
return comments;
}
public void setComments(String comments) {
this.comments = comments;
}
public Integer getFid() {
return fid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public void setFid(Integer fid) {
this.fid = fid;
}
}
使用hilo的方式獲得id:
建表語句:
CREATE TABLE T_HILO(HILO_ID NUMBER(10));
INSERT INTO T_HILO VALUES(1);
寫hibernate的連接數據庫的配置文件:
<?xml version="1.0"?>
<!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="show_sql">true</property>
<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="connection.url">jdbc
racle:thin
127.0.0.1:1521:name</property>
<property name="connection.username">scott</property>
<property name="connection.password">tiger</property>
<property name="connection.isolation">2</property>
<property name="dialect">org.hibernate.dialect.Oracle9Dialect</property>
<mapping resource="Yuchen/fristHbn/business/entity/Fruit.hbm.xml"/>
</session-factory>
</hibernate-configuration>
寫映射配置文件:
<?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="Yuchen.fristHbn.business.entity">
<class name="Fruit" table="T_FRUIT">
<id name="fid" column="fid">
<generator class="hilo">
<param name="table">t_hilo</param>
<param name="column">hilo_id</param>
</generator>
</id>
<property name="name" column="name" />
<property name="comments" column="comments"></property>
<property name="price" column="price"></property>
</class>
</hibernate-mapping>
A. 類名—表名
B. id—id 獲得id的方式 詳細信息(如: hilo的表名和字段)
C. 屬性—字段
使用hibernate API(FruitManager.java):
package Yuchen.fristHbn.business.Biz;
//業務邏輯類:負責增刪改查通過使用hibernate API進行
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import Yuchen.fristHbn.business.entity.Fruit;
public class FruitManager {
public void insert(Fruit fruit){
Configuration config=new Configuration();
config.configure();//讀配置文件
SessionFactory sf=config.buildSessionFactory();//得到工廠
Session session=sf.openSession();//得到session
Transaction tt=session.beginTransaction();//檢查事務開啟
session.save(fruit);//存儲insert
tt.commit();//提交
session.close();//關閉資源
}
}
寫測試類: 插入一個對象到數據庫中
/**
* 知識點:
* hibernate基礎:練習語法部分API和簡單的映射關系
* 程序目標:
* 使用hibernate方法將對象進行持久化
* 實現數據庫的增刪改查
* API:
* 1.Configuration:這個類負責讀取XML文檔(映射配置文件)
* configure():讀xml
* buildSessionFactory():創建一個生產session對象的工廠,其實是再次檢查
* 因為hibernate和jdbc不一樣,jdbc是如果不手動設置開啟事務,那它
* 就是馬上執行sql的,hibernate的不會馬上執行,是事務提交后執行
* 默認情況下就是打開事務的狀態,這里只是再檢查以下
* 2.SessionFactory:負責生產session對象
* openSession():創建一個session
* 3.Session類:這個是主要的類,負責增刪改查,開啟事務等
* beginTransaction():產生一個事務對象(Transaction)
* save():增加相當于操作sql中的insert語句
* 4.Transaction類:負責管理事務的
* commit():提交一個事務
*
*/
package Yuchen.fristHbn.client;
import Yuchen.fristHbn.business.Biz.FruitManager;
import Yuchen.fristHbn.business.entity.Fruit;
public class Test {
public static void test1(){
Fruit fruit=new Fruit("lisi","hello",100);
// fruit.setName("zhangsan");
// fruit.setComments("hello");
// fruit.setPrice(100);
FruitManager fm=new FruitManager();
fm.insert(fruit);
}
public static void main(String[] args) {
// TODO 自動生成方法存根
Test t=new Test();
t.test1();
}
}
hibernate API(一):
Configuration: 讀取配置文件信息用來初始化的
SessionFactory: 重量級對象,特點:消耗資源大,線程是安全,所以可以被共享
上面兩個對象只實例化一個就行了,都是用于初始化的
Session: 線程是不安全的,所以要避免多個線程共享它,是輕量級的對象,使用后關閉
Session對象的狀態:
順態: 還沒有被持久化,也就是說數據庫中沒有該對象的記錄,并且Session中的緩沖區里沒有這個對象的引用
持久態: 在數據庫中有該對象的記錄,并且在session中的緩沖區里有這個對象的引用,和順態正好相反
游離態: 在數據庫中有記錄,但是不在session的緩沖區里
對象狀態的轉換:
做一個工具類,將hibernate中重復的代碼包裝起來:
package Yuchen.fristHbn.util;
//生產session對象的工具類
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HbnUtil {
private static SessionFactory sf;
static{
sf=new Configuration().configure().buildSessionFactory();
}
public static Session getSession(){
return sf.openSession();
}
}
完善FruitManager類:
package Yuchen.fristHbn.business.Biz;
//業務邏輯類:負責增刪改查通過使用hibernate API進行
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import Yuchen.fristHbn.business.entity.Fruit;
import Yuchen.fristHbn.util.HbnUtil;
public class FruitManager {
public Integer insert(Fruit fruit){
Session session=HbnUtil.getSession();//通過工具更方便了
Integer id=null;
// Configuration config=new Configuration();
// config.configure();//讀配置文件
// SessionFactory sf=config.buildSessionFactory();//得到工廠
// Session session=sf.openSession();//得到session
Transaction tt=session.beginTransaction();//檢查事務開啟
id=(Integer)session.save(fruit);//存儲insert
tt.commit();//提交
session.close();//關閉資源
return id;
}
public Fruit selectId(Integer id){
Session session=HbnUtil.getSession();
Transaction t=session.beginTransaction();
Fruit fruit=(Fruit)session.get(Fruit.class, id);
t.commit();
session.close();
return fruit;
}
public void remove(Fruit fruit){
Session session=HbnUtil.getSession();
Transaction t=session.beginTransaction();
session.delete(fruit);
t.commit();
session.close();
}
}
測試對象狀態的轉換:
/**
* 知識點:
* hibernate基礎:練習語法部分API和簡單的映射關系
* 程序目標:
* 使用hibernate方法將對象進行持久化
* 實現數據庫的增刪改查
* API:
* 1.Configuration:這個類負責讀取XML文檔(映射配置文件)
* configure():讀xml
* buildSessionFactory():創建一個生產session對象的工廠,其實是再次檢查
* 因為hibernate和jdbc不一樣,jdbc是如果不手動設置開啟事務,那它
* 就是馬上執行sql的,hibernate的不會馬上執行,是事務提交后執行
* 默認情況下就是打開事務的狀態,這里只是再檢查以下
* 2.SessionFactory:負責生產session對象
* openSession():創建一個session
* 3.Session類:這個是主要的類,負責增刪改查,開啟事務等
* beginTransaction():產生一個事務對象(Transaction)
* save():增加相當于操作sql中的insert語句
* 4.Transaction類:負責管理事務的
* commit():提交一個事務
* test1():測試插入的功能
* test2():測試數據同步更新的功能
* test3():測試saveOrUpdate()
* test4():測試clear()和flush()
*/
package Yuchen.fristHbn.client;
import org.hibernate.Session;
import org.hibernate.Transaction;
import Yuchen.fristHbn.business.Biz.FruitManager;
import Yuchen.fristHbn.business.entity.Fruit;
import Yuchen.fristHbn.util.HbnUtil;
public class Test {
public void test1(){
Fruit fruit=new Fruit("lisi","hello",100);
// fruit.setName("zhangsan");
// fruit.setComments("hello");
// fruit.setPrice(100);
FruitManager fm=new FruitManager();
fm.insert(fruit);
}
public void test2(){
//測試同步更新的功能
Fruit fruit=new Fruit("meigui","hongse",70);//順態
FruitManager fm=new FruitManager();
Fruit fruit2=new Fruit();
Integer id=fm.insert(fruit);
fruit2=fm.selectId(id);
System.out.println(fruit2.getFid());
System.out.println(fruit2.getName());
fruit.setName("ziluolan");//這里修改了對象
fruit2=fm.selectId(id);
System.out.println(fruit2.getFid());//但是結果沒有更新
System.out.println(fruit2.getName());
//因為fruit在Integer id=fm.insert(fruit);后變成游離態了
//也就是說只有持久態才能實現同步更新
System.out.println(fruit.getFid());
System.out.println(fruit.getName());
}
public void test3(){
Session session=HbnUtil.getSession();
Transaction t=session.beginTransaction();
Fruit fruit=new Fruit("ziluolan","lanse",100);//順態
Fruit fruit2=new Fruit();
FruitManager fm=new FruitManager();
session.save(fruit);//fruit在運行完此句后變為游離態
fruit2=(Fruit) session.get(Fruit.class, fruit.getFid());
//從數據庫讀并打印出來
System.out.println(fruit2.getFid()+":"+fruit2.getName());
session.saveOrUpdate(fruit);//如果該對象為游歷態就更新數據庫update
//否則就是順態,增加insert
fruit2=(Fruit) session.get(Fruit.class, fruit.getFid());
//saveOrUpdate后再從數據庫讀并打印出來
System.out.println(fruit2.getFid()+":"+fruit2.getName());
//兩個打印結果一樣,saveOrUpdate方法判斷如果id為null,就
//順態,否則就是游離態
t.commit();
session.close();
}
public void test4(){
Session session=HbnUtil.getSession();
Transaction t=session.beginTransaction();
Fruit fruit=new Fruit("guihua","fense",300);//順態
Fruit fruit2=new Fruit();
session.saveOrUpdate(fruit);//執行insert因為對象為順態
// session.flush();
session.clear();//fruit變成游離態了,并且不會執行insert語句
//因為hibernate不是馬上執行sql,而是等t.commit()提交事務
//后才執行,clear后,對象為游離態
session.saveOrUpdate(fruit);//這里驗證上面的話,執行update
//做個select查看一下,可以證明,因為clear后,沒有馬上執行
//sql語句,所以表里沒有數據,這里update也沒有用,所以表中
//一個對象也沒插入,但是如果加入flush()刷新就是馬上執行sql了
t.commit();
session.close();
}
public static void main(String[] args) {
// TODO 自動生成方法存根
Test t=new Test();
// t.test1();
// t.test2();
// t.test3();
t.test4();
}
}
hibernate API(二):
flush(): 從上面的例子可以看出,flush是刷新session的緩沖區,并執行里面的命令
flush()的事務管理模式: flushMode()里面有三個常量,可以用數字來表示
Load(): 另一種讀取數據的方法,和get的區別是: 1.異常處理: load有異常處理,get沒有,它返回null,2.get從數據庫讀數據,load可能去讀緩沖區
事務的隔離級別:
在hibernate的數據庫配置文件中設置
數字1為可以臟讀,數字2為不能,這個是最常用的
鎖機制:
避免并發沖突,在數據庫中寫數據是自動加鎖的,讀一般不加,有悲觀鎖和樂觀鎖
樂觀鎖是可以是hibernate程序自己加
實現樂觀鎖: 引例(hbn2包)
步驟:
1. 在表中加個version字段
2. 在持久類里加個version屬性
3. 配置文件<version name=”versopm”> 每存一次值加1
引例:hbn2包
復雜的映射:
1. 基數關系映射
2. 繼承關系映射
3. 組件關系映射
4. 集合映射
基數關系的映射—one to one:
基數關系的映射需要考慮的問題:
1. 數量問題
2. 方向問題
在one to one的關系中,我們有兩種方法可以體現類與類之間的關系
1. 共享主鍵
2. 外鍵唯一
引例: Joto包-此包引用了fristHbn包
建立與Fruit類有一對一關系的類:
我們認為一個花有一個產地,一個產地生產一種花,所以要建立產地類
package Yuchen.Joto.business.entity;
//花的地址類
//問題:為什么不能在構造函數中寫Fruit?因為生成對象后要持久化
//這個對象,但是數據庫的表中不能插入另一個類的值,寫上null又不
//大合適,所以就去掉它
public class Address {
private Integer aid;
private String nation;
private String postcode;
private Fruit fruit;
public Address() {
}
public Address(String nation, String postcode) {
super();
this.nation = nation;
this.postcode = postcode;
}
public Integer getAid() {
return aid;
}
public void setAid(Integer aid) {
this.aid = aid;
}
public Fruit getFruit() {
return fruit;
}
public void setFruit(Fruit fruit) {
this.fruit = fruit;
// fruit.setAddress(this);
}
public String getNation() {
return nation;
}
public void setNation(String nation) {
this.nation = nation;
}
public String getPostcode() {
return postcode;
}
public void setPostcode(String postcode) {
this.postcode = postcode;
}
}
修改Fruit類:
package Yuchen.Joto.business.entity;
//持久化類(花類),注意因為采用的是hilo的方式獲得id,所以需要有setid的方法
public class Fruit {
private Integer fid;//hibernate中的id不能識別int
private String name;
private String comments;
private int price;
private Address address;//一朵花對應一個地址
public Fruit() {
super();
}
public Fruit(String name, String comments, int price) {
super();
this.name = name;
this.comments = comments;
this.price = price;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
address.setFruit(this);//因為當你給一個花設置產地的時候
//該產地也有了花
}
public String getComments() {
return comments;
}
public void setComments(String comments) {
this.comments = comments;
}
public Integer getFid() {
return fid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price)
持久化的框架,屬于設計方面的內容,類庫,用來做對象持久化的,什么是對象持久化呢?
Hibernate的知識內容:
語法部分(類庫)
程序設計思想,也就是持久層的設計
什么是對象持久化?對象持久化有什么用?(解決的問題):
發現問題:
程序設計的架構: 表現層—業務層—持久層—數據庫層,其中表現層和業務層是JVM來執行,應用程序會產生許多的對象,如果斷電了,對象就消失了,也就是說在內存中的對象是不穩定的,狀態不能持久
發現問題:
將一個對象從A電腦復制到B電腦,如何做到呢?
那么有三種方法解決上面的問題:
1. 序列化: 通過網絡傳遞,或者硬盤共享
2. 存儲到數據庫中,誰想用,從數據庫中拿
3. EJB Entity Bean(實體Bean)
序列化的方法比較死板:如果當一個對象的結構比較復雜的時候,我們這時只需要一部分內容,沒有辦法,只能整個寫入到文件,整個讀取
序列化的缺點: 不能檢索,不能分離一個對象,不方便共享
所以說第一種方法只能用于做臨時的持久化,簡單的傳輸,但不適合復雜的持久化工作
第二種方法(數據庫持久化):檢索方便,分布式共享,永久數據
總結:
什么是對象持久化: 對象持久化就是把內存中的對象永久的保存起來,保護對象的狀態,方便使用
對象持久化有什么用: 1.解決掉電的問題 2.共享方便 3.保證對象安全檢索方便
如何對象持久化:
1. 對象序列化
2. 數據庫(JDBC,EJB,Hibernate)
如何用數據庫的方法做對象持久化:
1. JDBC
發現問題: 需要做大量的工作,難度大
2. EJB
使用的是其中的一個功能來做持久化,解決了使用JDBC方法的的大量工作的問題
發現問題: EJB是重量級的組件,要使用它,有兩個問題 1.成本 2.性能
發現問題: 以上兩種方式還有個共同的問題,對象不是簡單存儲在數據庫中的,比如多態的特點就不能處理 A b=new B(); B為A的子類
3. Hibernate
解決了以上的所有問題,作用:1.不用做大量的工作 2.移植性能好 3.提高了代碼的質量,簡單 4.檢索共享重用成本調試
ORM(對象關系映射)是什么?有什么作用?
發現問題:
java中的對象的屬性類型和數據庫中的字段類型是不一樣的,那么如何來存儲java中的對象呢?這就需要做對象關系的映射,也就是ORM
什么是ORM: 將內存中的對象和數據庫做轉化,這樣就實現了java與數據庫之間的訪問等功能
ORM從對象到表所要考慮的問題:
Orm的復雜問題:
1. 數據庫如何保證對象的唯一性:在內存中,兩個對象屬性值都一樣,但是內存地址不一樣,可以做區分,但是在數據庫中如何分辨呢?
2. 繼承關系如何轉化
3. 集合如何映射呢?
什么是ORM框架?有什么用?
就是一個類庫,通過這個類庫完成持久化層的設計
使用hibernate的方法做對象持久化的工作,程序員應該怎么做?
1. 將ORM方案定下來,就是類到數據庫的轉化 2.利用hibernate生成代碼
hibernate有什么用?
1. 完成jdbc的代碼
2. 管理持久化對象的狀態
3. 提供一個查詢的API
程序員和hibernate的整體工作流程
程序員:
1. 設計ORM方案
2. 寫配置文件
3. 調用Hibernate的API,向Hibernate發出命令
hibernate:
4. 讀配置文件
5. 生成jdbc代碼
6. 執行
Hibernate簡單實例
Hibernate語法:
作用: 數據庫的增刪改查 HQL面向對象的查詢語句
大致步驟:
1. 設置環境 類庫
2. 定義映射
A 定義映射的實體po
B 建立數據庫表
C 寫XML配置文件(表,數據庫)
3. 調用Hibernate API
A 管理po的狀態(增刪改,恢復po狀態)
B 檢索(查詢)
Hibernate第一個簡單的實例: 引例(frisHbn包)
1. 設置環境
hibernate配置環境需要的資源
Hibernate的jar包: lib.zip dtd.zip: dtd.zip可以不設置
2. 定義映射
建立項目:
bussiness包: entity包 Biz包業務
client包: 測試
util包: 工具
先寫持久化類: 以花為實體,建立花類,并且建立數據庫表
/**
* 建表語句:
* CREATE TABLE T_FRUIT(
FID NUMBER(10) PRIMARY KEY,
NAME VARCHAR(20) NOT NULL,
COMMENTS VARCHAR(50),
PRICE NUMBER(5) NOT NULL
);
*/
package Yuchen.fristHbn.business.entity;
//持久化類(花類),注意因為采用的是hilo的方式獲得id,所以需要有setid的方法
public class Fruit {
private Integer fid;//hibernate中的id不能識別int
private String name;
private String comments;
private int price;
public Fruit() {
super();
}
public Fruit(String name, String comments, int price) {
super();
this.name = name;
this.comments = comments;
this.price = price;
}
public String getComments() {
return comments;
}
public void setComments(String comments) {
this.comments = comments;
}
public Integer getFid() {
return fid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public void setFid(Integer fid) {
this.fid = fid;
}
}
使用hilo的方式獲得id:
建表語句:
CREATE TABLE T_HILO(HILO_ID NUMBER(10));
INSERT INTO T_HILO VALUES(1);
寫hibernate的連接數據庫的配置文件:
<?xml version="1.0"?>
<!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="show_sql">true</property>
<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="connection.url">jdbc


<property name="connection.username">scott</property>
<property name="connection.password">tiger</property>
<property name="connection.isolation">2</property>
<property name="dialect">org.hibernate.dialect.Oracle9Dialect</property>
<mapping resource="Yuchen/fristHbn/business/entity/Fruit.hbm.xml"/>
</session-factory>
</hibernate-configuration>
寫映射配置文件:
<?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="Yuchen.fristHbn.business.entity">
<class name="Fruit" table="T_FRUIT">
<id name="fid" column="fid">
<generator class="hilo">
<param name="table">t_hilo</param>
<param name="column">hilo_id</param>
</generator>
</id>
<property name="name" column="name" />
<property name="comments" column="comments"></property>
<property name="price" column="price"></property>
</class>
</hibernate-mapping>
A. 類名—表名
B. id—id 獲得id的方式 詳細信息(如: hilo的表名和字段)
C. 屬性—字段
使用hibernate API(FruitManager.java):
package Yuchen.fristHbn.business.Biz;
//業務邏輯類:負責增刪改查通過使用hibernate API進行
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import Yuchen.fristHbn.business.entity.Fruit;
public class FruitManager {
public void insert(Fruit fruit){
Configuration config=new Configuration();
config.configure();//讀配置文件
SessionFactory sf=config.buildSessionFactory();//得到工廠
Session session=sf.openSession();//得到session
Transaction tt=session.beginTransaction();//檢查事務開啟
session.save(fruit);//存儲insert
tt.commit();//提交
session.close();//關閉資源
}
}
寫測試類: 插入一個對象到數據庫中
/**
* 知識點:
* hibernate基礎:練習語法部分API和簡單的映射關系
* 程序目標:
* 使用hibernate方法將對象進行持久化
* 實現數據庫的增刪改查
* API:
* 1.Configuration:這個類負責讀取XML文檔(映射配置文件)
* configure():讀xml
* buildSessionFactory():創建一個生產session對象的工廠,其實是再次檢查
* 因為hibernate和jdbc不一樣,jdbc是如果不手動設置開啟事務,那它
* 就是馬上執行sql的,hibernate的不會馬上執行,是事務提交后執行
* 默認情況下就是打開事務的狀態,這里只是再檢查以下
* 2.SessionFactory:負責生產session對象
* openSession():創建一個session
* 3.Session類:這個是主要的類,負責增刪改查,開啟事務等
* beginTransaction():產生一個事務對象(Transaction)
* save():增加相當于操作sql中的insert語句
* 4.Transaction類:負責管理事務的
* commit():提交一個事務
*
*/
package Yuchen.fristHbn.client;
import Yuchen.fristHbn.business.Biz.FruitManager;
import Yuchen.fristHbn.business.entity.Fruit;
public class Test {
public static void test1(){
Fruit fruit=new Fruit("lisi","hello",100);
// fruit.setName("zhangsan");
// fruit.setComments("hello");
// fruit.setPrice(100);
FruitManager fm=new FruitManager();
fm.insert(fruit);
}
public static void main(String[] args) {
// TODO 自動生成方法存根
Test t=new Test();
t.test1();
}
}
hibernate API(一):
Configuration: 讀取配置文件信息用來初始化的
SessionFactory: 重量級對象,特點:消耗資源大,線程是安全,所以可以被共享
上面兩個對象只實例化一個就行了,都是用于初始化的
Session: 線程是不安全的,所以要避免多個線程共享它,是輕量級的對象,使用后關閉
Session對象的狀態:
順態: 還沒有被持久化,也就是說數據庫中沒有該對象的記錄,并且Session中的緩沖區里沒有這個對象的引用
持久態: 在數據庫中有該對象的記錄,并且在session中的緩沖區里有這個對象的引用,和順態正好相反
游離態: 在數據庫中有記錄,但是不在session的緩沖區里
對象狀態的轉換:
做一個工具類,將hibernate中重復的代碼包裝起來:
package Yuchen.fristHbn.util;
//生產session對象的工具類
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HbnUtil {
private static SessionFactory sf;
static{
sf=new Configuration().configure().buildSessionFactory();
}
public static Session getSession(){
return sf.openSession();
}
}
完善FruitManager類:
package Yuchen.fristHbn.business.Biz;
//業務邏輯類:負責增刪改查通過使用hibernate API進行
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import Yuchen.fristHbn.business.entity.Fruit;
import Yuchen.fristHbn.util.HbnUtil;
public class FruitManager {
public Integer insert(Fruit fruit){
Session session=HbnUtil.getSession();//通過工具更方便了
Integer id=null;
// Configuration config=new Configuration();
// config.configure();//讀配置文件
// SessionFactory sf=config.buildSessionFactory();//得到工廠
// Session session=sf.openSession();//得到session
Transaction tt=session.beginTransaction();//檢查事務開啟
id=(Integer)session.save(fruit);//存儲insert
tt.commit();//提交
session.close();//關閉資源
return id;
}
public Fruit selectId(Integer id){
Session session=HbnUtil.getSession();
Transaction t=session.beginTransaction();
Fruit fruit=(Fruit)session.get(Fruit.class, id);
t.commit();
session.close();
return fruit;
}
public void remove(Fruit fruit){
Session session=HbnUtil.getSession();
Transaction t=session.beginTransaction();
session.delete(fruit);
t.commit();
session.close();
}
}
測試對象狀態的轉換:
/**
* 知識點:
* hibernate基礎:練習語法部分API和簡單的映射關系
* 程序目標:
* 使用hibernate方法將對象進行持久化
* 實現數據庫的增刪改查
* API:
* 1.Configuration:這個類負責讀取XML文檔(映射配置文件)
* configure():讀xml
* buildSessionFactory():創建一個生產session對象的工廠,其實是再次檢查
* 因為hibernate和jdbc不一樣,jdbc是如果不手動設置開啟事務,那它
* 就是馬上執行sql的,hibernate的不會馬上執行,是事務提交后執行
* 默認情況下就是打開事務的狀態,這里只是再檢查以下
* 2.SessionFactory:負責生產session對象
* openSession():創建一個session
* 3.Session類:這個是主要的類,負責增刪改查,開啟事務等
* beginTransaction():產生一個事務對象(Transaction)
* save():增加相當于操作sql中的insert語句
* 4.Transaction類:負責管理事務的
* commit():提交一個事務
* test1():測試插入的功能
* test2():測試數據同步更新的功能
* test3():測試saveOrUpdate()
* test4():測試clear()和flush()
*/
package Yuchen.fristHbn.client;
import org.hibernate.Session;
import org.hibernate.Transaction;
import Yuchen.fristHbn.business.Biz.FruitManager;
import Yuchen.fristHbn.business.entity.Fruit;
import Yuchen.fristHbn.util.HbnUtil;
public class Test {
public void test1(){
Fruit fruit=new Fruit("lisi","hello",100);
// fruit.setName("zhangsan");
// fruit.setComments("hello");
// fruit.setPrice(100);
FruitManager fm=new FruitManager();
fm.insert(fruit);
}
public void test2(){
//測試同步更新的功能
Fruit fruit=new Fruit("meigui","hongse",70);//順態
FruitManager fm=new FruitManager();
Fruit fruit2=new Fruit();
Integer id=fm.insert(fruit);
fruit2=fm.selectId(id);
System.out.println(fruit2.getFid());
System.out.println(fruit2.getName());
fruit.setName("ziluolan");//這里修改了對象
fruit2=fm.selectId(id);
System.out.println(fruit2.getFid());//但是結果沒有更新
System.out.println(fruit2.getName());
//因為fruit在Integer id=fm.insert(fruit);后變成游離態了
//也就是說只有持久態才能實現同步更新
System.out.println(fruit.getFid());
System.out.println(fruit.getName());
}
public void test3(){
Session session=HbnUtil.getSession();
Transaction t=session.beginTransaction();
Fruit fruit=new Fruit("ziluolan","lanse",100);//順態
Fruit fruit2=new Fruit();
FruitManager fm=new FruitManager();
session.save(fruit);//fruit在運行完此句后變為游離態
fruit2=(Fruit) session.get(Fruit.class, fruit.getFid());
//從數據庫讀并打印出來
System.out.println(fruit2.getFid()+":"+fruit2.getName());
session.saveOrUpdate(fruit);//如果該對象為游歷態就更新數據庫update
//否則就是順態,增加insert
fruit2=(Fruit) session.get(Fruit.class, fruit.getFid());
//saveOrUpdate后再從數據庫讀并打印出來
System.out.println(fruit2.getFid()+":"+fruit2.getName());
//兩個打印結果一樣,saveOrUpdate方法判斷如果id為null,就
//順態,否則就是游離態
t.commit();
session.close();
}
public void test4(){
Session session=HbnUtil.getSession();
Transaction t=session.beginTransaction();
Fruit fruit=new Fruit("guihua","fense",300);//順態
Fruit fruit2=new Fruit();
session.saveOrUpdate(fruit);//執行insert因為對象為順態
// session.flush();
session.clear();//fruit變成游離態了,并且不會執行insert語句
//因為hibernate不是馬上執行sql,而是等t.commit()提交事務
//后才執行,clear后,對象為游離態
session.saveOrUpdate(fruit);//這里驗證上面的話,執行update
//做個select查看一下,可以證明,因為clear后,沒有馬上執行
//sql語句,所以表里沒有數據,這里update也沒有用,所以表中
//一個對象也沒插入,但是如果加入flush()刷新就是馬上執行sql了
t.commit();
session.close();
}
public static void main(String[] args) {
// TODO 自動生成方法存根
Test t=new Test();
// t.test1();
// t.test2();
// t.test3();
t.test4();
}
}
hibernate API(二):
flush(): 從上面的例子可以看出,flush是刷新session的緩沖區,并執行里面的命令
flush()的事務管理模式: flushMode()里面有三個常量,可以用數字來表示
Load(): 另一種讀取數據的方法,和get的區別是: 1.異常處理: load有異常處理,get沒有,它返回null,2.get從數據庫讀數據,load可能去讀緩沖區
事務的隔離級別:
在hibernate的數據庫配置文件中設置
數字1為可以臟讀,數字2為不能,這個是最常用的
鎖機制:
避免并發沖突,在數據庫中寫數據是自動加鎖的,讀一般不加,有悲觀鎖和樂觀鎖
樂觀鎖是可以是hibernate程序自己加
實現樂觀鎖: 引例(hbn2包)
步驟:
1. 在表中加個version字段
2. 在持久類里加個version屬性
3. 配置文件<version name=”versopm”> 每存一次值加1
引例:hbn2包
復雜的映射:
1. 基數關系映射
2. 繼承關系映射
3. 組件關系映射
4. 集合映射
基數關系的映射—one to one:
基數關系的映射需要考慮的問題:
1. 數量問題
2. 方向問題
在one to one的關系中,我們有兩種方法可以體現類與類之間的關系
1. 共享主鍵
2. 外鍵唯一
引例: Joto包-此包引用了fristHbn包
建立與Fruit類有一對一關系的類:
我們認為一個花有一個產地,一個產地生產一種花,所以要建立產地類
package Yuchen.Joto.business.entity;
//花的地址類
//問題:為什么不能在構造函數中寫Fruit?因為生成對象后要持久化
//這個對象,但是數據庫的表中不能插入另一個類的值,寫上null又不
//大合適,所以就去掉它
public class Address {
private Integer aid;
private String nation;
private String postcode;
private Fruit fruit;
public Address() {
}
public Address(String nation, String postcode) {
super();
this.nation = nation;
this.postcode = postcode;
}
public Integer getAid() {
return aid;
}
public void setAid(Integer aid) {
this.aid = aid;
}
public Fruit getFruit() {
return fruit;
}
public void setFruit(Fruit fruit) {
this.fruit = fruit;
// fruit.setAddress(this);
}
public String getNation() {
return nation;
}
public void setNation(String nation) {
this.nation = nation;
}
public String getPostcode() {
return postcode;
}
public void setPostcode(String postcode) {
this.postcode = postcode;
}
}
修改Fruit類:
package Yuchen.Joto.business.entity;
//持久化類(花類),注意因為采用的是hilo的方式獲得id,所以需要有setid的方法
public class Fruit {
private Integer fid;//hibernate中的id不能識別int
private String name;
private String comments;
private int price;
private Address address;//一朵花對應一個地址
public Fruit() {
super();
}
public Fruit(String name, String comments, int price) {
super();
this.name = name;
this.comments = comments;
this.price = price;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
address.setFruit(this);//因為當你給一個花設置產地的時候
//該產地也有了花
}
public String getComments() {
return comments;
}
public void setComments(String comments) {
this.comments = comments;
}
public Integer getFid() {
return fid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price)
posted on 2007-08-21 18:18 小鋒 閱讀(386) 評論(0) 編輯 收藏 所屬分類: J2EE