日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Hiernate 笔记

發(fā)布時間:2025/3/20 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Hiernate 笔记 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

目錄

1.框架好處: 1
2.三大框架 1
3.Hibernate 簡介: 1
4.Hibernate詳細(xì): 1
5.使用Hibernate流程,五步 1
6. 使用Hibernate操作數(shù)據(jù)庫七步: 1
7. Hibernate里的[異常]認(rèn)識 2
8. javabean映射文件里配置時的 主鍵生成策略 3
9. Hibernate關(guān)于對象的三種狀態(tài)(javabean實(shí)例對象的三種狀態(tài)) 3
10. 增、刪、改操作 3
11. 通過id查詢 (get與load方法的區(qū)別) 3
12. 多表關(guān)聯(lián)的分類 4
13. 實(shí)現(xiàn)多表關(guān)聯(lián)步驟 4
14. 配置兩張表之間的關(guān)聯(lián)關(guān)系 4
15. 級聯(lián)(cascade)操作的實(shí)現(xiàn) 5
16. 映射文件里的關(guān)聯(lián)關(guān)系的一些屬性inverse、cascade、lazy、fetch、batch-size、property-ref… 5
17. Hibernate里的三種查詢(HQL、SQL、條件查詢) 6
1. HQL(Hibernate Query Language) :可實(shí)現(xiàn)分頁 6
3. SQL查詢(Structs Query Language):查的是表 7
3.條件查詢(criteria:標(biāo)準(zhǔn),規(guī)范) 8
4. 條件查詢——示例查詢:QBE(Query By Example) 9
5. 條件查詢——統(tǒng)計、分組 9
18.命名SQL調(diào)用存儲過程(用得少) 10
19.Hibernate里的緩存 11
1. 緩存有三種: 11
2. 緩存的范圍【遞增】 11
3. 一級緩存的體現(xiàn) 11
4 二級緩存 11
5 . 使用查詢緩存的步驟 12
20. 逆向工程,參照Hibernate逆向工程文檔 12
21. Hibernate+servlet實(shí)現(xiàn)Web工程訪問操作 12
22.注解:詳解參考Hibernate注解 12

1.框架好處:

安全、穩(wěn)定、寫業(yè)務(wù)邏輯代碼容易、提高了開發(fā)效率

2.三大框架

a) Hibernate:針對數(shù)據(jù)庫
b) Structs:針對servlet
c) Spring:它是一個容器,管理框架

3.Hibernate 簡介:

作者:Gavin King 2003年9月加入JBoss進(jìn)行全職開發(fā)
定義: 對象(類的實(shí)例)關(guān)系映射框架(Object Relation Mapping),也叫ORM框架。Hibernate就是一種流行的 ORM框架。
jdbc開發(fā)效率低,代碼冗余,重復(fù)工作多;Hibernate解決了該缺陷。
它可對jdbc進(jìn)行輕量級封裝,將javaBean對象和數(shù)據(jù)庫的表建立對應(yīng)關(guān)系

4.Hibernate詳細(xì):

1) 將數(shù)據(jù)庫連接的信息,放到它自己的配置文件里去
2) 它有一個或多個映射文件,就是為了將javabean與數(shù)據(jù)庫的表對應(yīng)起來(表中列與javabean里的屬性一一對應(yīng))
3) Hibernate所在dao層,也稱持久層,可將數(shù)據(jù)保存到數(shù)據(jù)庫中(硬盤中)
4) 使用Hibernate的基本流程是:配置Configuration對象、產(chǎn)生SessionFactory、創(chuàng)建session對象,啟動事務(wù),完成CRUD操作,提交事務(wù),關(guān)閉session。
5) 使用Hibernate時,先要配置hibernate.cfg.xml文件,其中配置數(shù)據(jù)庫連接信息和方言等,還要為每個實(shí)體配置相應(yīng)的hbm.xml文件,hibernate.cfg.xml文件中需要登記每個hbm.xml文件。
6) 在應(yīng)用Hibernate時,重點(diǎn)要了解Session的緩存原理,級聯(lián),延遲加載和hql查詢。

5.使用Hibernate流程,五步

a) 創(chuàng)建一個Web工程,將jar包放到工程里去:WebRoot的WEB_INF的lib里
b) 配置總配置文件 :hibernate.cfg.xml文件,一般放在src目錄下。配置相關(guān)數(shù)據(jù)庫連接信息。cfg: configuration 配置
c) 寫JavaBean,再寫針對javabean與表的映射文件,命名:對象名.hbm.xml。一般放在與javabean同級的目錄里。注:在映射文件里配置表的字段時,配置順序必須與表的字段的順序一致。hbm: hibernate mapping 映射

<class name="com.model.Employee" table="employee"><!-- 1.配置主鍵 <id name="id" 中name值對應(yīng)的是javaBean的屬性--><id name="id" type="java.lang.Integer"><!-- column標(biāo)簽里配置的是對應(yīng)表里的id列 --><column name="id" /> <!— 主鍵生成策略之一:increment :查到主鍵的最大值,然后自增1 --> <generator class="increment"/> </id><!-- 2.配主鍵以外的字段--><!-- 這里是javabean的屬性:name值與屬性對應(yīng) --><property name="name" type="java.lang.String" ><!-- 這里是表里的字段:name值與字段對應(yīng) --><column name="name" length="20" /></property> <!-- 有多個字段時,配置的property順序得與表中字段一致 --> </class>

