Feng.Li's Java See

          抓緊時間,大步向前。
          隨筆 - 95, 文章 - 4, 評論 - 58, 引用 - 0
          數據加載中……

          hibernate簡述

          1. 什么是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">jdbcracle:thin127.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)

          posted on 2007-08-21 18:18 小鋒 閱讀(387) 評論(0)  編輯  收藏 所屬分類: J2EE

          主站蜘蛛池模板: 乌拉特中旗| 东丽区| 泗水县| 都昌县| 乌鲁木齐市| 武城县| 遂宁市| 广南县| 蒲江县| 灌阳县| 内江市| 永城市| 江都市| 福安市| 宁晋县| 资中县| 方山县| 普定县| 西丰县| 夹江县| 海宁市| 陆河县| 托克托县| 都江堰市| 九寨沟县| 江达县| 广灵县| 乌拉特前旗| 惠东县| 大荔县| 墨玉县| 镇宁| 涿州市| 鄂尔多斯市| 台州市| 丹东市| 苗栗市| 修文县| 汶上县| 中方县| 耒阳市|