Hiernate 笔记
目錄
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 映射
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)識
org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save(): com.zrgk.model.Student
新單詞:Identifier 鑒定人 ,說明主鍵id有問題
org.hibernate.TransientObjectException: The given object has a null identifier: com.zrgk.model.Student
新單詞:manually assigned 手動指定
少寫了個configure()也會導(dǎo)致上述錯誤,數(shù)據(jù)庫連接不正常好像也會出現(xiàn)此異常6。dialect是方言的意思,方言指定的是連的那個數(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)建序列,與其他生成策略不同的是,還需多配置一個序列名
上面的seq_student_id是在Oracle里創(chuàng)建的序列的名字
9. Hibernate關(guān)于對象的三種狀態(tài)(javabean實(shí)例對象的三種狀態(tài))
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”屬性時,則會報錯。
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)步驟
1) 在javabean里寫存另一表對象信息的屬性,若要存多個時用Set集合存放
2) 在操作表的javabean對應(yīng)的映射文件里配置關(guān)聯(lián)關(guān)系,雙向時,都要配:
4.把相關(guān)的映射文件加入到Hibernate的總配置文件里去
14. 配置兩張表之間的關(guān)聯(lián)關(guān)系
因?yàn)槎鄬σ粫r,外鍵是主表的屬性,所以不需要 key 標(biāo)簽配外鍵,直接一行搞定
注:在一對一的關(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)系(多對一):
要實(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í)行插入操作了。
注:在一對一的關(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…
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)表。
a) fetch=”join” :查詢回來時只有一個sql語句
b) fetch=”select ” :有多個sql語句
c) fetch=”subselect” : 有多個sql語句
要區(qū)分開的是,總配置文件里的批處理,指的是整個容器里的批處理,即整個容器一次性能處理多少條數(shù)據(jù)
如在學(xué)生表映射文件里有學(xué)生與學(xué)生證的關(guān)系配置:
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)用存儲過程即可,如下:
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. 緩存有三種:
2. 緩存的范圍【遞增】
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類的映射文件里配置如下代 碼:
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" />使用二級緩存的情景:
并發(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”)映射
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)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux系统下安装rz/sz命令及使用
- 下一篇: Strus2概览