d) 將javabean對應(yīng)的映射文件配置到hibernate.cfg.xml總配置文件里去:包名+文件名(帶.hbm.xml后綴),多個包之間用/隔開。即在總配置文件最后加下面一行代碼:

e) 通過hibernate的相關(guān)類(當(dāng)前是Test類)使用javabean,最終操作數(shù)據(jù)庫。

6. 使用Hibernate操作數(shù)據(jù)庫七步:

1. 讀取并解析配置文件
Configuration conf = new Configuration().configure();
2. 讀取映射信息,創(chuàng)建SessionFactory(session工廠里可建多個同樣session)
SessionFactory sessionFactory = conf.buildSessionFactory();
3. 打開Session
Session session = sessionFactory.openSession();
4. 打開一個事務(wù)Transaction
Transaction tx = session.beginTransaction();
5. 在事務(wù)里面對數(shù)據(jù)庫進(jìn)行增刪改查
Student stu=new Student();
stu.setSname(“李小龍”);
stu.setSid(8);
session.save(stu); //增
6. 提交或回滾事務(wù)
tx.commit();
注:Hibernate是在提交事務(wù)時將數(shù)據(jù)持久化的,不提交的話,都不走Hibernate里封裝的sql語句,所以不會持久化。有了Spring以后,就用新的事務(wù)了,就不用Transaction
tx.rollback;放在catch里,如果出現(xiàn)問題就回滾撤銷之前的操作。
7. 關(guān)閉Session(釋放資源)
session.close(); //關(guān)閉session
sessionFactory.close();//關(guān)閉session工廠

