第一篇:hibernate總結(jié)(共)
1、JPA是接口(是一套標(biāo)準(zhǔn)),hibernate是其實(shí)現(xiàn)
2、@Entity 表示這個(gè)類是實(shí)體類(javaBean)
3、@Id 表示主鍵(javaBean)
4、這樣寫在配置文件中要書寫映射
配置時(shí)不一樣,不用resouse了,也不用寫映射文件了;
但在測(cè)試時(shí)要用Configuration config = new AnnotationConfiguration(); 其他的都一樣了注:加入annotationjia包 :hibernate annotation jar包---ejb3 persistence jar包---
hibernate-common-annotations.jar包 ★在文檔中沒提到hibernate-common-annotations.jar包
5、若打@符號(hào)不提示可修改:windows--properties--搜索content--java--Editor--Content Assist然后改動(dòng)右下的Auto-Activation中的選項(xiàng);第一個(gè)表示提示的時(shí)間,越短表示提示的越快,;第二個(gè)表示在java類中是以 “.”號(hào)觸發(fā)的;第三項(xiàng)表示以@來(lái)觸發(fā)javadoc的;你需要把點(diǎn)三項(xiàng)的@改動(dòng)到第二項(xiàng)中就可以了,想快點(diǎn)提示,把第一項(xiàng)的時(shí)間該小點(diǎn);
6、常見的O/R Mapping Freamworks :hibernate / jdo/toplink/ibatis7、JPA他是O/R Mapping Freamworks框架的接口,像hibenate等框架實(shí)現(xiàn)這個(gè)接口;類比JDBC和實(shí)現(xiàn)它的眾多數(shù)據(jù)庫(kù)的驅(qū)動(dòng)
★
8、hiberante可以把你建好的表自動(dòng)生成類(通過逆向工程)
當(dāng)然也可以通過你建好的類幫你自動(dòng)生成對(duì)應(yīng)的表;
到底是先類還是先表????
解答: 純理論是先建類后見表, 你的類建好后可以夸數(shù)據(jù)庫(kù)建表,因?yàn)槲覀兪敲嫦驅(qū)ο缶幊蹋械钠瘘c(diǎn)都應(yīng)該是面向?qū)ο螅瑥拿嫦驅(qū)ο箝_始,所以說(shuō)純理論是先類后表;
實(shí)際中先表后類要比先類后表的多,因?yàn)榈谝弧]有hibernate時(shí)人們都習(xí)慣先表后類,這個(gè)習(xí)慣不好改了; 第二、建好數(shù)據(jù)庫(kù)表后往往要對(duì)數(shù)據(jù)庫(kù)表進(jìn)行優(yōu)化,比如說(shuō)建索引、建中間表、建視圖、建各種各樣的優(yōu)化,若用hibernate自動(dòng)生成,針對(duì)數(shù)據(jù)庫(kù)優(yōu)化的這些內(nèi)容hibernate是沒法幫你生成的9、通過轉(zhuǎn)換,引入log4j的配置文件輸出日志信息,想把日志信息輸出到配置文件中,改動(dòng)一下配置文件就行了(log4j.properties);
★ :注解寫在get方法上
★ 注解放在get方法上還是放在成員變量上?
解答:應(yīng)該放在get方法上,若放在成員變量上實(shí)際上破壞了java面向?qū)ο蟮姆庋b性,因?yàn)槌蓡T變量定義成private權(quán)限就是不讓直接訪問的,如果把注解放在其上,hibernate就可以直接去訪問你私有的成員變量(java反射訪問私有變量),甚至去修改你的私有成員變量
10、ID的自動(dòng)生成策略解答?(重點(diǎn)AUTO)
解答:若在id的get方法上只標(biāo)注@GeneratedValue相當(dāng)于用了AUTO,會(huì)根據(jù)你連得數(shù)據(jù)庫(kù)幫你用哪種生成id的方式;如果你連的是oracle會(huì)用sequence,但他建的序列名字是固定的名字~~HIBERNATE_SEQUENCE;
11、TableGenerator(表生成器),他適用于任何一種數(shù)據(jù)庫(kù),如你想讓你的數(shù)據(jù)庫(kù)跨平臺(tái)、連數(shù)據(jù)也跨平臺(tái),表生成器是一個(gè)好的選擇; 若用AUTO跨平臺(tái),以個(gè)缺點(diǎn)是若用的是
sequence,其序列名字是固定的~~~hibernate-sequence;
12、聯(lián)合主鍵:如果有幾列聯(lián)合做主鍵,其設(shè)計(jì)模式是,構(gòu)建一個(gè)主鍵類并實(shí)現(xiàn)Serializable
接口,重寫equals()方法和hashCode()方法,并有其get/set方法;然后在bena類中構(gòu)
建一個(gè)主鍵類屬性即可;
Serializable接口作用:把當(dāng)前類的對(duì)象序列化的序列化的作用:可以把一個(gè)對(duì)像直接寫到硬盤上,也可以直接從硬盤上讀取對(duì)像,還可以通過網(wǎng)
絡(luò)把對(duì)象傳到對(duì)方那去,或者對(duì)方把序列化得東西直接傳給我;
為什么要實(shí)現(xiàn)Serializable接口?
解答:Annotation項(xiàng)目中,對(duì)于Woman類,若在內(nèi)存中有多個(gè)Woman類對(duì)象,而每個(gè)Woman
類對(duì)象里都有個(gè)WomanPK(主鍵類)類對(duì)像,如果內(nèi)存滿了,要用虛擬內(nèi)存,就是把硬盤上的一
部分空間作為內(nèi)存來(lái)使用,這就需要把一部分Woman對(duì)象暫時(shí)先傳到硬盤上去,此時(shí)就需要用到
序列化了;
為什么要重寫equals()方法?
解答:用來(lái)保證唯一性的; 我們不僅要在數(shù)據(jù)庫(kù)中保證唯一性,還要在內(nèi)存中保證唯一性,在數(shù)據(jù)庫(kù)中通過主鍵來(lái)保證的,類比在內(nèi)存中的對(duì)象也要通過主鍵類對(duì)像來(lái)保證其唯一性,達(dá)到與
數(shù)據(jù)庫(kù)同步,所以在這種情況下應(yīng)該重寫equals和hashCode;所以說(shuō)既然用了聯(lián)合主鍵,就
應(yīng)該重寫equals和hashCode方法,而且他的邏輯還不能亂用,不能用父類里面的equals,兩個(gè)同樣的對(duì)象就視為同一個(gè)對(duì)象;
為什么要重寫hashCode()方法
解答:要查哈希表中的內(nèi)容是否相等時(shí)首先從hashCode查起;最簡(jiǎn)單的哈希表可看作是一
個(gè)表格或數(shù)組,里面有好多位置,每個(gè)位置放的是哈希值相同的對(duì)象,所以里面往往裝的是一個(gè)
鏈表;例如有兩個(gè)類A、B,他們的哈希值都是1,他們就會(huì)被放在哈希表中的同一個(gè)位置,若要
查詢哈希標(biāo)中某個(gè)類和哈希表中的那個(gè)類相同,首先要計(jì)算出這個(gè)類的哈希值,通過計(jì)算出的哈
希值直接定位到與這個(gè)哈希值相等的位置,然后循環(huán)遍歷出這個(gè)哈希值里面的對(duì)象,找出與哈希
標(biāo)中對(duì)象相同的對(duì)象;注:存放Woman對(duì)象時(shí),計(jì)算對(duì)象里面的主鍵類對(duì)象的哈希碼值(不是
計(jì)算對(duì)象的哈希碼值),然后存入哈希表中;
13、從數(shù)據(jù)庫(kù)中取一個(gè)對(duì)象的方法:get();和 load();二者區(qū)別?
解答:當(dāng)用session.get()去拿一個(gè)對(duì)象的時(shí)候,他馬上發(fā)出sql語(yǔ)句,從數(shù)據(jù)庫(kù)中取
出對(duì)象的值來(lái)把它裝到對(duì)象中去(此時(shí)對(duì)象中已有值了),不會(huì)產(chǎn)生延遲;
若用load()方法去拿對(duì)象時(shí),load生成的是一個(gè)代理對(duì)象(他并沒有對(duì)象的屬性值),他
并沒有真正的發(fā)出sql語(yǔ)句從數(shù)據(jù)庫(kù)中取出數(shù)據(jù),sql語(yǔ)句其實(shí)是在你需要拿那個(gè)對(duì)象的屬性
是才發(fā)出的,當(dāng)然從數(shù)據(jù)庫(kù)中拿屬性時(shí)肯定需要session對(duì)象,若session關(guān)閉會(huì)報(bào)錯(cuò);
若用get或load取數(shù)據(jù)時(shí),數(shù)據(jù)庫(kù)中沒有那條數(shù)據(jù),get會(huì)報(bào)錯(cuò),load不會(huì),因?yàn)闆]有
用對(duì)象的屬性,load就不會(huì)馬上發(fā)送sql語(yǔ)句,也就不會(huì)去連數(shù)據(jù)庫(kù);
☆ 判斷一個(gè)對(duì)象是代理對(duì)象還是普通對(duì)象?
解答:打印對(duì)象所在的類名; 如t對(duì)象System.out.println(t.class);
接受代理對(duì)象的類是實(shí)際類的子類;(拿屬性時(shí)要調(diào)用類中方法,代理類又沒有)
14、update()方法總結(jié)及注意事項(xiàng)?(注:★update方法會(huì)在commit時(shí)才發(fā)update語(yǔ)句)
解答:第一:用來(lái)更新detached狀態(tài)的對(duì)象,更新完成后對(duì)象轉(zhuǎn)為persistent狀態(tài);
第二:更新transisent狀態(tài)的對(duì)象會(huì)報(bào)錯(cuò);
第三:更新自己手動(dòng)設(shè)定id的transisent對(duì)象可以(前提是數(shù)據(jù)庫(kù)中有對(duì)應(yīng)的記錄)
第四:處于persistent狀態(tài)的對(duì)象若被改變,若跟原來(lái)(和緩存中的比較)的值不相同就會(huì)發(fā)
sql語(yǔ)句,發(fā)sql語(yǔ)句時(shí)會(huì)把所有字段都更新,若跟原來(lái)的值相同就不會(huì)發(fā)送sql語(yǔ)句;
第五:若在xml中設(shè)置成動(dòng)態(tài)更新,沒變的值是不會(huì)更新的,(他是把改過的值和在內(nèi)存中對(duì)應(yīng)的對(duì)象進(jìn)行比較,若值相同就不把這個(gè)字段夾在sql語(yǔ)句中,反之夾在sql語(yǔ)句中; 若對(duì)象
在內(nèi)存中不存在,會(huì)把所有字段都更新,即發(fā)送所有字段)(跨session)
若想跨session也想知更新改過的字段,用merge(s對(duì)象)方法(他會(huì)先從數(shù)據(jù)庫(kù)把對(duì)
應(yīng)的對(duì)象取出,然后比較在發(fā)update語(yǔ)句)
只更新部分字段建議用HQL(EJBQL)語(yǔ)句,面向?qū)ο蟮恼Z(yǔ)句;
15、saveOrUpdate()方法,沒id時(shí)肯定執(zhí)行save,有id且做了屬性改變執(zhí)行update方
法;
16、clear()方法:不管是get方法還是用load方法取對(duì)象都是先從緩存中查找(一級(jí)緩
存),如果緩存中沒有才會(huì)從數(shù)據(jù)庫(kù)中查找,調(diào)用clear方法會(huì)強(qiáng)制清空session緩存;
17、flush()方法:強(qiáng)制進(jìn)行從內(nèi)存到數(shù)據(jù)庫(kù)同步;在什么時(shí)候flush是受FlushMode控
制,這可以設(shè)置,在session對(duì)象剛建立時(shí)設(shè)置什么時(shí)候flush;
18、SchemaExport類:用于在程序中生成建表語(yǔ)句;
關(guān)系映射(重點(diǎn))
<有雙向關(guān)聯(lián)必設(shè)mappedBy=”對(duì)方屬性名”>
1、關(guān)系映射指的是對(duì)象之間的關(guān)系,并不是指數(shù)據(jù)庫(kù)之間的關(guān)系;(數(shù)據(jù)庫(kù)中表之間只有主
外建關(guān)系)《分單向和雙向,其數(shù)據(jù)庫(kù)是一樣的》
2、一對(duì)一關(guān)系(單向關(guān)聯(lián):丈夫表對(duì)應(yīng)的bean類中有妻子表bean對(duì)象屬性,妻子表中沒
有丈夫表bean對(duì)象):
a)、一對(duì)一單向外鍵關(guān)聯(lián)(丈夫表中多出一個(gè)id,它是引用妻子表中的id值,也就是
說(shuō)妻子表中id存在,丈夫表中的那個(gè)id值才能存在: emp和dept):
Annation::@OneToOne @JoinColumn
b)、一對(duì)一單向主鍵關(guān)聯(lián)(不重要丈夫表和 妻子表中都多出一id,并且都是引用對(duì)方
表的id值):xml c)、一對(duì)一單向 雙主鍵 關(guān)聯(lián)(丈夫表中有兩個(gè)字段做主鍵《雙主鍵》去引用妻子表 中 id值):此時(shí)的bean需要實(shí)現(xiàn)serialzable接口,還得重寫hasCode()和 equals()方法; 3、一對(duì)一關(guān)系(雙向關(guān)聯(lián):丈夫表和妻子表都有對(duì)方法的bena對(duì)象): a)一對(duì)一雙向外鍵關(guān)聯(lián):@OneToOne(mappedBy 對(duì)方那里是主導(dǎo)) xml b)一對(duì)一雙向主鍵關(guān)聯(lián): 4、組件映射:還拿妻子和丈夫來(lái)說(shuō)—在數(shù)據(jù)庫(kù)中妻子和丈夫做成一張表,妻子是丈夫表的一部 分,但在寫bean時(shí)還是丈夫bean和妻子bean,但此時(shí)妻子bean中就沒有id了,丈夫表中還有妻子bean對(duì)象引用,用Annotation配置是在丈夫bean中的妻子引用上 加上@Embedded就可以了;在訪問時(shí)通過丈夫?qū)ο蠛推拮訉?duì)象來(lái)訪問; 5、多對(duì)一的數(shù)據(jù)庫(kù)設(shè)計(jì)一般是:在多方加外鍵; 多對(duì)一 單向關(guān)聯(lián):在類中的映射,在多的那個(gè)bean類中加上單個(gè)bean的類的屬性就行 用Annotation配置 :在加的那個(gè)bean屬性上配置:@ManyToOne就行了; 多對(duì)一雙向關(guān)聯(lián):和平時(shí)練習(xí)的一樣,一個(gè)bean屬性一個(gè)Set集合屬性; 此時(shí)Annotation配置是:在多里@ManyToOne單個(gè)里 @OneToMany(mappedBy=”group”) 6、一對(duì)多單向關(guān)聯(lián):數(shù)據(jù)庫(kù)的設(shè)計(jì)和多對(duì)一的是一樣的; 一對(duì)多的單向關(guān)聯(lián):在類中的映射,在單個(gè)bean類中加上多個(gè)bean的類的set集合屬性就 行了; 用Annotation配置:在加的那個(gè)bean屬性上配置: @OneToMany 和 @JoinColumn(name=”多bean類中的外鍵名”) 一對(duì)多 和多對(duì)一的雙向關(guān)聯(lián):?jiǎn)蔚募訉?duì)方set集合屬性,多的一方加對(duì)方bean屬性; 7、多對(duì)多的單向關(guān)聯(lián): 首先數(shù)據(jù)庫(kù)的一般設(shè)計(jì)是: 建一個(gè)中間表,中間表有兩個(gè)id分別引 用兩個(gè)對(duì)象的id值,并且兩id做主鍵(雙主鍵),多對(duì)多的單向關(guān)聯(lián):只在一方間立對(duì)方的set集合,xml配置也只配有集合的一方; 多對(duì)多雙向關(guān)聯(lián)(少用):個(gè)在自己bena中加上對(duì)方set<對(duì)方bena>集合屬性; 配置是: 8、cascade=“all”----可以取的值:all(所有 時(shí)級(jí)聯(lián))、remove(刪除時(shí)級(jí)聯(lián)),其他兩個(gè)不常用:----刷新和合并; 《除了all,其他的只有在調(diào)用其對(duì)應(yīng)的方法時(shí)才級(jí)聯(lián);》 Eg:存A關(guān)聯(lián)到B,而B又關(guān)聯(lián)到C,此時(shí)就可以在A的xml中用于映射對(duì)象的的標(biāo)簽加上 cascade屬性,在B也中加上就行了;它不是必須的,也可以先存儲(chǔ)C--在存儲(chǔ)B—在存儲(chǔ)A; 《有關(guān)聯(lián)就可以用它,不管是那種關(guān)聯(lián),一對(duì)一還是多對(duì) 一、或一對(duì)多 都行;》 鐵律:雙向關(guān)系在程序中要設(shè)定雙向關(guān)聯(lián); 9、fetch(抓取):用于從數(shù)據(jù)庫(kù)中讀取數(shù)據(jù)時(shí)能夠級(jí)聯(lián)讀取; 它有兩個(gè)值:eager《渴望的》表示立即加載== 和 lazy《懶惰的》表示延遲加載,不用不加載,用時(shí)才加載數(shù)據(jù)<級(jí)聯(lián)的>; 取一不要多《lazy》取多要一《eager》 cascade用于級(jí)聯(lián)增、刪、改fetch用于 查 級(jí)聯(lián); 注意: 1、上面說(shuō)的cascade管增、刪、改,fetch管 查的解釋:其實(shí)cascade對(duì)增、刪、改、查都是級(jí)聯(lián)的,只不過是在查詢時(shí)分為立即加載和延遲加載,你若用立即加載,不 管你用不用都會(huì)同時(shí)把所關(guān)聯(lián)的數(shù)據(jù)提取出來(lái)放入內(nèi)存中,若用延遲加載,只有等到你 用到所關(guān)聯(lián)的對(duì)象時(shí),才會(huì)從數(shù)據(jù)庫(kù)中把數(shù)據(jù)提取出來(lái); 2、若用的是延遲加載:只有你用到被關(guān)聯(lián)的數(shù)據(jù)時(shí)才會(huì)從數(shù)據(jù)庫(kù)中提取出來(lái),此時(shí)必須在session關(guān)閉之前操作,因?yàn)樗怯胹ession從數(shù)據(jù)庫(kù)中提取數(shù)據(jù)的; 而立即加載會(huì)在你從數(shù)據(jù)庫(kù)提取數(shù)據(jù)(當(dāng)前數(shù)據(jù))時(shí)把所關(guān)聯(lián)的數(shù)據(jù)一塊取出放入內(nèi)存 中,若你在讀取這部分關(guān)聯(lián)的操作,在session關(guān)閉前后都可以,它是從內(nèi)存中 取的;10、11、更新數(shù)據(jù): 第一種:先把要更新的數(shù)據(jù)get()或load()出來(lái),然后對(duì)其賦予你想的值,commitxml中:inverse=”true” 《set的屬性》;表示關(guān)聯(lián)關(guān)系在對(duì)方那里設(shè)定,取我不用拿對(duì)方,取對(duì)方必須拿我; 后會(huì)幫你更改;這種方式會(huì)發(fā)送兩條update語(yǔ)句,第一條更改user 第二改group 第二種:用update方法更新數(shù)據(jù): update方法用于更新托管狀態(tài)的對(duì)象,即:脫離 session管理的對(duì)象,先get()出來(lái),然后關(guān)閉session,對(duì)get出來(lái)的對(duì)象從新賦值,然后在得到另一個(gè)session,在用update更新數(shù)據(jù),==關(guān)閉session; 12、刪除對(duì)象:先把要?jiǎng)h除的對(duì)象get出來(lái),然后把關(guān)聯(lián)關(guān)系設(shè)為null<打破關(guān)聯(lián)關(guān)系>,在調(diào)用delete()方法,如不設(shè)為null,會(huì)把二者有關(guān)聯(lián)的數(shù)據(jù)全刪除掉; 注解:刪除u1會(huì)關(guān)聯(lián)到group1,然而刪group2又會(huì)關(guān)聯(lián)到u2,所有若不打破關(guān)聯(lián)關(guān)系 會(huì)把所有相互關(guān)聯(lián)的數(shù)據(jù)全部刪除掉;u.setGroup(null);打破關(guān)聯(lián)關(guān)系; 另一種方式是:用hql語(yǔ)句刪除對(duì)象,實(shí)際中此方法用的多; 13、查詢語(yǔ)句: ===、緩存問題: 分為-? 一級(jí)緩存、二級(jí)緩存、查詢緩存(三級(jí)緩存) 一級(jí)緩存:稱為session級(jí)別的緩存, 每個(gè)session都有各自的緩存; 二級(jí)緩存:可稱為sessionFactory級(jí)別的緩存;session會(huì)先從二級(jí)緩存中查找所需 數(shù)據(jù),找不到才發(fā)送sel語(yǔ)句從數(shù)據(jù)庫(kù)中提取所需數(shù)據(jù); 若想用eh二級(jí)緩存,首先在habernate.cfg.xml中打開二級(jí)緩存,然后到habernate的文檔去找到eh的xml文件,拷貝到項(xiàng)目中,和habernate.cfg.xml同級(jí)別;project—etc適合放二級(jí)緩存的數(shù)據(jù): 1、經(jīng)常被訪問 2、不會(huì)被經(jīng)常改動(dòng) 3、數(shù)據(jù)量不大; 實(shí)際中,不到萬(wàn)不得已一般是不會(huì)考慮二級(jí)緩存; 精華-Hibernate面試題及答案大集合 1.一般情況下,關(guān)系數(shù)據(jù)模型與對(duì)象模型之間有哪些匹配關(guān)系(多選) A)表對(duì)應(yīng)類B)記錄對(duì)應(yīng)對(duì)象C)表的字段對(duì)應(yīng)類的屬性D)表之間的參考關(guān)系對(duì)應(yīng)類之間的依賴關(guān)系(1)A,B,C 2.以下關(guān)于SessionFactory的說(shuō)法哪些正確?(多選) A)對(duì)于每個(gè)數(shù)據(jù)庫(kù)事務(wù),應(yīng)該創(chuàng)建一個(gè)SessionFactory對(duì)象B)一個(gè)SessionFactory對(duì)象對(duì)應(yīng)一個(gè)數(shù)據(jù)庫(kù)存儲(chǔ)源。C)SessionFactory是重量級(jí)的對(duì)象,不應(yīng)該隨意創(chuàng)建。如果系統(tǒng)中只有一個(gè)數(shù)據(jù)庫(kù)存儲(chǔ)源,只需要?jiǎng)?chuàng)建一個(gè)。D)SessionFactory的load()方法用于加載持久化對(duì)象(2)B,C 3.Customer類中有一個(gè)Set類型的orders屬性,用來(lái)存放Order訂單對(duì)象,在Customer.hbm.xml文件中,用哪個(gè)元素映射orders屬性? A)B)C)D)<:property>(3)A 4.元素有一個(gè)cascade屬性,如果希望Hibernate級(jí)聯(lián)保存集合中的對(duì)象,casecade屬性應(yīng)該取什么值?(單選) A)noneB)saveC)deleteD)save-update(4)D 5.以下哪些屬于Session的方法? A)load()B)save()C)delete()D)update()E)open()F)close()(5)A,B,C,D,F 6.以下程序的打印結(jié)果是什么?(單選) 1.2.3.4.tx = session.beginTransaction();Customer c1=(Customer)session.load(Customer.class,new Long(1));Customer c2=(Customer)session.load(Customer.class,new Long(1));System.out.println(c1==c2);5.6.tx.commit();session.close();A)運(yùn)行出錯(cuò),拋出異常B)打印falseC)打印true(6)C 7.以下程序代碼對(duì)Customer的name屬性修改了兩次: 7.8.9.tx = session.beginTransaction();Customer customer=(Customer)session.load(Customer.class, new Long(1));10.customer.setName(“Jack”);11.customer.setName(“Mike”);12.tx.commit();執(zhí)行以上程序,Hibernate需要向數(shù)據(jù)庫(kù)提交幾條update語(yǔ)句?(單選)A)0 B)1 C)2 D)3(7)B 8.在持久化層,對(duì)象分為哪些狀態(tài)?(多選)A)臨時(shí)狀態(tài)B)獨(dú)立狀態(tài)C)游離狀態(tài)D)持久化狀態(tài)(8)A,C,D 9.對(duì)于以下程序,Customer對(duì)象在第幾行變?yōu)槌志没癄顟B(tài)?(單選) 13.Customer customer=new Customer();//line1 14.customer.setName(“Tom”);//line2 15.Session session1=sessionFactory.openSession();//line3 16.Transaction tx1 = session1.beginTransaction();//line4 17.session1.save(customer);//line4 18.tx1.commit();//line5 19.session1.close();//line6 A)line1 B)line2 C)line3 D)line4 E)line5 F)line6(9)D 10.對(duì)于以下程序,Customer對(duì)象在第幾行變?yōu)橛坞x狀態(tài)?(單選) 20.Customer customer=new Customer();//line1 21.customer.setName(“Tom”);//line2 22.Session session1=sessionFactory.openSession();//line3 23.Transaction tx1 = session1.beginTransaction();//line4 24.session1.save(customer);//line4 25.tx1.commit();//line5 26.session1.close();//line6 A)line1 B)line2 C)line3 D)line4 E)line5 F)line6(10)F 11.以下哪一種檢索策略利用了外連結(jié)查詢?(單選)A)立即檢索 B)延遲檢索 C)迫切左外連結(jié)檢索(11)C 12.假設(shè)對(duì)Customer類的orders集合采用延遲檢索策略,編譯或運(yùn)行以下程序,會(huì)出現(xiàn)什么情況(單選) 27.Session session=sessionFactory.openSession();28.tx = session.beginTransaction();29.Customer customer=(Customer)session.get(Customer.class,new Long(1)); 30.tx.commit();31.session.close();32.Iterator orderIterator=customer.getOrders().iterator();A)編譯出錯(cuò) B)編譯通過,并正常運(yùn)行 C)編譯通過,但運(yùn)行時(shí)拋出異常(12)C 13.關(guān)于HQL與SQL,以下哪些說(shuō)法正確?(多選) A)HQL與SQL沒什么差別B)HQL面向?qū)ο螅鳶QL操縱關(guān)系數(shù)據(jù)庫(kù)C)在HQL與SQL中,都包含select,insert,update,delete語(yǔ)句D)HQL僅用于查詢數(shù)據(jù),不支持insert,update和delete語(yǔ)句 (13)B,D 14.事務(wù)隔離級(jí)別是由誰(shuí)實(shí)現(xiàn)的?(單選) A)Java應(yīng)用程序 B)Hibernate C)數(shù)據(jù)庫(kù)系統(tǒng) D)JDBC驅(qū)動(dòng)程序(14)C 15.悲觀鎖與樂觀鎖,哪個(gè)具有較好的并發(fā)性能?(單選)A)悲觀鎖 B)樂觀鎖(15)B Hibernate工作原理及為什么要用? 原理: 1.讀取并解析配置文件 2.讀取并解析映射信息,創(chuàng)建SessionFactory 3.打開Sesssion 4.創(chuàng)建事務(wù)Transation 5.持久化操作 6.提交事務(wù) 7.關(guān)閉Session 8.關(guān)閉SesstionFactory 為什么要用: 1.對(duì)JDBC訪問數(shù)據(jù)庫(kù)的代碼做了封裝,大大簡(jiǎn)化了數(shù)據(jù)訪問層繁瑣的重復(fù)性代碼。 2.Hibernate是一個(gè)基于JDBC的主流持久化框架,是一個(gè)優(yōu)秀的ORM實(shí)現(xiàn)。他很大程度的簡(jiǎn)化DAO層的編碼工作 3.hibernate使用Java反射機(jī)制,而不是字節(jié)碼增強(qiáng)程序來(lái)實(shí)現(xiàn)透明性。 4.hibernate的性能非常好,因?yàn)樗莻€(gè)輕量級(jí)框架。映射的靈活性很出色。它支持各種關(guān)系數(shù)據(jù)庫(kù),從一對(duì)一到多對(duì)多的各種復(fù)雜關(guān)系。 2. Hibernate是如何延遲加載? 1.Hibernate2延遲加載實(shí)現(xiàn):a)實(shí)體對(duì)象 b)集合(Collection) 2.Hibernate3 提供了屬性的延遲加載功能 當(dāng)Hibernate在查詢數(shù)據(jù)的時(shí)候,數(shù)據(jù)并沒有存在與內(nèi)存中,當(dāng)程序真正對(duì)數(shù)據(jù)的操作時(shí),對(duì)象才存在與內(nèi)存中,就實(shí)現(xiàn)了延遲加載,他節(jié)省了服務(wù)器的內(nèi)存開銷,從而提高了服務(wù)器的性能。 3.Hibernate中怎樣實(shí)現(xiàn)類之間的關(guān)系?(如:一對(duì)多、多對(duì)多的關(guān)系) 類與類之間的關(guān)系主要體現(xiàn)在表與表之間的關(guān)系進(jìn)行操作,它們都市對(duì)對(duì)象進(jìn)行操作,我們程序中把所有的表與類都映射在一起,它們通過配置文件中的many-to-one、one-to-many、many-to-many、4. 說(shuō)下Hibernate的緩存機(jī)制 1.內(nèi)部緩存存在Hibernate中又叫一級(jí)緩存,屬于應(yīng)用事物級(jí)緩存 2.二級(jí)緩存: a)應(yīng)用及緩存 b)分布式緩存 條件:數(shù)據(jù)不會(huì)被第三方修改、數(shù)據(jù)大小在可接受范圍、數(shù)據(jù)更新頻率低、同一數(shù)據(jù)被系統(tǒng)頻繁使用、非 關(guān)鍵數(shù)據(jù) c)第三方緩存的實(shí)現(xiàn) 5. Hibernate的查詢方式 Sql、Criteria,object comptosition Hql: 1、屬性查詢 2、參數(shù)查詢、命名參數(shù)查詢 3、關(guān)聯(lián)查詢 4、分頁(yè)查詢 5、統(tǒng)計(jì)函數(shù) 6. 如何優(yōu)化Hibernate? 1.使用雙向一對(duì)多關(guān)聯(lián),不使用單向一對(duì)多 2.靈活使用單向一對(duì)多關(guān)聯(lián) 3.不用一對(duì)一,用多對(duì)一取代 4.配置對(duì)象緩存,不使用集合緩存 5.一對(duì)多集合使用Bag,多對(duì)多集合使用Set 6.繼承類使用顯式多態(tài) 7.表字段要少,表關(guān)聯(lián)不要怕多,有二級(jí)緩存撐腰 7. Struts工作機(jī)制?為什么要使用Struts? 工作機(jī)制: Struts的工作流程: 在web應(yīng)用啟動(dòng)時(shí)就會(huì)加載初始化ActionServlet,ActionServlet從 struts-config.xml文件中讀取配置信息,把它們存放到各種配置對(duì)象 當(dāng)ActionServlet接收到一個(gè)客戶請(qǐng)求時(shí),將執(zhí)行如下流程.-(1)檢索和用戶請(qǐng)求匹配的ActionMapping實(shí)例,如果不存在,就返回請(qǐng)求路徑無(wú)效信息;-(2)如果ActionForm實(shí)例不存在,就創(chuàng)建一個(gè)ActionForm對(duì)象,把客戶提交的表單數(shù)據(jù)保存到ActionForm對(duì)象中;-(3)根據(jù)配置信息決定是否需要表單驗(yàn)證.如果需要驗(yàn)證,就調(diào)用ActionForm的validate()方法;-(4)如果ActionForm的validate()方法返回null或返回一個(gè)不包含ActionMessage的ActuibErrors對(duì)象, 就表示表單驗(yàn)證成功;-(5)ActionServlet根據(jù)ActionMapping所包含的映射信息決定將請(qǐng)求轉(zhuǎn)發(fā)給哪個(gè)Action,如果相應(yīng)的 Action實(shí)例不存在,就先創(chuàng)建這個(gè)實(shí)例,然后調(diào)用Action的execute()方法;-(6)Action的execute()方法返回一個(gè)ActionForward對(duì)象,ActionServlet在把客戶請(qǐng)求轉(zhuǎn)發(fā)給 ActionForward對(duì)象指向的JSP組件;-(7)ActionForward對(duì)象指向JSP組件生成動(dòng)態(tài)網(wǎng)頁(yè),返回給客戶; 為什么要用: JSP、Servlet、JavaBean技術(shù)的出現(xiàn)給我們構(gòu)建強(qiáng)大的企業(yè)應(yīng)用系統(tǒng)提供了可能。但用這些技術(shù)構(gòu)建的系統(tǒng)非常的繁亂,所以在此之上,我們需要一個(gè)規(guī)則、一個(gè)把這些技術(shù)組織起來(lái)的規(guī)則,這就是框架,Struts便應(yīng)運(yùn)而生。 基于Struts開發(fā)的應(yīng)用由3類組件構(gòu)成:控制器組件、模型組件、視圖組件 8. Struts的validate框架是如何驗(yàn)證的? 在struts配置文件中配置具體的錯(cuò)誤提示,再在FormBean中的validate()方法具體調(diào)用。 9. 說(shuō)下Struts的設(shè)計(jì)模式 MVC 模式: web應(yīng)用程序啟動(dòng)時(shí)就會(huì)加載并初始化ActionServler。用戶提交表單時(shí),一個(gè)配置好的ActionForm對(duì)象被創(chuàng)建,并被填入表單相應(yīng)的數(shù)據(jù),ActionServler根據(jù)Struts-config.xml文件配置好的設(shè)置決定是否需要表單驗(yàn)證,如果需要就調(diào)用ActionForm的 Validate()驗(yàn)證后選擇將請(qǐng)求發(fā)送到哪個(gè)Action,如果Action不存在,ActionServlet會(huì)先創(chuàng)建這個(gè)對(duì)象,然后調(diào)用 Action的execute()方法。Execute()從ActionForm對(duì)象中獲取數(shù)據(jù),完成業(yè)務(wù)邏輯,返回一個(gè)ActionForward對(duì)象,ActionServlet再把客戶請(qǐng)求轉(zhuǎn)發(fā)給ActionForward對(duì)象指定的jsp組件,ActionForward對(duì)象指定的jsp生成動(dòng)態(tài)的網(wǎng)頁(yè),返回給客戶。 10. spring工作機(jī)制及為什么要用? 1.spring mvc請(qǐng)所有的請(qǐng)求都提交給DispatcherServlet,它會(huì)委托應(yīng)用系統(tǒng)的其他模塊負(fù)責(zé)負(fù)責(zé)對(duì)請(qǐng)求進(jìn)行真正的處理工作。 2.DispatcherServlet查詢一個(gè)或多個(gè)HandlerMapping,找到處理請(qǐng)求的Controller.3.DispatcherServlet請(qǐng)請(qǐng)求提交到目標(biāo)Controller 4.Controller進(jìn)行業(yè)務(wù)邏輯處理后,會(huì)返回一個(gè)ModelAndView 5.Dispathcher查詢一個(gè)或多個(gè)ViewResolver視圖解析器,找到ModelAndView對(duì)象指定的視圖對(duì)象 6.視圖對(duì)象負(fù)責(zé)渲染返回給客戶端。為什么用: {AOP 讓開發(fā)人員可以創(chuàng)建非行為性的關(guān)注點(diǎn),稱為橫切關(guān)注點(diǎn),并將它們插入到應(yīng)用程序代碼中。使用 AOP 后,公共服務(wù)(比如日志、持久性、事務(wù)等)就可以分解成方面并應(yīng)用到域?qū)ο笊希瑫r(shí)不會(huì)增加域?qū)ο蟮膶?duì)象模型的復(fù)雜性。 IOC 允許創(chuàng)建一個(gè)可以構(gòu)造對(duì)象的應(yīng)用環(huán)境,然后向這些對(duì)象傳遞它們的協(xié)作對(duì)象。正如單詞 倒置 所表明的,IOC 就像反 過來(lái)的 JNDI。沒有使用一堆抽象工廠、服務(wù)定位器、單元素(singleton)和直接構(gòu)造(straight construction),每一個(gè)對(duì)象都是用其協(xié)作對(duì)象構(gòu)造的。因此是由容器管理協(xié)作對(duì)象(collaborator)。 Spring即使一個(gè)AOP框架,也是一IOC容器。Spring 最好的地方是它有助于您替換對(duì)象。有了 Spring,只要用 JavaBean 屬性和配置文件加入依賴性(協(xié)作對(duì)象)。然后可以很容易地在需要時(shí)替換具有類似接口的協(xié)作對(duì)象。} Spring 框架是一個(gè)分層架構(gòu),由 7 個(gè)定義良好的模塊組成。Spring 模塊構(gòu)建在核心容器之上,核心容器定義了創(chuàng)建、配置和管理 bean 的方式,如圖 1 所示。 組成 Spring 框架的每個(gè)模塊(或組件)都可以單獨(dú)存在,或者與其他一個(gè)或多個(gè)模塊聯(lián)合實(shí)現(xiàn)。每個(gè)模塊的功能如下: ☆ 核心容器:核心容器提供 Spring 框架的基本功能。核心容器的主要組件是 BeanFactory,它是工廠模式的實(shí)現(xiàn)。BeanFactory 使用控制反轉(zhuǎn)(IOC)模式將應(yīng)用程序的配置和依賴性規(guī)范與實(shí)際的應(yīng)用程序代碼分開。 ☆ Spring 上下文:Spring 上下文是一個(gè)配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企業(yè)服務(wù),例如 JNDI、EJB、電子郵件、國(guó)際化、校驗(yàn)和調(diào)度功能。 ☆ Spring AOP:通過配置管理特性,Spring AOP 模塊直接將面向方面的編程功能集成到了 Spring 框架中。所以,可以很容易地使 Spring 框架管理的任何對(duì)象支持 AOP。Spring AOP 模塊為基于 Spring 的應(yīng)用程序中的對(duì)象提供了事務(wù)管理服務(wù)。通過使用 Spring AOP,不用依賴 EJB 組件,就可以將聲明性事務(wù)管理集成到應(yīng)用程序中。 ☆ Spring DAO:JDBC DAO 抽象層提供了有意義的異常層次結(jié)構(gòu),可用該結(jié)構(gòu)來(lái)管理異常處理和不同數(shù)據(jù)庫(kù)供應(yīng)商拋出的錯(cuò)誤消息。異常層次結(jié)構(gòu)簡(jiǎn)化了錯(cuò)誤處理,并且極大地降低了需要編寫的異常代碼數(shù)量(例如打開和關(guān)閉連接)。Spring DAO 的面向 JDBC 的異常遵從通用的 DAO 異常層次結(jié)構(gòu)。 ☆ Spring ORM:Spring 框架插入了若干個(gè) ORM 框架,從而提供了 ORM 的對(duì)象關(guān)系工具,其中包括 JDO、Hibernate 和 iBatis SQL Map。所有這些都遵從 Spring 的通用事務(wù)和 DAO 異常層次結(jié)構(gòu)。 ☆ Spring Web 模塊:Web 上下文模塊建立在應(yīng)用程序上下文模塊之上,為基于 Web 的應(yīng)用程序提供了上下文。所以,Spring 框架支持與 Jakarta Struts 的集成。Web 模塊還簡(jiǎn)化了處理多部分請(qǐng)求以及將請(qǐng)求參數(shù)綁定到域?qū)ο蟮墓ぷ鳌?/p> ☆ Spring MVC 框架:MVC 框架是一個(gè)全功能的構(gòu)建 Web 應(yīng)用程序的 MVC 實(shí)現(xiàn)。通過策略接口,MVC 框架變成為高度可配置的,MVC 容納了大量視圖技術(shù),其中包括 JSP、Velocity、Tiles、iText 和 POI。 Spring 框架的功能可以用在任何 J2EE 服務(wù)器中,大多數(shù)功能也適用于不受管理的環(huán)境。Spring 的核心要點(diǎn)是:支持不綁定到特定 J2EE 服務(wù)的可重用業(yè)務(wù)和數(shù)據(jù)訪問對(duì)象。毫無(wú)疑問,這樣的對(duì)象可以在不同 J2EE 環(huán)境(Web 或 EJB)、獨(dú)立應(yīng)用程序、測(cè)試環(huán)境之間重用。 IOC 和 AOP 控制反轉(zhuǎn)模式(也稱作依賴性介入)的基本概念是:不創(chuàng)建對(duì)象,但是描述創(chuàng)建它們的方式。在代碼中不直接與對(duì)象和服務(wù)連接,但在配置文件中描述哪一個(gè)組件需要哪一項(xiàng)服務(wù)。容器(在 Spring 框架中是 IOC 容器)負(fù)責(zé)將這些聯(lián)系在一起。 在典型的 IOC 場(chǎng)景中,容器創(chuàng)建了所有對(duì)象,并設(shè)置必要的屬性將它們連接在一起,決定什么時(shí)間調(diào)用方法。下表列出了 IOC 的一個(gè)實(shí)現(xiàn)模式。 Spring 框架的 IOC 容器采用類型 2 和類型3 實(shí)現(xiàn)。 面向方面的編程 面向方面的編程,即 AOP,是一種編程技術(shù),它允許程序員對(duì)橫切關(guān)注點(diǎn)或橫切典型的職責(zé)分界線的行為(例如日志和事務(wù)管理)進(jìn)行模塊化。AOP 的核心構(gòu)造是方面,它將那些影響多個(gè)類的行為封裝到可重用的模塊中。 AOP 和 IOC 是補(bǔ)充性的技術(shù),它們都運(yùn)用模塊化方式解決企業(yè)應(yīng)用程序開發(fā)中的復(fù)雜問題。在典型的面向?qū)ο箝_發(fā)方式中,可能要將日志記錄語(yǔ)句放在所有方法和 Java 類中才能實(shí)現(xiàn)日志功能。在 AOP 方式中,可以反過來(lái)將日志服務(wù)模塊化,并以聲明的方式將它們應(yīng)用到需要日志的組件上。當(dāng)然,優(yōu)勢(shì)就是 Java 類不需要知道日志服務(wù)的存在,也不需要考慮相關(guān)的代碼。所以,用 Spring AOP 編寫的應(yīng)用程序代碼是松散耦合的。 AOP 的功能完全集成到了 Spring 事務(wù)管理、日志和其他各種特性的上下文中。 IOC 容器 Spring 設(shè)計(jì)的核心是 org.springframework.beans 包,它的設(shè)計(jì)目標(biāo)是與 JavaBean 組件一起使用。這個(gè)包通常不是由用戶直接使用,而是由服務(wù)器將其用作其他多數(shù)功能的底層中介。下一個(gè)最高級(jí)抽象是 BeanFactory 接口,它是工廠設(shè)計(jì)模式的實(shí)現(xiàn),允許通過名稱創(chuàng)建和檢索對(duì)象。BeanFactory 也可以管理對(duì)象之間的關(guān)系。 BeanFactory 支持兩個(gè)對(duì)象模型。 □ 單態(tài) 模型提供了具有特定名稱的對(duì)象的共享實(shí)例,可以在查詢時(shí)對(duì)其進(jìn)行檢索。Singleton 是默認(rèn)的也是最常用的對(duì)象模型。對(duì)于無(wú)狀態(tài)服務(wù)對(duì)象很理想。 □ 原型 模型確保每次檢索都會(huì)創(chuàng)建單獨(dú)的對(duì)象。在每個(gè)用戶都需要自己的對(duì)象時(shí),原型模型最適合。 bean 工廠的概念是 Spring 作為 IOC 容器的基礎(chǔ)。IOC 將處理事情的責(zé)任從應(yīng)用程序代碼轉(zhuǎn)移到框架。正如我將在下一個(gè)示例中演示的那樣,Spring 框架使用 JavaBean 屬性和配置數(shù)據(jù)來(lái)指出必須設(shè)置的依賴關(guān)系。 BeanFactory 接口 因?yàn)?org.springframework.beans.factory.BeanFactory 是一個(gè)簡(jiǎn)單接口,所以可以針對(duì)各種底層存儲(chǔ)方法實(shí)現(xiàn)。最常用的 BeanFactory 定義是 XmlBeanFactory,它根據(jù) XML 文件中的定義裝入 bean,如清單 1 所示。 清單 1.XmlBeanFactory BeanFactory factory = new XMLBeanFactory(new FileInputSteam(“mybean.xml”)); 在 XML 文件中定義的 Bean 是被消極加載的,這意味在需要 bean 之前,bean 本身不會(huì)被初始化。要從 BeanFactory 檢索 bean,只需調(diào)用 getBean()方法,傳入將要檢索的 bean 的名稱即可,如清單 2 所示。 清單 2.getBean() MyBean mybean =(MyBean)factory.getBean(“mybean”); 每個(gè) bean 的定義都可以是 POJO(用類名和 JavaBean 初始化屬性定義)或 FactoryBean。FactoryBean 接口為使用 Spring 框架構(gòu)建的應(yīng)用程序添加了一個(gè)間接的級(jí)別。 IOC 示例 理解控制反轉(zhuǎn)最簡(jiǎn)單的方式就是看它的實(shí)際應(yīng)用。在對(duì)由三部分組成的 Spring 系列 的第 1 部分進(jìn)行總結(jié)時(shí),我使用了一個(gè)示例,演示了如何通過 Spring IOC 容器注入應(yīng)用程序的依賴關(guān)系(而不是將它們構(gòu)建進(jìn)來(lái))。 我用開啟在線信用帳戶的用例作為起點(diǎn)。對(duì)于該實(shí)現(xiàn),開啟信用帳戶要求用戶與以下服務(wù)進(jìn)行交互: ☆ 信用級(jí)別評(píng)定服務(wù),查詢用戶的信用歷史信息。 ☆ 遠(yuǎn)程信息鏈接服務(wù),插入客戶信息,將客戶信息與信用卡和銀行信息連接起來(lái),以進(jìn)行自動(dòng)借記(如果需要的話)。 ☆ 電子郵件服務(wù),向用戶發(fā)送有關(guān)信用卡狀態(tài)的電子郵件。 三個(gè)接口 對(duì)于這個(gè)示例,我假設(shè)服務(wù)已經(jīng)存在,理想的情況是用松散耦合的方式把它們集成在一起。以下清單顯示了三個(gè)服務(wù)的應(yīng)用程序接口。清單 3.CreditRatingInterface public interface CreditRatingInterface { public boolean getUserCreditHistoryInformation(ICustomer iCustomer);} 清單 3 所示的信用級(jí)別評(píng)定接口提供了信用歷史信息。它需要一個(gè)包含客戶信息的 Customer 對(duì)象。該接口的實(shí)現(xiàn)是由 CreditRating 類提供的。 清單 4.CreditLinkingInterface public interface CreditLinkingInterface { public String getUrl();public void setUrl(String url);public void linkCreditBankAccount()throws Exception;} 信用鏈接接口將信用歷史信息與銀行信息(如果需要的話)連接在一起,并插入用戶的信用卡信息。信用鏈接接口是一個(gè)遠(yuǎn)程服務(wù),它的查詢是通過 getUrl()方法進(jìn)行的。URL 由 Spring 框架的 bean 配置機(jī)制設(shè)置,我稍后會(huì)討論它。該接口的實(shí)現(xiàn)是由 CreditLinking 類提供的。 清單 5.EmailInterface public interface EmailInterface { public void sendEmail(ICustomer iCustomer);public String getFromEmail();public void setFromEmail(String fromEmail);public String getPassword();public void setPassword(String password);public String getSmtpHost();public void setSmtpHost(String smtpHost);public String getUserId();public void setUserId(String userId); 學(xué)習(xí)Hibernate,如何快速入門? 1. 學(xué)習(xí)Hibernate,入門的重點(diǎn)是什么? a)怎么樣在我的Tomcat中配置Hibernate? 2種類型的配置文件 2類Jar包(jdbc jar包、hibernate jar包集合)b)我怎么樣在我的Java程序中使用Hibernate? 標(biāo)準(zhǔn)代碼 2. Hibernate技術(shù)中最重要的30%常用技術(shù)是什么? a)在Tomcat中熟練配置Hibernate; b)在使用Session和Query對(duì)象熟練的執(zhí)行增刪改查操作; c)基本的HQL開發(fā); 下面看個(gè)示例: public List String hql = “select m.id as {menu.id},m.name as {menu.name},m.url as {menu.url},m.icon_url as {menu.iconUrl},m.parent_id as {menu.parentId},” +“m.serial_number as {menu.serialNo},m.admin as {menu.adminUse},m.system_admin as {menu.systemAdmin} ,m.program_name as {menu.programName}” +“ from menu m, entity_type et, entity_admin_menu eam” +“ where et.id = ”+id+“" +” and m.program_name = '“+GlobalNames.PROGRAM_NAME_CHSS+”'“ +” and et.id = eam.entity_id“ +” and m.id = eam.menu_id“; List第二篇:精華-Hibernate面試題及答案大集合
第三篇:學(xué)習(xí)Hibernate,如何快速入門
第四篇:hibernate執(zhí)行sql語(yǔ)句的總結(jié)
nu”,Menu.class).list();
return menus;
}
1.通過addEntity(“menu”,Menu.class),通過addEntity把要返回的數(shù)據(jù)強(qiáng)轉(zhuǎn)為Menu,注意Menu必須要是配置hibernate映射了的。m.id as {menu.id},這是為了如果數(shù)據(jù)庫(kù)字段名和Menu模型中不一樣所以都as取了個(gè)別名,那么這樣就能返回menu對(duì)象了。
2、如果要執(zhí)行的sql語(yǔ)句是多表查詢,并且是返回一個(gè)對(duì)象。但是這個(gè)對(duì)象是沒有配置hibernate映射的。這種就麻煩了。hibernate執(zhí)行SQL默認(rèn)返回的是一個(gè)object類型的數(shù)組,List menus
=super.getSessionFactory().getCurrentSession().createSQLQuery(hql).list();
for(int i=0;i {Object[] objects =(Object[])menus.get(i);for(int j=0;j 運(yùn)行后報(bào)錯(cuò):java.lang.ClassCastExceptionjava.lang.Object;cannot be cast to net.greatsoft.chss.domain.privilege.model.Menu,原來(lái)是查詢出來(lái)的字段并不能自動(dòng)轉(zhuǎn)換為bean對(duì)象,所以要添加addEntity(Clazz class)。有人肯定會(huì)說(shuō)添加addEntity了,但是如果Menu沒有添加hibernate映射的話,此時(shí)會(huì)報(bào)Menu unmapping。。。就是沒添加映射,所以只能添加setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);//返回一個(gè)map,KEY:為DB中名稱一致(大小寫一致)遍歷list時(shí)就可以。所以只能將返回的值變成Map,這樣就好操作了,然后就可用反射取值了,詳細(xì)看:hibernate 執(zhí)行sql語(yǔ)句返回自定義對(duì)象 3、hibernate 中createQuery與createSQLQuery兩者區(qū)別是: 前者用的hql語(yǔ)句進(jìn)行查詢,后者可以用sql語(yǔ)句查詢 前者以hibernate生成的Bean為對(duì)象裝入list返回,后者則是以對(duì)象數(shù)組進(jìn)行存儲(chǔ) 所以使用createSQLQuery有時(shí)候也想以hibernate生成的Bean為對(duì)象裝入list返回,就不是很menus = super.getSessionFactory().getCurrentSession().createSQLQuery(hql).addEntity("me 方便 突然發(fā)現(xiàn)createSQLQuery有這樣一個(gè)方法可以直接轉(zhuǎn)換對(duì)象 Query query = session.createSQLQuery(sql).addEntity(XXXXXXX.class); XXXXXXX 代表以hibernate生成的Bean的對(duì)象,也就是數(shù)據(jù)表映射出的Bean。但是這個(gè)bean必須有映射 呵呵以后多注意,還是時(shí)不時(shí)的要看看hibernate各個(gè)對(duì)象方法的使用. Hibernate(6)—— 一對(duì)多和多對(duì)多關(guān)聯(lián)關(guān)系映射(xml和注解)總結(jié) 涉及的知識(shí)點(diǎn)總結(jié)如下: ? One to Many 映射關(guān)系 o 多對(duì)一單向外鍵關(guān)聯(lián)(XML/Annotation)o 一對(duì)多單向外鍵關(guān)聯(lián)(XML/Annotation)o 懶加載和積極加載 o 一對(duì)多雙向外鍵關(guān)聯(lián)(XML/Annotation)? Many to Many 映射關(guān)系 o 多對(duì)多單向外鍵關(guān)聯(lián)(XML/Annotation)o 多對(duì)多雙向外鍵關(guān)聯(lián)(XML/Annotation)o set的inverse元素詳解 ? ? 問題小結(jié) 關(guān)聯(lián)關(guān)系的優(yōu)缺點(diǎn) 多對(duì)一單向外鍵關(guān)聯(lián)關(guān)系 注意多對(duì)一關(guān)聯(lián)是多方持有一方的引用。看一個(gè)例子,去淘寶購(gòu)物,那么一個(gè)淘寶用戶可以對(duì)應(yīng)多個(gè)購(gòu)物訂單,如圖所示: 多的一方是Orders,持有一方的引用,也就是Users,而在Users中無(wú)需作任何定義,從訂單到用戶的關(guān)系是單向多對(duì)一關(guān)聯(lián)。對(duì)應(yīng)數(shù)據(jù)庫(kù)就是: 還有比如說(shuō)學(xué)生和班級(jí)的關(guān)系,多個(gè)學(xué)生可以屬于同一個(gè)班級(jí),這就是從學(xué)生到班級(jí)也是典型的單向多對(duì)一關(guān)系,看代碼實(shí)現(xiàn): 基于注解的多對(duì)一單向外鍵關(guān)聯(lián): 單向多對(duì)一關(guān)聯(lián)中,多方需要持有一方的引用,那么多方(學(xué)生類)需要額外配置,需要對(duì)持有的一方引用使用注解@ManyToOne(cascade={CascadeType.ALL}, fetch=FetchType.EAGER),設(shè)置為級(jí)聯(lián)操作和饑渴的抓取策略,@JoinColumn(name=“cid”),而一方(教室類)無(wú)需做任何多方的定義。 注意;多方必須保留一個(gè)不帶參數(shù)的構(gòu)造器! importjavax.persistence.Entity;importjavax.persistence.GeneratedValue;importjavax.persistence.Id; //班級(jí)類,在多對(duì)一關(guān)系中屬于一的方,不持有其他多余的配置,反而是被多方持有 @Entity public class ClassRoom { private intcid;//班級(jí)編號(hào) private String cname;//班級(jí)名稱 // 自動(dòng)增長(zhǎng)的主鍵 @Id @GeneratedValue publicintgetCid(){ returncid;} public void setCid(intcid){ this.cid = cid;} public String getCname(){ returncname;} public void setCname(String cname){ this.cname = cname;} } View Code 一方——班級(jí)類無(wú)需做多余的定義,下面是多方——學(xué)生實(shí)體和配置: importjavax.persistence.CascadeType;importjavax.persistence.Entity;importjavax.persistence.FetchType;importjavax.persistence.GeneratedValue;importjavax.persistence.Id;importjavax.persistence.JoinColumn;importjavax.persistence.ManyToOne; //學(xué)生實(shí)體類,屬于多對(duì)一的多方,持有班級(jí)(一方)的引用 @Entity public class Students { private intsid;//編號(hào) private String sname;//姓名 private ClassRoom classroom;//學(xué)生班級(jí) //注意:多方一定要顯式的定義不帶參數(shù)的構(gòu)造方法 public Students(){ } public Students(String sname){ this.sname = sname;} // 多方使用注解:@ManyToOne // fetch=FetchType.EAGER,急加載,加載一個(gè)實(shí)體時(shí),定義急加載的屬性會(huì)立即從數(shù)據(jù)庫(kù)中加載。 // 全部級(jí)聯(lián)操作,referencedColumnName顯式設(shè)置數(shù)據(jù)庫(kù)字段名cid,不寫默認(rèn)就是和name一樣的。 @ManyToOne(cascade={CascadeType.ALL}, fetch=FetchType.EAGER)@JoinColumn(name=“cid”,referencedColumnName=“cid”)publicClassRoomgetClassroom(){ return classroom;} public void setClassroom(ClassRoom classroom){ this.classroom = classroom;} // 自動(dòng)增長(zhǎng)主鍵 @Id @GeneratedValue publicintgetSid(){ returnsid;} public void setSid(intsid){ this.sid = sid;} public String getSname(){ returnsname;} public void setSname(String sname){ this.sname = sname;} } View Code 下面測(cè)試:先生成數(shù)據(jù)庫(kù)腳本,再進(jìn)行學(xué)生對(duì)象的插入 public class TestStudentsByAnno { private static SessionFactorysessionFactory; @Before public void setUp()throws Exception { System.out.println(“setUp()...”);sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();} @After public void tearDown()throws Exception { System.out.println(“tearDown()...”);sessionFactory.close();} @Test public void testSave(){ Session session = sessionFactory.getCurrentSession();Transaction tx = session.beginTransaction(); try { ClassRoom c = new ClassRoom();c.setCname(“computer001”); Students s = new Students(“zhangsan”);s.setClassroom(c); session.save(s);tx.commit();} catch(Exception ex){ ex.printStackTrace();tx.rollback();} } @Test @Ignore public void testSchemaExport(){ SchemaExport se = new SchemaExport(new AnnotationConfiguration().configure());se.create(true, true);} } View Code 反向創(chuàng)建表的數(shù)據(jù)庫(kù)腳本如下: create table ClassRoom(cid integer not null auto_increment, cnamevarchar(255), primary key(cid))create table Students(sid integer not null auto_increment, snamevarchar(255), cid integer, primary key(sid)) 插入一個(gè)學(xué)生對(duì)象,會(huì)自動(dòng)生成如下語(yǔ)句: ClassRoom c = new ClassRoom();c.setCname(“computer001”); Students s = new Students(“zhangsan”);s.setClassroom(c); session.save(s);tx.commit();View Code Hibernate: insert into ClassRoom(cname)values(?)Hibernate: insert into Students(cid, sname)values(?, ?)插入成功: 基于xml配置實(shí)現(xiàn)多對(duì)一單向外鍵關(guān)聯(lián) View Code 一方(教室類)無(wú)需做任何多方的定義。只需要維護(hù)好自己的屬性配置即可。而多方只需要加上 hibernate.cfg.xml里加上 ? ? 多對(duì)一時(shí)候,多方設(shè)置EAGER加載,一對(duì)多的時(shí)候,一方設(shè)置LAZY加載 多對(duì)多關(guān)聯(lián),多方需要保留一個(gè)無(wú)參構(gòu)造器。第五篇:Hibernate(6)—— 一對(duì)多和多對(duì)多關(guān)聯(lián)關(guān)系映射(xml和注解)總結(jié)