7. Hibernate里的 [異常 ] 認(rèn)識

  • session的空針針問題:沒有打開服務(wù):services.msc
  • 在調(diào)用hibernate的save()方法時,主鍵沒插入值
    org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save(): com.zrgk.model.Student
    新單詞:Identifier 鑒定人 ,說明主鍵id有問題
  • 該異常是因?yàn)閖dk版本有問題java.lang.UnsupportedClassVersionError: com/test/Test : Unsupported major.minor version 51.0
  • 主鍵是null值,需要手動給主鍵賦值
    org.hibernate.TransientObjectException: The given object has a null identifier: com.zrgk.model.Student
    新單詞:manually assigned 手動指定
  • org.hibernate.HibernateException: ‘hibernate.dialect’ must be set when no Connection avalable
    少寫了個configure()也會導(dǎo)致上述錯誤,數(shù)據(jù)庫連接不正常好像也會出現(xiàn)此異常6。dialect是方言的意思,方言指定的是連的那個數(shù)據(jù)庫。
  • 下面異常主要是與數(shù)據(jù)庫沒有連接上
    Exception in thread “main” org.hibernate.exception.GenericJDBCException: Cannot open connection
  • 8. javabean映射文件里配置時的 主鍵生成策略

    1) assigned : 指定的(手動插入主鍵)
    2) increment : 找到主鍵的最大值后增1
    3) identity : 一致,由數(shù)據(jù)庫給值,前提是主鍵設(shè)成自增(orac le里主鍵不能設(shè)為自增,最多序列化)。一般用在mysql數(shù)據(jù)庫中
    4) native: 根據(jù)使用的數(shù)據(jù)庫自行判斷采用identity、hilo、sequence其中一種作為主鍵生成方式,靈活性很強(qiáng)。如果能支持identity則使用identity,如果支持sequence則使用sequence。
    5) sequence : 序列化,前提是要在Oracle里創(chuàng)建序列,與其他生成策略不同的是,還需多配置一個序列名

    <generator class="sequence"> <param name="sequence">seq_student_id</param> </generator>

    上面的seq_student_id是在Oracle里創(chuàng)建的序列的名字

    9. Hibernate關(guān)于對象的三種狀態(tài)(javabean實(shí)例對象的三種狀態(tài))

  • 瞬時狀態(tài)(transicent:’tr?n?ns /’tr?nz??ns):剛用new創(chuàng)建時的狀態(tài),這時數(shù)據(jù)沒有持久化(未入庫),并且此時對象并沒有放到session緩存里去
  • 持久狀態(tài)(persistent):已經(jīng)被持久化,且加入到了session緩存里【提交事務(wù)后】
  • 游離狀態(tài)(detached:de’tached):已經(jīng)被持久化(在內(nèi)存中),但不在session緩存中【關(guān)閉session后】
  • 10. 增、刪、改操作

    1. 添加 數(shù)據(jù)到數(shù)據(jù)庫

    用session調(diào)用 save()方法 或 saveOrUpdate()方法
    saveOrUpdate()方法分情況
    1) 主鍵生成策略是assigned
    當(dāng)表中已有插入主鍵值時,則先查詢再修改
    當(dāng)表中沒有插入主鍵值時,則先查詢再插入
    2) 主鍵生成策略是sequence
    當(dāng)表中已有插入主鍵值時,則執(zhí)行修改
    當(dāng)表中沒有插入主鍵值時,則執(zhí)行插入

    2. 刪除

    1) 若不指定主鍵,不報錯,但什么也沒刪除
    2) 如果 只指定主鍵,而其他字段都不指定,當(dāng)映射文件里配置某字段如name時,后面加了not-null=”true”屬性時,則會報錯。

    <property name="name" type="java.lang.String" not-null="true" ><column name="name" length="20" /> </property>

    3) 若不指定主鍵,但指定了另外一個字段,也刪不了,是因?yàn)閯h除只能通過主鍵刪除

    3. 改:用session調(diào)用update()方法,,

    11. 通過id查詢 (get與load方法的區(qū)別),只能是Id

    //使用session調(diào)用get()方法 Employee employee=(Employee) session.get(Employee.class,1);//sesssion得回的值是Object類型,需要強(qiáng)轉(zhuǎn),1表示id //get里第一個參數(shù)是Class類型的,所以需要轉(zhuǎn)。Class表示類的類,數(shù)據(jù)庫的反射里有講到 System.out.println(employee.getName()+"||"+employee.getSalary()); //使用session調(diào)用load()方法,load的延遲是針對本表 Employee empl=(Employee) session.load(Employee.class, 3); System.out.println(empl.getName()+"--"+empl.getSalary());

    兩方法的區(qū)別:【面試題】
    使用get時,沒查回數(shù)據(jù)時返回null,而使用load沒有查回數(shù)據(jù)報org.hibernate.ObjectNotFoundException異常。
    get方法比較謹(jǐn)慎,它先從數(shù)據(jù)庫中查詢有沒有該數(shù)據(jù),有再從緩沖查詢,沒有則不查找,所以不會報錯。
    load方法認(rèn)為該數(shù)據(jù)一定存在數(shù)據(jù)庫中,所以可以放心使用代理來延遲加載(即在用到對象的屬性數(shù)據(jù)時才進(jìn)緩存里查詢,所以說,load拋出的異常是在使用該對象的數(shù)據(jù)時才拋出的),當(dāng)從load認(rèn)為數(shù)據(jù)庫有數(shù)據(jù)而直接從緩存里查時,由于實(shí)際數(shù)據(jù)庫中沒有該數(shù)據(jù),最后會導(dǎo)致異常。
    load方法的延遲是只針對本表的,至于另一張表是否延遲,取決于配置本表與另一表的關(guān)聯(lián)關(guān)系時的lazy屬性

    12. 多表關(guān)聯(lián)的分類

    多表關(guān)聯(lián)好處:可以操作一張表時可對其他相關(guān)進(jìn)行相關(guān)操作
    1. 按種類分:
    1) 一對多、多對一
    2) 多對多(有中間表)
    3) 一對一(用得少,因?yàn)檫@種情況可以直接將數(shù)據(jù)放進(jìn)一張表)
    2. 按方向分:
    1) 單向關(guān)聯(lián)
    2) 雙向關(guān)聯(lián)

    13. 實(shí)現(xiàn)多表關(guān)聯(lián)步驟

  • 把相關(guān)的多張表在數(shù)據(jù)庫中建完整
  • 寫相關(guān)表的javabean以及對應(yīng)的映射文件(外鍵不能配進(jìn)property屬性里)
  • 配置多表之間的關(guān)聯(lián)關(guān)系(在映射文件里配置)
    1) 在javabean里寫存另一表對象信息的屬性,若要存多個時用Set集合存放
    2) 在操作表的javabean對應(yīng)的映射文件里配置關(guān)聯(lián)關(guān)系,雙向時,都要配:
  • <set name="employees" ><!-- employees對應(yīng)的是部門的javabean里的存員工信息的屬性 --><key column="deptnum" ></key><!-- deptnum是員工表的部門外鍵 --><one-to-many class="com.model.Employee"/><!-- 獲得員工表路徑 --> </set>

    4.把相關(guān)的映射文件加入到Hibernate的總配置文件里去

    14. 配置兩張表之間的關(guān)聯(lián)關(guān)系

  • 配置一對多的關(guān)聯(lián)關(guān)系[不管一對多,還是多對一,都需要配兩表之間設(shè)定的那個外鍵]
  • <!-- 配置部門與員工的一對多的關(guān)聯(lián)關(guān)系 --> <set name="employees" > <!-- name值employees是部門javabean存員工信息的屬性 --><key column="deptnum" ></key> <!-- deptnum是員工表的部門外鍵 --><one-to-many class="com.model.Employee"/> <!-- 獲得員工javabean路徑 --> </set>
  • 配置多對一的關(guān)聯(lián)關(guān)系[不管一對多,還是多對一,都需要配兩表之間設(shè)定的那個外鍵]
  • <!-- 配置員工與部門 多對一 的關(guān)聯(lián)關(guān)系 --> <many-to-one name="dep" column="deptnum" class="com.model.Dept" cascade="all"></many-to-one><!-- dep是員工javabean里的存部門信息的屬性,deptnum是員工表的部門外鍵,class里值是部門javabean的路徑 cascade是級聯(lián)操作-->

    因?yàn)槎鄬σ粫r,外鍵是主表的屬性,所以不需要 key 標(biāo)簽配外鍵,直接一行搞定

  • 配置多對多的關(guān)聯(lián)關(guān)系
  • <!-- 配置員工與項(xiàng)目的 多對多 的關(guān)聯(lián)關(guān)系 --> <set name="projects" table="ep" cascade="all"><!-- projects是員工表存項(xiàng)目信息的屬性,ep是中間表,cascade是級聯(lián)操作 --><key column="eid"></key><!-- 中間表 對應(yīng)的員工外鍵 --><many-to-many column="pid" class="com.model.Project" ></many-to-many> <!--pid是中間表 對應(yīng)的項(xiàng)目外鍵 --> </set>
  • 配置 一對一 的關(guān)聯(lián)關(guān)系
  • <!-- 配置員工表與妻子表 一對一 的關(guān)聯(lián)關(guān)系 --><one-to-one name="wife" class="com.model.Wife" property-ref="employee"></one-to-one> <!-- wife是員工表存妻子信息的屬性, class是妻子javabean的路徑,property-ref屬性表示參照的是妻子表的employe屬性 --><!-- 配置妻子表與員工表的一對一關(guān)聯(lián)關(guān)系,也可以用many-to-one來實(shí)現(xiàn) ,它的性能要優(yōu)于one-to-one--><many-to-one name="employee" column="empId" class="com.model.Employee" cascade="all" unique="true"></many-to-one><!-- employee是妻子表存員工信息的屬性, empId是妻子表的員工外鍵,class值是員工類的路徑 unique="true",unique=“mpId”表示唯一 -->

    注:在一對一的關(guān)聯(lián)關(guān)系里,則不需要使關(guān)聯(lián)的主鍵生成策略設(shè)成:assigned,但在測試類里面,必須在兩個javabean里聲明存對方實(shí)例化對象的屬性,這樣才能使外鍵值自動插入

    15. 級聯(lián)(cascade)操作的實(shí)現(xiàn)

    配了它,說明能對對象進(jìn)行級聯(lián)操作:比如插入時,能同時插入相關(guān)聯(lián)的表,已有則更新;它有4個屬性:
    1. save-update : 對新增或修改進(jìn)行級聯(lián)
    2. delete : 對刪除操作進(jìn)行級聯(lián)
    3. all : 對所有操作(增刪改)進(jìn)行級聯(lián)
    4. none : 對所有操作都不級聯(lián)
    將cascade配置在主表(測試時,調(diào)用像save方法的操作時,括號里傳的對象所對應(yīng)的表就是主表)對應(yīng)的映射文件里,如下面配置員工與部門的關(guān)聯(lián)關(guān)系(多對一):

    <many-to-one name="dep" column="deptnum" class="com.model.Dept" cascade="all"></many-to-one> <!-- dep是員工javabean里的存部門的屬性,deptnum是員工表存的部門主鍵id字段,class里值是部門javabean的路徑 , cascade是級聯(lián)操作-->

    要實(shí)現(xiàn)級聯(lián)操作,還需將主表a級聯(lián)的表b對應(yīng)的javabean對應(yīng)的映射文件里的主鍵生成策略設(shè)置為:assigned。
    之所以要設(shè)成assigned,是因?yàn)槿绻窍駃ncrement這種生成策略,如果執(zhí)行的級聯(lián)操作里的主鍵在b表中存在,則會執(zhí)行更新操作;但是,如果級聯(lián)操作里的主鍵值是b表中沒有的,則不會執(zhí)行插入操作了。

    <id name="did" type="java.lang.Integer"><column name="did" /><generator class="assigned"/> </id>

    注:在一對一的關(guān)聯(lián)關(guān)系里,則不需要使關(guān)聯(lián)的主鍵生成策略設(shè)成:assigned, 在測試類里面,必須在兩個javabean里聲明存對方實(shí)例化對象的屬性,這樣才能使外鍵值自動插入

    16. 映射文件里的關(guān)聯(lián)關(guān)系的一些屬性inverse、cascade、lazy、fetch、batch-size、property-ref…

  • 控制反轉(zhuǎn)(invserse):該屬性指定了關(guān)聯(lián)的方向性問題,誰有主動權(quán),那么其他數(shù)據(jù)就依據(jù)它而變動。如,學(xué)生表為主動表且有班級外鍵cid,如果我們操作學(xué)生表插入數(shù)據(jù)時,新增學(xué)生,新增班級,但就是不寫學(xué)生表外鍵,學(xué)生和班級插入成功后,卻會發(fā)現(xiàn)班級外鍵沒有插入值(照理說,新班級與新學(xué)生同時插入的,那么新增學(xué)生的外鍵應(yīng)該有值)。這是是因?yàn)閷W(xué)生表和班級表配置關(guān)聯(lián)關(guān)系時,沒有設(shè)置控制反轉(zhuǎn)屬性,就默認(rèn)為inverse=”false”,即默認(rèn)都是主動表,這就導(dǎo)致了上面插入時,外鍵不跟著插入,兩張表都有主動權(quán)
  • 級聯(lián)操作(cascade):使得操作一張表時,另一張表也跟著操作。如,在向?qū)W生表插入數(shù)據(jù)時,也同時向班級表里插入數(shù)據(jù),要執(zhí)行成功,則主表(這兒是學(xué)生表)里配置學(xué)生與班級的關(guān)聯(lián)關(guān)系時必須有cascade屬性,且還有個前提就是,級聯(lián)表(班級表)的主鍵生成策略必須是assigned.
  • 延遲加載(lazy): 需要用到某數(shù)據(jù)時,才從緩存里去取,取不到就報錯。
    a) lazy=”true” : 延遲加載,默認(rèn)為true,當(dāng)session關(guān)閉后(緩沖區(qū)不存在了)就取不到值了
    b) lazy=”false” : 不延遲加載,直接從數(shù)據(jù)庫里取
    c) lazy=“ture” 這個延遲加載是針對關(guān)聯(lián)表的,主表是否延遲加載,取決于用的是load方法還是get方法;load方法的延遲針對主表,不能影響到關(guān)聯(lián)表。
  • fetch: 譯為:拿來。都是左外連接。默認(rèn)都為join,即一個sql語句
    a) fetch=”join” :查詢回來時只有一個sql語句
    b) fetch=”select ” :有多個sql語句
    c) fetch=”subselect” : 有多個sql語句
  • 批處理(batch-size):規(guī)定一次處理的條數(shù)據(jù),默認(rèn)1條。這樣可以提高效率。合理值為:2-10,batch-size=”2”
    要區(qū)分開的是,總配置文件里的批處理,指的是整個容器里的批處理,即整個容器一次性能處理多少條數(shù)據(jù)
  • 屬性參考(property-ref):用于多對一和一對一的關(guān)聯(lián)關(guān)系里,不能用于多對多。表示引用關(guān)聯(lián)表的javabean屬性
    如在學(xué)生表映射文件里有學(xué)生與學(xué)生證的關(guān)系配置:
  • <one-to-one name="card" class="com.zrgk.model.Card" property-ref="student"></one-to-one>

    card是學(xué)生表里存學(xué)生證信息的屬性,class寫學(xué)生證javabean的路徑,student表示學(xué)生證類里存學(xué)生信息的屬性
    有了property-ref就不需要外鍵了

    17. Hibernate里的三種查詢(HQL、SQL、條件查詢)

    1. HQL(Hibernate Query Language) :可實(shí)現(xiàn)分頁

    Sql查詢與Hql查詢大同小異,主要的區(qū)別是Sql查的是表,而Hql查的是表對應(yīng)的javabean類,都可實(shí)現(xiàn)分頁
    1. 它是根據(jù)javabean來查詢數(shù)據(jù)的,關(guān)鍵字也不區(qū)分大小寫,但是類名及屬性名區(qū)分大小寫
    2. 使用步驟:
    a) 得到session:與之前一樣
    b) 寫HQL語句: String hql=” from com.zrgk.model.Student “;
    c) 創(chuàng)建Query對象:Query query=session.createQuery(hql);
    d) 執(zhí)行查詢: List list=query.list();
    e) 處理查詢結(jié)果:用迭代器遍歷 ( 沒有泛型時,不知道類型,只能用迭代器),泛了型也可用迭代器
    3) 寫HQL語句時,用到的那個類最好寫全路徑:
    HQL語句可簡化:String hql=” from com.zrgk.model.Student “;
    不寫全路徑就簡化為:String hql=” from Student “;
    /注意了:當(dāng)用的是select的sql語句時,不能有號,在遍歷時,且只能用Object[]強(qiáng)轉(zhuǎn),
    * 如果是直接用的from的查詢sql語句,則在遍歷時,只能用Employee強(qiáng)轉(zhuǎn)
    * */
    1) 有占位符 ? 時
    String hql=”select sid,sname from com.zrgk.model.Student where sname=? “;
    Query query=session.createQuery(hql);
    query.setString(0, “韋小寶”);//綁定問號,占位符下標(biāo)是從0開始的
    //執(zhí)行查詢
    List list=query.list();//后面操作一樣

    2 hibernate里的 分頁

    query.setFirstResult(0);//從第幾條開始取: 0代表是第一條數(shù)據(jù)
    query.setMaxResults(5);//取5條
    數(shù)據(jù)多時,則從第幾條開始取是動態(tài)的,需要當(dāng)前頁這個變量得出:(currenPage-1)*5

    3. SQL查詢(Structs Query Language):查的是表

    Sql查詢與Hql查詢大同小異,主要的區(qū)別是Sql查的是表,而Hql查的是表對應(yīng)的javabean類,都可實(shí)現(xiàn)分頁

    public static void main(String[] args) {Session session = null;Transaction tx = null;try {//1.通過Hibernateo的靜態(tài)方法得到sessionsession = HibernateUtil.getSession();tx = session.beginTransaction();/* //2.寫sql語句* String sql="select * from student";* * //3.創(chuàng)建 Query對象 query* query=session.createSQLQuery(sql).addEntity(Student.class);* addEntity()方法將數(shù)據(jù)封裝進(jìn)Student的實(shí)體對象里 Entity:實(shí)體,實(shí)質(zhì)查的多表有多個表的字段時,就不能這樣用了喲。要么重新建個JavaBean或者在List里存Map* //4.執(zhí)行查詢 * List list=query.list();//由于前面的封閉,所以list存的是對象* * //5.處理查詢結(jié)果 * Iterator it=list.iterator();* while(it.hasNext()){* Student s=(Student)it.next(); * System.out.println("學(xué)生姓名:"+s.getSname()); * }*//**hibernate里多表連查時的處理*/String sql = "select s.sname,c.cname from student s,cla c where s.cid=c.cid";// 創(chuàng)建 Query對象 Query query = session.createSQLQuery(sql);//由于是多表聯(lián)查,所以查回的數(shù)據(jù)不能封裝進(jìn)一個javabean對象里,放進(jìn)數(shù)組里 //可以重建一個JavaBean,或是用List里存Map里的方法。List list = query.list();//存的是數(shù)組// 處理查詢結(jié)果:由于list沒有泛型,所有用迭代器遍歷Iterator it = list.iterator();while (it.hasNext()) {//因?yàn)榉祷氐膬蓚€表的兩個字段,所以用object[]數(shù)組來接收再處理Object[] obj=(Object[])it.next();System.out.println(obj[0]);System.out.println(obj[1]);}// 6.提交事務(wù)tx.commit();// 提交的時候才是真正把數(shù)據(jù)持久化到數(shù)據(jù)庫中 對象處于持久狀態(tài)System.out.println("執(zhí)行成功");} catch (HibernateException e) {tx.rollback();e.printStackTrace();} finally {// 7.關(guān)閉sessionsession.close(); // 對象處于游離狀態(tài)} }

    3.條件查詢(criteria:標(biāo)準(zhǔn),規(guī)范)

    1)都在注釋里:也可實(shí)現(xiàn)分頁

    public static void main(String[] args) {Session session=null;Transaction tx=null;try{session=HibernateUtil.getSession(); //得到sessiontx=session.beginTransaction(); //打開事務(wù)//1.創(chuàng)建條件查詢對象Criteria cri=session.createCriteria(Employee.class);//2.Criteria里的add方法可以追加查詢條件。Restrictions:限制,Criteria:標(biāo)準(zhǔn)cri.add(Restrictions.le("salary",3457.0));//less:小于3457.0【salary既可是屬性名,也可是表的字段名】//3.Criteria里的addOrder方法用來排序:默認(rèn)升序asccri.addOrder(Order.desc("salary")); //添加排序條件,先按工資降序排cri.addOrder(Order.desc("id")); //添加排序備件,再按id降序排//4.查詢所有,組裝成的list集合List list=cri.list(); //5.前面list沒有泛型,所以必須用迭代器處理查回結(jié)果,泛型后也可以用Iterator em=list.iterator();while(em.hasNext()){Employee employee=(Employee) em.next();System.out.println(employee.getName()+"-"+employee.getSalary());}tx.commit();}catch (Exception e) {tx.rollback();e.printStackTrace();}finally{session.close();} }

    2)Restrictions的幾個方法。還有in,表查詢范圍,里面?zhèn)鞯氖羌匣驍?shù)組

    //用Criteria里的add方法可以追加查詢條件。Restrictions:限制cri.add(Restrictions.ge("money", 16000.00)); //大于等于:gecri.add(Restrictions.eq("sname","劉德華")); //等于:eqcri.add(Restrictions.gt("money", 16000.00)); //大于:gtcri.add(Restrictions.le("money", 16000.00)); //小于:le less thanscri.add(Restrictions.like("sname", "%韋%")); //模糊查詢,與之前一樣用%cri.add(Restrictions.between("money", 10000.00,17000.00));//兩者之間

    4. 條件查詢——示例查詢:QBE(Query By Example)

    public static void main(String[] args) {Session session=null;Transaction tx=null;try{session=HibernateUtil.getSession(); //得到sessiontx=session.beginTransaction(); //得到事務(wù)//創(chuàng)建條件查詢對象Criteria cri=session.createCriteria(Employee.class);Employee em=new Employee();em.setName("張三豐");//有這個則是 "按名字查詢",沒有的話則走查詢所有/*需要【注意】的是,在示例查詢里,需要將所有javabean的屬性的類型寫成封裝類,如,將int寫成Integer類。如果就寫成int型,那么示例查詢將認(rèn)為給javabean屬性賦了默認(rèn)值0,它會按0去查詢,而實(shí)際上是沒有0的,這樣就會查不到數(shù)據(jù)。char對應(yīng)的封類是Character,double對應(yīng)的是Double*/cri.add(Example.create(em)); //執(zhí)行示例查詢//分頁cri.setFirstResults(0); cri.setMaxResults(6);//按id排序cri.addOrder(Order.asc("id"));List list=cri.list();//數(shù)據(jù)放進(jìn)list里//前面list沒有泛型,所以必須用迭代器,泛型后也可以迭代器Iterator<Employee> e=list.iterator();while(e.hasNext()){Employee employee=e.next();System.out.println(employee.getName()+"-"+employee.getSalary());}tx.commit();}catch (Exception e) {tx.rollback();e.printStackTrace();}finally{session.close();} }

    5. 條件查詢——統(tǒng)計、分組:查回的是一行一列

    分組要注意如:select name,sex from employee group by name ,sex ,查詢的字段與分組的字段必須一致,順序可以顛倒。

    /**統(tǒng)計,也屬性于條件查詢。Projections:映射*/session=HibernateUtil.getSession(); //得到sessiontx=session.beginTransaction(); //打開事務(wù)//創(chuàng)建條件查詢對象Criteria cri=session.createCriteria(Employee.class);/**屬性名不能寫外鍵,且區(qū)分大小寫.Projections:映射*///cri.setProjection(Projections.rowCount()); //調(diào)用count方法查數(shù)據(jù)條數(shù)//cri.setProjection(Projections.countDistinct("sex"));//去重條數(shù),空也算,所以返回3條//cri.setProjection(Projections.rowCount()); //統(tǒng)計Student類里的總條數(shù)//cri.setProjection(Projections.avg("money")); //求平均值//cri.setProjection(Projections.max("salary")); //求最大值//cri.setProjection(Projections.min("sid")); //求最小值//cri.setProjection(Projections.count("sex")); //根據(jù)一個屬性來求去掉null后的總條數(shù)//cri.setProjection(Projections.sum("money")); //求和/**分組*/cri.setProjection(Projections.groupProperty("sex"));Employee em=new Employee();//em.setName("張三豐");//有這個則是 "按名字查詢",沒有的話則走查詢所有cri.add(Example.create(em));//執(zhí)行示例查詢List list=cri.list();//數(shù)據(jù)放進(jìn)list里//前面list沒有泛型,所以必須用迭代器,泛型后也可以迭代器Iterator<Employee> e=list.iterator();/**聚合函數(shù)返順的值只有一行一列,所以直接打印*/while(e.hasNext()){ System.out.println(e.next());}tx.commit();

    18.命名SQL調(diào)用存儲過程(用得少)

    它是在映射文件里的class標(biāo)簽外面寫的命名sql,然后在測試類里調(diào)用命名sql的形式。

    1. 在配置文件里的命名sql

    <sql-query name="insertStudent">insert into student(id,sname,sex) values(?,?,?) 這兒寫sql語句,不能寫分號 <!-- 因?yàn)槊鹲ql寫在class標(biāo)簽外面,所以與class里配置的主鍵生成策略無關(guān), 所以,這里必須手動插入主鍵id --> </sql-query>

    insertStudent是后面調(diào)用時的關(guān)鍵字
    如果sql語句寫在了數(shù)據(jù)庫的存儲過程里,則只需在里面調(diào)用存儲過程即可,如下:

    <!--調(diào)用插入記錄的存儲過程--><sql-query name="loginInsert"> {call login_insert(?,?,?)} <!-- 調(diào)用數(shù)據(jù)庫里插入的存儲過程:login_insert。這在講Oracle調(diào)用存儲過程時的代碼里有講 --></sql-query>

    2. 在測試類里的代碼

    { session = HibernateUtil.getSession();// 得到sessiontx = session.beginTransaction(); //打開事務(wù)//通過insertStudent調(diào)用配置文件里的命名sql Query query=session.getNamedQuery("loginInsert "); query.setInteger(0, 77); //給第一個?賦值query.setString(1, "蕭敬騰"); //給第二個?賦值query.setCharacter(2, '1'); //給第三個?賦值query.executeUpdate(); //執(zhí)行sql語句tx.commit();// 提交事務(wù) }

    19.Hibernate里的緩存

    cache [k??]
    n. 貯藏所; 貯藏物; 快速緩沖貯存區(qū)

    1. 緩存有三種:

  • 一級緩存: session緩存,它是Hibernate必須帶的
  • 二級緩存: sessionFactory的緩沖,它是可配置的,空間比session大,sessionFactory是管理session的工廠
  • 查詢緩存: 與二級存類似,它依托二級緩存
  • 2. 緩存的范圍【遞增】

  • 事務(wù) 范圍內(nèi)的緩存,即session緩存
  • 進(jìn)程 范圍內(nèi)的緩存
  • 集群 范圍內(nèi)的緩存,像多個TomCat組成的群就是集群
  • 3. 一級緩存的體現(xiàn)

    當(dāng)兩次取學(xué)生信息時,第一次執(zhí)行sql后,從數(shù)據(jù)庫里取回數(shù)據(jù)后存進(jìn)session的緩存里(當(dāng)然也打印顯示),當(dāng)后面還有查詢語句,用的同一個session時,則不會再走sql語句了,它是直接從session緩存里取的值

    4 二級緩存

    二級緩存能夠被所有session所共有,它有以下幾種緩存插件:
    a.第一種緩存插件:EHCache 來源于:org.hibernate.cache.EhCacheProvider 支持查詢緩存 | 進(jìn)程范圍內(nèi)的緩存
    b.第二種緩存插件:OSCache 來源于: org.hibernate.cache.OSCacheProvider 支持查詢緩存 | 進(jìn)程范圍內(nèi)的緩存
    c.第三種緩存插件:SwarmCache 來源于:org.hibernate.cache.SwarmCacheProvider 不支持查詢緩存 | 集群范圍內(nèi)的緩存
    d.第四種緩存插件:JBossCache 來源于:org.hibernate.cache.TreeCacheProvider 支持查詢緩存 | 集群范圍內(nèi)的緩存

    使用二級緩存步驟:

    1. 選擇合適的緩存插件,配置它自帶的配置文件信息
    1) 在需要二級緩存的javabean類的映射文件里配置如下代 碼:

    <!-- 讀/寫緩存:可以只配read,即只能讀 --> <cache usage="read-write"/><!--標(biāo)明可以對Student進(jìn)行讀寫 -->

    2) 在總配置文件hibernate.cfg.xml里開啟二級緩存,并配置來源類

    <!-- 開啟二級緩存 --> <property name="hibernate.cache.use_second_level_cache"> true </property> <!—配置來源類 --> <property name="hibernate.cache.provider_class"> org.hibernate.cache.EhCacheProvider </property>

    2. 選擇需要使用二級緩存的持久化類(javabean類),并設(shè)置它的二級緩存的一些信息

    <!-- 配置 student使用二級緩存,配在EHCache插件(在src下的ehcache.xml文件)里 --><cache name="com.pb.hibernate.po.Student"<!—Student的javabean路徑 -->maxElementsInMemory="10000"eternal="false"timeToIdleSeconds="300"timeToLiveSeconds="600"overflowToDisk="true" />

    使用二級緩存的情景:

  • 很少被修改的數(shù)據(jù),像常量
  • 不是很重要的數(shù)據(jù),允許偶出現(xiàn)并發(fā)問題的數(shù)據(jù)
    并發(fā)問題:如同一張票被多人搶到
  • 5 . 使用查詢緩存的步驟

    查詢緩存依托二級緩存,所以先得配好二級緩存。由于查詢緩存依托二級緩存,所以前面關(guān)掉session1后,查同樣的數(shù)據(jù)時,不會走sql,用session2時,能直接從二級緩存里取到數(shù)據(jù)
    1) 在總配置文件里開啟查詢緩存 hibernate.cache.use_query_cache
    true
    2) 在程序(測試調(diào)用類)中手動啟動查詢緩存 query.setCacheable(true);
    //手動開啟查詢緩存:setCacheable(true),然后把查詢到的結(jié)果集放到查詢緩存 里去
    List stus= query.setCacheable(true).list();

    20. 逆向工程,參照Hibernate逆向工程文檔

    逆向工程,是根據(jù)數(shù)據(jù)庫的表,自動生成,總配置文件,javabean類,以及映射文件,生成實(shí)體類和文件可能會有些問題,自己修改下即可。以后盡量自己配置,這樣生的總會有這樣那樣的問題,知道怎么用就行。具體見詳解鏈接

    21. Hibernate+servlet實(shí)現(xiàn)Web工程訪問操作

    和以前一樣建servlet和頁面及其他,只是多了個Hibernate。多個總配置文件,以及javabean的映射文件,還有就是在實(shí)現(xiàn)類里,用的是Hibernate的操作調(diào)用數(shù)據(jù)庫(session….Query…..等)。

    22.注解:詳解參考Hibernate注解

    1. 注解:用于減少Hibernate的映射文件,把映射文件合并到j(luò)avabean里去[實(shí)現(xiàn)javabean與數(shù)據(jù)庫表的關(guān)聯(lián)]

    優(yōu)點(diǎn):減少配置
    缺點(diǎn):分層相當(dāng)而言不是特別明顯,代碼可能會顯得混亂。
    a) 如果持久化類的屬性沒有規(guī)定注解,則只要名字一樣,則會自動映射過去。持久化類javabean類名與表名一致,這樣就自動映射。
    b) 如果javabean類名與表名不一樣,則用:@Table(name=”user”)映射
    如果屬性列名與表列名不一致,則用:@Column(name=”password”)映射

    @Entity @Table(name="user")//javabean類名與表名不一致的處理 public class User {@Id@Column(name="id")@GeneratedValue(strategy=GenerationType.AUTO) //主鍵生成策略:自動增長@SequenceGenerator(name="sequence的名字")//引用sequenceprivate int uid;//主鍵 自增 @Column(name="username",length=100)private String username;//用戶名@Column(name="password",length=100)private String password;//密碼@Column(name="group_id")private String groupId;public int getUid() {return uid;}public void setUid(int uid) {this.uid = uid; }

    c) 當(dāng)javabean類里的某個屬性a在表里不存在對應(yīng)的字段時,則必須在get方法上加忽略注解:@Transient
    這是因?yàn)?#xff0c;如果不忽略,則在查詢所有時,系統(tǒng)會按屬性a去數(shù)據(jù)庫查詢,由于數(shù)據(jù)庫沒有該字段,所以會報錯-Unknown cloumn

    2. 使用格式:@+注解關(guān)鍵詞

    3. 在hibernate里使用注解的步驟:

    1) 添加hibernate-annotations.jar包
    2) 使用注解配置持久化類及對象的屬性信息及關(guān)聯(lián)關(guān)系
    3) 使用AannoationiConfiguration建立工廠
    4) 在hibernate.cfg.xml配置文件里配持久化類

    4. 持久化類:跟Hibernate關(guān)聯(lián)上的javabean類

    5. Hibernate相關(guān)注解類介紹:具體點(diǎn)鏈接

    1) @Entity 相當(dāng)于將一個類聲明為一個實(shí)體bean(即生成一個持久化類 POJO類) entity:實(shí)體
    2) @Id 聲明了該實(shí)體bean的標(biāo)識屬性(相當(dāng)于數(shù)據(jù)庫表的主鍵處理)
    3) @GeneratedValue 定義主鍵的生成策略
    4) @Table 為實(shí)體bean映射表
    5) @UniqueConstraint 定義表中唯一約束
    6) @Lob 表示屬性將持久化為Blob或者Clob類型
    7) @Column 將屬性映射到表中的列
    8) @Transient 將忽略這個屬性 不用持久化到數(shù)據(jù)庫中去
    9) @NamedQuery 配置命名查詢
    10) @OneToOne 建立實(shí)體bean之間的一對一的關(guān)聯(lián)關(guān)系
    11) @OneToMany 配置一對多的關(guān)系
    12) @ManyToMany 配置多對多的關(guān)系
    13) @ManyToOne 配置多對一的關(guān)系

    6. 使用注解的測試類里得到session時,需要用AnnotationConfiguration工廠類

    //使用注解工廠的類
    AnnotationConfiguration annotationConfiguration=
    new AnnotationConfiguration();
    SessionFactory sessionFactory=
    annotationConfiguration.configure().buildSessionFactory();

    Session session=sessionFactory.openSession();//得到session

    總結(jié)

    以上是生活随笔為你收集整理的Hiernate 笔记的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。