




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
Java程序員面試分類模擬14論述題1.
Struts1與Struts2有哪些區(qū)別正確答案:Strut1框架由AetionForm和JavaBean組成,其中AetionForm用于封裝用戶(江南博哥)的請求參數(shù),封裝成ActionForm對象,該對象被ActionServlet轉(zhuǎn)發(fā)給Action,Action根據(jù)ActionFrom里面的請求參數(shù)處理用戶的請求。Struts2框架的基礎(chǔ)是核心控制器FilterDispatcher,它包含了框架內(nèi)部的控制流程和處理機(jī)制。業(yè)務(wù)控制器Action和業(yè)務(wù)邏輯組件是需要用戶自己來實現(xiàn)的。開發(fā)人員在開發(fā)Action和業(yè)務(wù)邏輯組件的同時,還需要編寫相關(guān)的配置文件,以供核心控制器FiherDispatcher來使用。
Struts1與Struts2都是MVC的Web框架,盡管二者都叫Struts,但也存在著很多不一致的地方。具體而言,主要表現(xiàn)在以下方面:
1)風(fēng)險控制方面。Struts1是老牌框架,應(yīng)用廣泛,有很好的群眾基礎(chǔ),開發(fā)風(fēng)險很小,成本更低。Struts2雖然基于Struct1,但是相對不成熟,而且未知的風(fēng)險和變化很多,受眾并不多。所以,使用Struts2開發(fā)項目的風(fēng)險更大,成本更高。
2)Action實現(xiàn)類方面。Struts1要求Action類繼承一個抽象基類,而Struts2中Action類既可以實現(xiàn)一個Action接口,也可以實現(xiàn)其他接口,使可選和定制的服務(wù)成為可能。同時,Struts2提供了一個ActionSupport基類去實現(xiàn)常用的接口。
3)線程模式方面。Struts1Action是單例模式并且必須是線程安全的,因為僅有Action的一個實例來處理所有請求。而Struts2Action對象為每一個請求產(chǎn)生一個實例,因此不存在線程安全的問題。
4)Servlet依賴方面。Struts1Action依賴于ServletAPI,因為Struts1Action的execute()方法中有HttpServletRequest和HttpServletResponse方法。Struts2Action不再依賴于ServletAPI,因為Struts2的Action是由POJO(PlainOldJavaObjects,簡單的Java對象)組成,在Struts2中,Servlet上下文以簡單Map的形式表現(xiàn)出來,這使得Action可以進(jìn)行獨(dú)立的測試,當(dāng)然,如果Action需要直接訪問HttpServletRequest和HttpServletResponse參數(shù),Struts2Action仍然可以訪問它們。但是,大部分時候,Action都無需直接訪問HttpServetRequest和HttpServletResponse,從而給了開發(fā)人員更多選擇。
5)可測性方面。測試Struts1Action的一個主要問題是execute()方法依賴于ServletAPI,這使得Action的測試要依賴于Web容器。為了脫離Web容器測試Struts1的Action,必須借助于第三方擴(kuò)展:StrutsTestCase,該擴(kuò)展包包含了系列的Mock對象(模擬了HttpservetRequest和HttpServletResponse對象),從而可以脫離Web容器測試Struts1的Action類。Struts2Action可以通過初始化、設(shè)置屬性、調(diào)用方法來測試。
6)封裝請求參數(shù)。Struts1使用ActionForm對象封裝用戶的請求參數(shù),所有AetionForm必須繼承一個基類——ActionForm。普通的JavaBean不能用作ActionForm,因此,開發(fā)人員必須創(chuàng)建大量的ActionForm類封裝用戶請求參數(shù)。雖然Struts1提供了動態(tài)ActionForm來簡化ActionForm的開發(fā),但依然需要在配置文件中定義ActionForm。而Struts2直接使用Action屬性來封裝用戶請求屬性,避免了開發(fā)人員需要大量開發(fā)ActionForm類的煩瑣。實際上,這些屬性還可以是包含子屬性的Rich對象類型。如果開發(fā)人員依然“懷念”Struts1ActionForm的模式,Struts2提供了ModelDriven模式,可以讓開發(fā)人員使用單獨(dú)的Model對象來封裝用戶請求參數(shù)。但該Model對象無需繼承任何Struts2基類,是一個POJO,從而降低了代碼污染。
7)表達(dá)式語言方面。Struts1整合了JSP標(biāo)準(zhǔn)標(biāo)簽庫(JSPStandardTagLibrary,JSTL),因此可以使用JSTL表達(dá)式語言。Struts2可以使用JSTL,但它整合了一種更強(qiáng)大和靈活的表達(dá)式語言——對象圖的符號語言(ObjectGraphNotationLanguage,OGNL),因此,Struts2下的表達(dá)式語言功能更加強(qiáng)大。
8)綁定值到視圖。Struts1使用標(biāo)準(zhǔn)JSP機(jī)制把對象綁定到視圖頁面,而Struts2使用“ValueStack”技術(shù),使標(biāo)簽庫能夠訪問值,而不需要把對象和視圖頁面綁定在一起。
9)類型轉(zhuǎn)換。Struts1ActionForm屬性通常都是String類型。Struts1使用Commons-Beanutils進(jìn)行類型轉(zhuǎn)換,每個類一個轉(zhuǎn)換器,轉(zhuǎn)換器是不可配置的;Struts2使用OGNL進(jìn)行類型轉(zhuǎn)換,支持基本數(shù)據(jù)類型和常用對象之間的轉(zhuǎn)換。
10)數(shù)據(jù)校驗。Struts1與Strut2都支持通過validate()方法的手動驗證,不同的是,Struts1支持在ActionForm重寫validate()方法中手動校驗,或者通過整合Commonsalidator框架來完成數(shù)據(jù)校驗,而Struts2支持通過重寫validate()方法進(jìn)行校驗,也支持整合XWork校驗框架進(jìn)行校驗。
11)Action執(zhí)行控制。Struts1支持每一個模塊對應(yīng)一個請求處理(即生命周期的概念),但是模塊中的所有Action必須共享相同的生命周期。Struts2支持通過攔截器堆棧(InterceptorStacks)為每一個Action創(chuàng)建不同的生命周期。開發(fā)人員可以根據(jù)需要創(chuàng)建相應(yīng)堆棧,以便和不同的Action一起使用。
12)捕獲輸入。Struts1使用ActionForm對象捕獲輸入,所有ActionForm必須繼承自一個框架依賴的基類。因為其他JavaBean不能用作ActionForm,開發(fā)人員經(jīng)常創(chuàng)建多余的類捕獲輸入。而Struts2直接使用Action屬性作為輸入屬性,消除了對第二個輸入對象的需求。
2.
什么是IoC正確答案:控制反轉(zhuǎn)(InverseofControl,IoC)有時也被稱為依賴注入,是一種降低對象之間耦合關(guān)系的設(shè)計思想。一般而言,在分層體系結(jié)構(gòu)中,都是上層調(diào)用下層的接口,上層依賴于下層的執(zhí)行,即調(diào)用者依賴于被調(diào)用者。而通過IoC方式,使得上層不再依賴于下層的接口,即通過采用一定的機(jī)制來選擇不同的下層實現(xiàn),完成控制反轉(zhuǎn),使得由調(diào)用者來決定被調(diào)用者。IoC通過注入一個實例化的對象來達(dá)到解耦和的目的。使用這種方法后,對象不會被顯式地調(diào)用,而是根據(jù)需求通過IoC容器(例如Spring)來提供。
采用IoC機(jī)制能夠提高系統(tǒng)的可擴(kuò)展性,如果對象之間通過顯式調(diào)用進(jìn)行交互會導(dǎo)致調(diào)用者與被調(diào)用者存在著非常緊密的聯(lián)系,其中一方的改動將會導(dǎo)致程序出現(xiàn)很大的改動,例如,要為一家賣茶的商店提供一套管理系統(tǒng),在這家商店剛開業(yè)時只賣綠茶(GreenTea),隨著規(guī)模的擴(kuò)大或者根據(jù)具體銷售量,未來可能會隨時改變茶的類型,例如紅茶(BlackTea)等,傳統(tǒng)的實現(xiàn)方法會針對茶抽象化一個基類,綠茶類只需要繼承自該基類即可,如圖所示。
賣茶系統(tǒng)類圖(一)
采用該實現(xiàn)方法后,在需要使用GreenTea時只需要執(zhí)行以下代碼即可:AhstractTeat=newGreenTea(),當(dāng)然,這種方法是可以滿足當(dāng)前設(shè)計要求的。但是該方法的可擴(kuò)展性不好,存在著不恰當(dāng)?shù)牡胤?,例如,商家發(fā)現(xiàn)綠茶的銷售并不好,決定開始銷售紅茶(BlackTea)時,那么只需要實現(xiàn)一個BlackTea類,并且讓這個類繼承自AhstractTea即可。但是,系統(tǒng)中所有用到AbstractTeat=newGreenTea()的地方都需要被改為AbstractTeat=newBlackTea(),而這種創(chuàng)建對象實例的方法往往會導(dǎo)致程序的改動量非常大。
那么怎樣才能增強(qiáng)系統(tǒng)的可擴(kuò)展性呢?——設(shè)計模式,此時可以使用設(shè)計模式中的工廠模式來把創(chuàng)建對象的行為包裝起來,實現(xiàn)方法如圖所示。
賣茶系統(tǒng)類圖(二)
通過以上方法,可以把創(chuàng)建對象的過程委托給TeaFatory來完成,在需要使用Tea對象時只需要調(diào)用Factory類的getTea方法即可,具體創(chuàng)建對象的邏輯在TeaFactory中來實現(xiàn),那么當(dāng)商家需要把綠茶替換為紅茶時,系統(tǒng)中只需要改動TeaFaetory中創(chuàng)建對象的邏輯即可,采用了工廠模式后,只需要在一個地方做改動就可以滿足要求,這樣就增強(qiáng)了系統(tǒng)的可擴(kuò)展性。
雖然說采用工廠設(shè)計模式后增強(qiáng)了系統(tǒng)的可擴(kuò)展性,但是從本質(zhì)上來講,工廠模式只不過是把程序中會變動的邏輯移動到工廠類里面了,當(dāng)系統(tǒng)中的類較多時,在系統(tǒng)擴(kuò)展時需要經(jīng)常改動工廠類中的代碼。而采用IoC設(shè)計思想后,程序?qū)懈玫目蓴U(kuò)展性,下面主要介紹Spring框架在采用IoC后的實現(xiàn)方法,如圖所示。
賣茶系統(tǒng)類圖(三)
Spring容器將會根據(jù)配置文件來創(chuàng)建調(diào)用者對象(Sale),同時把被調(diào)用的對象(AbstractTea的子類)的實例化對象通過構(gòu)造函數(shù)或set()方法的形式注入到調(diào)用者對象中。
首先,創(chuàng)建名為SpringConfig.xml的文件。
<beans>
<beanid="sale"class="Sale"singleton="false">
<constrctor-arg>
<refbean="tea"/>
</constrctor-arg>
</bean>
<beanid="tea"class="BlueTea"singleton="false">
</beans>
在實現(xiàn)Sale類時,需要按照如下方式實現(xiàn)。
classSale{
privateAhstractTeat;
publicSale(AbstractTeat){
this.t=t;
}
//其他方法就可以使用t了
當(dāng)Spring容器創(chuàng)建Sale對象時,根據(jù)配置文件SpringConfig.xml就會創(chuàng)建一個BlueTea的對象,作為Sale構(gòu)造函數(shù)的參數(shù)。當(dāng)需要把BlueTea改為BlackTea時,只需要修改上述配置文件,而不需要修改代碼。
在需要Sale時,可以通過如下方式來創(chuàng)建Sale對象:
ApplicationContextxtx=newFileSystemXmlApplicationContext("SpringConfig.xml");
Sales=(Sale)ctx.getBean("sale");
上例中,Spring采用IoC的方式來實現(xiàn)把實例化的對象注入到開發(fā)人員自定義的對象中,具有較強(qiáng)的可擴(kuò)展性。
具體而言,IoC主要有以下兩個方面的優(yōu)點:
1)通過IoC容器,開發(fā)人員不需要關(guān)注對象如何被創(chuàng)建的,同時增加新類也非常方便,只需要修改配置文件即可實現(xiàn)對象的“熱插拔”。
2)IoC容器可以通過配置文件來確定需要注入的實例化對象,因此非常便于進(jìn)行單元測試。
盡管如此,IoC也有自身的缺點,具體表現(xiàn)為以下兩點:
1)對象是通過反射機(jī)制實例化出來的,因此會對系統(tǒng)的性能有一定的影響。
2)創(chuàng)建對象的流程變得比較復(fù)雜。
3.
什么是AOP正確答案:面向切面編程(Aspect-OrientedProgramming,AOP)是對面向?qū)ο箝_發(fā)的一種補(bǔ)充,它允許開發(fā)人員在不改變原來模型的基礎(chǔ)上動態(tài)地修改模型以滿足新的需求,例如,開發(fā)人員可以在不改變原來業(yè)務(wù)邏輯模型的基礎(chǔ)上可以動態(tài)地增加日志、安全或異常處理的功能。
下面介紹一個在Spring中使用AOP編程的簡單例子。
1)創(chuàng)建一個接口以及實現(xiàn)這個接口的類。TestAOPIn.java文件的內(nèi)容如下所示。
publicinterfaceTestAOPIn{
publicvoiddoSomething();
}
TestAOPImpl.java文件的內(nèi)容如下所示。
publicclassTestAOPImplimplementsTestAOPIn{
publicvoiddoSomething(){
System.out.println("TestAOPImpl:doSomething");
}
}
2)配置SpringConfig.xml,使得這個類的實例化對象可以被注入到使用這個對象的Test類中。
<?xmlversion="1.0"encoding="UTF-8"?>
<!DOCTYPEbeansPUBLIC"-//SPRING//DTDBEAN//EN""/dtd/
spring-beans.dtd">
<beans>
<beanid="testAOPBean"class="org.springframework.aop.framework.ProxyFactoryBean">
<propertyname="target">
<beanclass="testAOPIn"singleton="false"/>
</property>
</bean>
</beans>
3)在完成配置文件后,編寫如下測試代碼。
importorg.springframework.context.ApplicationContext;
importorg.springframework.context.support.FileSystemXmlApplicationContext;
publicclassTest{
publicstaticvoidmain(String[]args){
ApplicationContextetx=newFileSystemXmlApplicationContext("SpringConfig.xml");
TestAOPInt=(TestAOPIn)ctx.getBean("testAOPBean");
t.doSomething();
}
}
程序運(yùn)行結(jié)果為:
TestAOPImpl:doSomething
編寫完這個模塊后,開發(fā)人員需要增加對doSomething()方法調(diào)用的跟蹤,也就是說,要跟蹤該方法何時被調(diào)用以及調(diào)用何時結(jié)束等內(nèi)容。當(dāng)然,使用傳統(tǒng)的方法也可以實現(xiàn)該功能,但卻會產(chǎn)生額外的開銷,即需要修改已存在的模塊。此時可以采用AOP的方式來實現(xiàn)這個功能。它在不修改原有模塊的前提下可以完成相同的功能。
publicclassTestAOPImplimplementsTestAOPIn{
publicvoiddoSomething(){
System.out.println("beginCalldoSomething");
System.out.println("TestAOPImpl:doSomething");
System.out.println("endCalldoSomething");
}
}
其實現(xiàn)原理如圖所示。
AOP實現(xiàn)原理圖
為此需要提供用來跟蹤函數(shù)調(diào)用的類。traceBeforeCall.java文件的內(nèi)容如下所示:
publicclasstraceBeforeCallimplementsMethodBeforeAdviee{
publicvoidbeforeCall(Methodarg0,Object[]arg1,Objectarg2)throwsThrowable{
System.out.println("beginCalldoSomething");
}
}
traceEndCall.java文件的內(nèi)容如下所示:
importjava.lang.reflect.Method;
importorg.springframework.aop.AfterReturningAdvice;
publicclasstraceEndCallimplementsAflerRetumingAdvice{
publicvoidafterCall(Objectarg0,Methodarg1,Object[]arg2,Objectarg3)throwsThrowable{
System.out.println("endCalldoSomething");
}
}
只需在配置文件中配置在調(diào)用doSomething()方法之前需要調(diào)用traceBeforeCall類的beforeCall()方法以及在調(diào)用doSomething()方法之后需要調(diào)用traceEndCall類的afterCall()方法,Spring容器就會根據(jù)配置文件在調(diào)用doSomething()方法前后自動調(diào)用相應(yīng)的方法,通過在beforeCall()方法和afterCall()方法中添加跟蹤的代碼就可以滿足對doSomething()方法調(diào)用的跟蹤要求,同時還不需要更改原來已實現(xiàn)的代碼模塊。
4.
什么是Spring框架正確答案:Spring是一個J2EE的框架,這個框架提供了對輕量級IoC的良好支持,同時也提供了對AOP技術(shù)非常好的封裝。相比其他框架,Spring框架的設(shè)計更加模塊化,框架內(nèi)的每個模塊都能完成特定的工作,而且各個模塊可以獨(dú)立地運(yùn)行,不會相互牽制。因此,在使用Spring框架時,開發(fā)人員可以使用整個框架,也可以只使用框架內(nèi)的一部分模塊,例如可以只使用SpringAOP模塊來實現(xiàn)日志管理功能,而不需要使用其他模塊。
Spring框架主要由7個模塊組成,它們分別是SpringAOP、SpringORM、SpringDAO、SpringWeb、SpringContext、SpringWebMVC、SpringCore等。Spring框架圖如圖所示。
Spring框架圖
下表詳細(xì)介紹了各個模塊的作用。Spring框架的7個模塊的作用模塊描述SpringAOP采用了面向切面編程的思想,使Spring框架管理的對象支持AOP,同時這個模塊也提供了事務(wù)管理,可以不依賴具體的EJB組件,就可以將事務(wù)管理集成到應(yīng)用程序中SpringORM提供了對現(xiàn)有ORM框架的支持,例如Hibernate、JDO等SpringDAO提供了對數(shù)據(jù)訪問對象(DataAccessObject,DAO)模式和JDBC的支持。DAO可以實現(xiàn)把業(yè)務(wù)邏輯與數(shù)據(jù)庫訪問的代碼實現(xiàn)分離,從而降低代碼的耦合度。通過對JDBC的抽象,簡化了開發(fā)工作,同時簡化了對異常的處理(可以很好地處理不同數(shù)據(jù)庫廠商拋出的異常)SpringWeb提供了Servlet監(jiān)聽器的Context和Web應(yīng)用的上下文。同時還集成了一些現(xiàn)有的Web框架,例如StructsSpringContext擴(kuò)展核心容器,提供了Spring上下文環(huán)境,給開發(fā)人員提供了很多非常有用的服務(wù),例如國際化、E-mail和JNDI訪問等SpringWebMVC提供了一個構(gòu)建Web應(yīng)用程序的MVC的實現(xiàn)SpringCoreSpring框架的核心容器,它提供了Spring框架的基本功能。這個模塊中最主要的一個組件為BeanFactory,它使用工廠模式來創(chuàng)建所需的對象。同時BeanFactory使用IOC思想,通過讀取XML文件的方式來實例化對象,可以說BeanFactory提供了組件生命周期的管理,組件的創(chuàng)建、裝配、銷毀等功能
Spring在J2EE中到底扮演著怎樣的角色?在哪些地方可以使用Spring?
Spring的工作原理如圖所示,可以看出,Spring有著非常廣泛的用途,不僅可以在Web容器中用來管理Web服務(wù)器端的模塊,例如Servlet,還可以用來管理用于訪問數(shù)據(jù)庫的Hibernate。由于Spring在管理BusinessObject(業(yè)務(wù)對象)和DAO時使用了IoC和AOP的思想,因此這些被Spring管理的對象都可以脫離EJB容器單獨(dú)運(yùn)行和測試。在需要被Spring容器管理時,只需要增加配置文件,Spring框架就會根據(jù)配置文件與相應(yīng)的機(jī)制實現(xiàn)對這些對象的管理。
Spring的工作原理
除此之外,使用Spring還有如下好處:
1)在使用J2EE開發(fā)多層應(yīng)用程序時,Spring有效地管理了中間層的代碼,由于Spring采用了控制反轉(zhuǎn)和面向切面編程的思想,因此這些代碼非常容易進(jìn)行單獨(dú)測試。
2)使用Spring有助于開發(fā)人員培養(yǎng)一個良好的編程習(xí)慣:面向接口編程而不是面向類編程。面向接口編程使得程序有更好的可擴(kuò)展性。
3)Spring對數(shù)據(jù)的存取提供了一個一致的框架(不論是使用JDBC還是O/R映射的框架,例如Hibernate或JDO)。
4)Spring通過支持不同的事務(wù)處理API(如JTA、JDBC、Hibernate等)的方法對事務(wù)的管理提供了一致的抽象方法。
5)使用Spring框架編寫的大部分業(yè)務(wù)對象不需要依賴Spring。
5.
什么是Hibernate正確答案:Hibernate是一個開放源代碼的對象關(guān)系映射(ObjectRelationMapping,ORM,一種用來完成對象模型到關(guān)系模型的映射技術(shù))框架,它不僅可以運(yùn)行在J2EE容器中,也可以在J2EE容器外運(yùn)行。它對JDBC進(jìn)行了非常輕量級的對象封裝,所以任何可以使用JDBC的地方都可以用Hibernate來替代。Hibernate實現(xiàn)了Java對象與關(guān)系數(shù)據(jù)庫記錄的映射關(guān)系,簡化了開發(fā)人員訪問數(shù)據(jù)庫的流程,極大地提高了軟件的開發(fā)效率。
Hibernate主要提供了5個核心接口,分別為Session、SessionFactory、Transaction、Query和Configuration。通過使用這些接口不僅可以完成對數(shù)據(jù)庫的訪問(例如查詢、插入、更新與刪除等),而且還可以實現(xiàn)對事務(wù)的控制。Hibernate的結(jié)構(gòu)圖如圖所示。
Hibernate結(jié)構(gòu)圖
下表詳細(xì)介紹了各個模塊的作用。Hibernate模塊介紹接口名描述Session一個輕量級的非線程安全的對象,主要負(fù)責(zé)被持久化對象與數(shù)據(jù)庫的操作??梢允褂肧essionFaetory來創(chuàng)建一個Session,當(dāng)對數(shù)據(jù)庫的所有操作都執(zhí)行完成后,就可以關(guān)閉Session。Session在訪問數(shù)據(jù)庫時會建立與數(shù)據(jù)庫的連接,這個連接只有在需要時才會被建立SessionFactory負(fù)責(zé)初始化Hibernate。它可以被看作數(shù)據(jù)源的代理,可以用來創(chuàng)建Session對象。此外,SessionFactory是線程安全的,因此可以被多個線程同時訪問。一般而言,SessionFactory會在Hibernate啟動時創(chuàng)建一次,因此,為了便于使用,SessionFactory應(yīng)該用一個單例模式來實現(xiàn)Transaction負(fù)責(zé)事務(wù)相關(guān)的操作。它的主要方法有commit()和rollback(),其中commit()方法負(fù)責(zé)事務(wù)的提交,rollback()方法負(fù)責(zé)事務(wù)的回滾,可以通過Session的beginTrancation()方法來創(chuàng)建Query負(fù)責(zé)執(zhí)行各種數(shù)據(jù)庫查詢??梢允褂肏ibernate查詢語言(HibernateQueryLanguage,HQL)或SQL語句兩種方式進(jìn)行查詢(這兩種查詢方式非常類似,與SQL不同的是,HQL語言使用類和屬性而不是表與列名進(jìn)行查詢)??梢酝ㄟ^Session的createQuery()方法來創(chuàng)建Query。此外,Hibernate還提供了另外一種查詢方式QBC(QueryByCriteria),其使用方法為:先使用Session實例的createCriteria()方法創(chuàng)建Criteria對象,接著使用工具類Restrictions的方法為Criteria對象設(shè)置查詢條件,同時還可以用Order工具類的方法沒置排序方式,最后用Projections工具類的方法進(jìn)行統(tǒng)計和分組,使用Criteria對象的list()方法進(jìn)行查詢并返回結(jié)果。需要注意的是,QBC是一種類型安全的面向?qū)ο蟮牟樵兎绞紺onfiguration用于讀取Hibernate配置文件,并生成SessionFaetory對象。其中配置文件主要有兩類:一類是hiber-nate.cfg.xml或perties;另一類是映射文件,例如***.hbm.xml。其中hibernate.cfg.xml或perties用來配置Hibernate服務(wù)的信息(例如連接數(shù)據(jù)庫使用的驅(qū)動類、數(shù)據(jù)庫連接的URL、數(shù)據(jù)庫的用戶名和密碼等信息)。如果同時提供了hibernate.cfg.xml和perties文件,那么hibernate.cfg.xml會覆蓋perties中的配置信息。映射文件(*.hbm.xml)用來配置java對象與關(guān)系數(shù)據(jù)庫記錄的映射關(guān)系。為了便于管理與維護(hù),通常會給每個對象創(chuàng)建一個單獨(dú)的映射文件
Hibernate的使用過程如下:
1)應(yīng)用程序通過Configuration類讀取配置文件并創(chuàng)建SessionFactory對象。
SessionFaetorysessionFaetory=newConfiguration().configure().buildSessionfactory();
2)通過SessionFactory生成一個Session對象。
Sessionsession=sessionFactory.openSession();
3)通過Session對象的beginTrancation()方法創(chuàng)建一個事務(wù)。
Transactiont=session.beginTransaction();接著可以通過Session對象的get()、load()、save()、update()、delete()和saveOrUpdate()等方法實現(xiàn)數(shù)據(jù)的加載、保存、更新和刪除等操作;也可以通過session生成一個Query對象,然后利用Query對象執(zhí)行查詢操作;最后通過commit()方法或rollback()方法完成事務(wù)操作。
4)在完成所有持久化操作與事務(wù)操作后需要關(guān)閉Session與SessionFactory。
下面以訪問MySQL為例給出一個使用Hibernate的示例。
1)創(chuàng)建一個表。
createtableEmployee(
idintprimarykey,
nanlevarchar(20),
ageint
);
2)在Eclipse中創(chuàng)建一個工程,接著導(dǎo)入相關(guān)的類庫,例如Hibernate需要用到的類(hibernate3.jar),訪問數(shù)據(jù)庫的驅(qū)動包(mysql-connector-java-5.0.8-bin.jar)和操作XML文件用到的jar包等。接著創(chuàng)建一個持久化類。
publicclassEmployee{
privateIntegerid;
privateStringname;
privateIntegerage;
publicEmployee(){}
publicEmployee(Integerid,Stringname,Integerage){
this,id=id;
=name;
this.age=age;
}
publicStringgetName(){
returnname;
}
publicvoidsetName(Stringname){
=name;
}
publicIntegergetAge(){
returnage;
}
publicvoidsetAge(Integerage){
this.age=age;
}
publicIntegergetId(){
returnid;
}
publicvoidsetId(Integerid){
this.id=id;
}
}
3)創(chuàng)建一個目錄hibernate,在這個目錄下創(chuàng)建兩個配置文件:hibernate.cfg.xml與employee.hdm.xml。其中,hibernate.cfg.xml文件的內(nèi)容如下所示:
<?xmlversion='1.0'encoding='UTF-8'?>
<!DOCTYPEhibernate-configurationPUBLIC
"-//Hibernate/HibernateConfigurationDTD3.0//EN"
"/hibernate-configuration-3.0.dtd">
<!--GeneratedbyMyEclipseHibernateTools.-->
<hibernate-configuration>
<session-factory>
<propertyname="connection.username">user1</property>
<propertyname="connection.url">
jdbc:mysql://loealhost:3306/Test
</property>
<propertyname="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<propertyname="file">MySQL5.1</property>
<propertyname="connection.password">pwd1</property>
<propertyname="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<propertyname="show_sql">true</property>
<mappingresource="hibernate/employee.hdm.xml"/>
</session-factory>
</hibernate-configuration>
配置文件employee.hdm.xml中存放了訪問數(shù)據(jù)庫的基本信息,具體內(nèi)容如下所示:
<?xmlversion="1.0"encoding="utf-8"?>
<!DOCTYPEhibernate-mappingPUBLIC"-//Hibernate/HibernateMappingDTD3.0//EN"
"/hibernate-mapping-3.0.dtd">
<!--
MappingfileautogeneratedbyMyEclipse-HibernateTools
-->
<hibernate-mapping>
<classname="Employee"table="Employee">
<idname="id"type="java.lang.Integer">
<columnname="id"/>
<!--Hibernate可以實現(xiàn)自增-->
<generatorclass="increment"/>
</id>
<propertyname="name"type="java.lang.String">
<columnname="name"length="20"/>
</property>
<propertyname="age"type="java.lang.Integer">
<columnname="age"/>
</property>
</class>
</hibernate-mapping>
以上文件中存放了Java類與數(shù)據(jù)庫表的對應(yīng)關(guān)系。
4)編寫訪問數(shù)據(jù)庫的代碼。
importjava.sql.SQLException;
importjava.util.List;
importorg.hibernate.Query;
importorg.hibernate.Session;
importorg.hibernate.SessionFactory;
importorg.hibernate.Transaction;
importorg.hibernate.cfg.Configuration;
publicclassTest{
publicstaticvoidmain(String[]args)throwsClassNotFoundException,SQLException{
Configurationconfig=newConfiguration().configure("/hibernate/hibernate.cfg.xml");
SessionFactorysessionFaetory=config.buildSessionFaetory();
Sessions=sessionFaetory.openSession();
Transactiontx=s.beginTransacfinn();
Employeee=HewEmployee();
e.setName("James");
e.setAge(25);
try{
s.save(e);
//保存持久類對象
mit();
//提交到數(shù)據(jù)庫
//從數(shù)據(jù)庫中查找剛才保存的數(shù)據(jù)
Queryq=s.createSQLQuery("select*fromEmployee").addEntity(Employee.class);
List<Employee>rs=q.list();
for(inti=0;i<rs.size();i++){
Employeee1=rs.get(i);
System.out.println("id:"+e1.getId()+"name:"+e1.getName()+"age:"+
e1.getAge());
}
s.close();
}
catch(Exceptione1)
e1.printStackTraee();
tx.rollback();
}
}
}
程序運(yùn)行結(jié)果為:
Hibernate:selectmax(id)fromEmployee
Hibernate:insertintoEmployee(name,age,id)values(?,?,?)
Hibernate:select*fromEmployee
id:1name:Jamesage:25
需要注意的是,輸出結(jié)果的前三行是由Hibernate框架打印出的信息,最后一行數(shù)據(jù)為從數(shù)據(jù)庫中查找出的數(shù)據(jù)。
具體而言,使用Hibernate框架有諸多好處,主要表現(xiàn)為以下幾個方面。
1)提高開發(fā)效率。
2)使得開發(fā)可以完全采用面向?qū)ο蟮乃枷耄恍枰P(guān)心數(shù)據(jù)庫的關(guān)系模型。
3)使用Hibernate開發(fā)的系統(tǒng)有很好的可移植性,可以很容易地實現(xiàn)不同數(shù)據(jù)庫之間的移植而不需要關(guān)系不同數(shù)據(jù)庫SQL語句的差異。
4)支持透明持久化,Hibernate的API沒有侵入性,當(dāng)保存一個對象時,這個對象不需要繼承Hibernate中的任何類和實現(xiàn)任何接口。
雖然如此,但Hibernate只適用于針對單一對象簡單的增、刪、查、改,而對于批量的修改/刪除的場合,則不適用,這也是OR框架的弱點,所以,當(dāng)要使用數(shù)據(jù)庫的特定優(yōu)化機(jī)制時,不適合使用Hibernate。
引申:
1.在使用Hibernate時如何提高性能?
使用Hibernate時,有多種方法可以用來提高性能,具體內(nèi)容如下所示。
1)延遲加載。當(dāng)Hibernate從數(shù)據(jù)庫獲取某一個對象數(shù)據(jù)、獲取某一個對象的集合屬性值時或者獲取某一個對象所關(guān)聯(lián)的另一個對象時,并不會立即從數(shù)據(jù)庫中把數(shù)據(jù)加載到對象中,而是通過建立一個代理對象,把這個對象的屬性都設(shè)置為默認(rèn)值,只有當(dāng)這些數(shù)據(jù)在被使用時才會從數(shù)據(jù)庫中去加載對應(yīng)的數(shù)據(jù),使用這種方法有助于提高Hibernate的性能。
2)緩存技術(shù)。Hibernate中提供了一級緩存與二級緩存,合理的利用緩存也有助于提高系統(tǒng)的性能,為了避免不合理的利用緩存導(dǎo)致內(nèi)存的過度消耗降低系統(tǒng)的性能,可以通過合理配置緩存的參數(shù)(例如配置緩存可以加載數(shù)據(jù)的個數(shù))來避免這個問題。
3)優(yōu)化查詢語句。通過優(yōu)化查詢語句來提高系統(tǒng)的性能。
2.Hibernate中怎樣實現(xiàn)類之間的關(guān)系?(例如一對多、多對多關(guān)系)
類之間的關(guān)系主要體現(xiàn)在表之間的關(guān)系,它們都是對對象進(jìn)行操作,程序中把所有表與類都映射在一起,它們通過配置文件中的many-to-one、one-to-many、many-to-man),來進(jìn)行配置。
6.
什么是Hibernate的二級緩存正確答案:緩存的目的是為了通過減少應(yīng)用程序?qū)ξ锢頂?shù)據(jù)源訪問的次數(shù)來提高程序運(yùn)行的效率,原理則是把當(dāng)前或接下來一段時間可能會用到的數(shù)據(jù)保存到內(nèi)存中,在使用時直接從內(nèi)存中讀取,而不是從硬盤中去讀取,簡單來說,緩存就是數(shù)據(jù)庫中數(shù)據(jù)在內(nèi)存中的“臨時容器”。
在Hibernate中,緩存用來把從數(shù)據(jù)庫中查詢出來的和使用過的對象保存在內(nèi)存中,以便在后期需要用到這個對象時可以直接從緩存中來獲取這個對象(只有當(dāng)該對象在緩存中不存在時才會去數(shù)據(jù)庫中查詢)。顯然,由于避免了因大量發(fā)送SQL語句到數(shù)據(jù)庫查詢導(dǎo)致的性能損耗,緩存機(jī)制可以顯著提高程序的運(yùn)行效率。
在Hibernate中有一級緩存與二級緩存的概念,一級緩存由Session來管理,二級緩存由SessionFactory來管理。在使用時,二級緩存是可有可無的,但一級緩存是必不可少的。
一級緩存使用的場合如下:當(dāng)使用Session查詢數(shù)據(jù)時,首先會在該Session內(nèi)部查找該對象是否存在,若存在,則直接返回,否則,就到數(shù)據(jù)庫中去查詢,并將查詢的結(jié)果緩存起來以便后期使用。一級緩存的缺點就是當(dāng)使用Session來表示一次會話時,它的生命周期較短,而且它是線程不安全的,不能被多個線程共享,因此,在實際使用時,對效率的提升不是非常明顯。
鑒于以上原因,二級緩存的概念被引入了。二級緩存用來為Hibernate配置一種全局的緩存,以便實現(xiàn)多個線程與事務(wù)共享。在使用了二級緩存機(jī)制后,當(dāng)查詢數(shù)據(jù)時,會首先在內(nèi)部緩存巾去查找,如果不存在,接著在二級緩存中查找,最后才去數(shù)據(jù)庫中查找。與一級緩存相比,二級緩存是獨(dú)立于Hibernte的軟件部件,屬于第三方的產(chǎn)品,常見的產(chǎn)品有。EhCache、OSCache和JbossCache等,Hibernate3以后默認(rèn)使用的產(chǎn)品為EhCache。在使用時,可以根據(jù)需求通過配置二級緩存插件來實現(xiàn)二級緩存功能,Hibernate為了集成這些插件,提供了org.hibernate.cache.CacheProvider接口來充當(dāng)緩存插件與Hibernate之間的適配器。當(dāng)然,二級緩存除了以內(nèi)存作為存儲介質(zhì)外,還可以選用硬盤等外部存儲設(shè)備。
合理地使用Hibernate的二級緩存機(jī)制有助于提高系統(tǒng)的運(yùn)行效率,但如果使用得不合理,不僅不會提高效率,反而有可能會降低系統(tǒng)的性能。
二級緩存一般適用于以下幾種情況:
1)數(shù)據(jù)量較小。如果數(shù)據(jù)量太大,緩存太多,會消耗大量內(nèi)存,造成內(nèi)存資源短缺,從而降低系統(tǒng)的性能。
2)對數(shù)據(jù)的修改較少。如果進(jìn)行大量的修改,就需要頻繁地對緩存中數(shù)據(jù)與數(shù)據(jù)庫中的數(shù)據(jù)進(jìn)行同步,而這也會影響系統(tǒng)的性能。
3)不會被大量的應(yīng)用共享的數(shù)據(jù)。如果數(shù)據(jù)被大量線程或事務(wù)共享,多線程訪問時的同步機(jī)制也會影響系統(tǒng)的性能。
4)不是很重要的數(shù)據(jù)。如果查詢的數(shù)據(jù)非常重要(例如財務(wù)數(shù)據(jù)),對數(shù)據(jù)的正確性要求非常高,最好不要使用二級緩存。
7.
Hibernate中session的update()和saveOrUpdate()、load()和get()有什么區(qū)別正確答案:Hibernate的對象有3種狀態(tài),分別為:瞬時態(tài)(Transient)、持久態(tài)(Persistent)和脫管態(tài)(Detached)。處于持久態(tài)的對象也被稱為PO(PersistenceObject),瞬時對象和脫管對象也被稱為VO(ValueObject)。
saveOrUpdate()方法同時包含了save()和update()方法的功能。Hibernate會根據(jù)對象的狀態(tài)來確定是調(diào)用save()方法還是調(diào)用update()方法:若對象是持久化對象,則不進(jìn)行任何操作,直接返回;若傳入的對象與session中的另一個對象有相同的標(biāo)識符,則拋出一個異常;若對象的標(biāo)識符屬性(用來唯一確定一個對象)在數(shù)據(jù)庫中不存在或者是一個臨時值,則調(diào)用save()方法把它保存到數(shù)據(jù)庫中,否則,調(diào)用update()方法更新對象的值到數(shù)據(jù)庫中。鑒于此,在使用時,若能確定對象的狀態(tài),則最好不要調(diào)用saveOrUpdate()方法,這樣有助于提高效率,例如,如果能夠確定這個對象所對應(yīng)的值在數(shù)據(jù)庫中肯定不存在,那么就可以直接調(diào)用save()方法。
get()方法與load()方法都是用來通過從數(shù)據(jù)庫中加載所需的數(shù)據(jù)來創(chuàng)建一個持久化的對象,它們主要有以下幾個不同點:
1)如果數(shù)據(jù)庫中不存在該對象,load()方法會拋出一個ObjectNotFoundException異常,而get()方法則會返回null。
2)get()方法首先查詢Session內(nèi)部緩存,若不存在,則接著查詢二級緩存,最后查詢數(shù)據(jù)庫;而load()方法在創(chuàng)建時會首先查詢Session內(nèi)部緩存,如果不存在,就創(chuàng)建代理對象,實際使用數(shù)據(jù)時才查詢二級緩存和數(shù)據(jù)庫,因此load()方法支持延遲加載(對象中的屬性在使用時才會加載,而不是在創(chuàng)建對象時就加載所有屬性)。
3)get()方法永遠(yuǎn)只返回實體類,而load()方法可以返回實體類的代理類實例。
4)get()方法和find()方法都是直接從數(shù)據(jù)庫中檢索,而load()方法的執(zhí)行則比較復(fù)雜:首先查找Session的persistentContext中是否有緩存,若有,則直接返回;若沒有,則判斷是否是lazy。如果不是,直接訪問數(shù)據(jù)庫檢索,查到記錄返回,查不到拋出異常;若是lazy,則需要建立代理對象,對象的initialized屬性為false,target屬性為null。在訪問獲得的代理對象的屬性時檢索數(shù)據(jù)庫,若找到記錄,則把該記錄的對象復(fù)制到代理對象的target上,并將initialized置為true;若找不到,就拋出異常。
8.
Hibernate有哪些主鍵生成策略正確答案:Hibernate作為一種優(yōu)秀的持久層框架,采用ORM方式,大大地簡化了對數(shù)據(jù)庫的操作。同時,Hibernate框架提供的主鍵生成策略,使開發(fā)人員可以通過在實體類的映射文件中設(shè)定關(guān)鍵字來告訴Hibernate要使用的主鍵生成方式,然后Hibernate會根據(jù)設(shè)定完成數(shù)據(jù)庫的主鍵控制。Hibernate中的主鍵生成策略主要有如下幾種:
1)Assigned。使用該方法時,主鍵不是由Hibernate生成的,而是由外部程序負(fù)責(zé)生成,所以無需Hibernate參與,但需要開發(fā)人員在調(diào)用save()方法之前來指定,否則調(diào)用save()方法會拋出異常。其缺點是在執(zhí)行新增操作時需查詢數(shù)據(jù)庫判斷生成的主鍵是否已經(jīng)存在,否則很容易產(chǎn)生主鍵沖突。
2)Hilo。該方法使用一個高/低位算法(High/LowAlgorithm)生成long、short或int類型的標(biāo)識符。給定一個表和字段作為高位值的來源(默認(rèn)的表是hibernate_unique_key,默認(rèn)的字段是next_hi)。它將id的產(chǎn)生源分成兩部分:DB+內(nèi)存,然后,按照算法結(jié)合在一起產(chǎn)生id值,從而可以在很少的連接次數(shù)內(nèi)產(chǎn)生多條記錄,提高效率。
需要注意的是,該方法需要額外的數(shù)據(jù)庫表保存主鍵生成歷史狀態(tài)。Hilo能保證同一個數(shù)據(jù)庫中主鍵的唯一性,但不能保證多個數(shù)據(jù)庫之間主鍵的唯一性。
3)Seqhilo。與Hilo類似,Seqhilo是一種通過高/低位算法實現(xiàn)的主鍵生成機(jī)制,只是主鍵歷史狀態(tài)保存在Sequence中,適用于支持Sequence的數(shù)據(jù)庫,例如Oracle。
4)Increment。這種方式采用對主鍵自增的方式來生成新的主鍵。實現(xiàn)機(jī)制為:在當(dāng)前應(yīng)用實例中維持一個變量,以保存當(dāng)前的最大值,之后每當(dāng)需要生成主鍵時,便會將此值加1作為主鍵。該方式要求數(shù)據(jù)庫支持Sequence。
盡管該方式優(yōu)點眾多,但問題也不少。首先,新增數(shù)據(jù)前需要先查詢一遍,這會影響系統(tǒng)的性能;其次,主鍵的類型只能是數(shù)值的int或long型;最后,會產(chǎn)生并發(fā)問題,即如果當(dāng)前有多個實例訪問同一個數(shù)據(jù)庫,那么由于各個實例各自維護(hù)主鍵狀態(tài),不同實例可能生成同樣的主鍵,從而造成主鍵重復(fù)異常。所以,該方法只適合單線程對數(shù)據(jù)庫的訪問方式,不適合在多進(jìn)程并發(fā)更新數(shù)據(jù)庫的場合使用。因此,如果同一數(shù)據(jù)庫有多個實例訪問,最好不要使用這種方法。需要注意的是,該主鍵遞增的方式是由Hibernate來維護(hù)的。
5)Identity。這種方式采用數(shù)據(jù)庫提供的自增方式來生成新的主鍵,例如DB2、SQLServer、MySQL中的主鍵生成機(jī)制。該方式的特點是不需要Hibernate與開發(fā)人員的干涉,使用起來非常方便,但會給程序在不同數(shù)據(jù)庫的移植帶來嚴(yán)重不便。
6)Sequence。這種方式采用數(shù)據(jù)庫提供的Sequence(序列)機(jī)制生成主鍵。這就要求數(shù)據(jù)庫必須提供Sequence機(jī)制,例如Oracle就提供Sequence機(jī)制。其主要缺點是當(dāng)程序在不同數(shù)據(jù)庫之間移植時,特別是從支持序列的數(shù)據(jù)庫移植到不支持序列的數(shù)據(jù)庫時,使用該方式會非常麻煩。
7)Native。在該方式中,由Hibernate根據(jù)底層數(shù)據(jù)庫自行選取Identity、Hilo、Sequence中的一種作為主鍵生成方式,例如,對于Oracle采用Sequence方式,對于MySQL和SQLServer采用Identity方式。該方式的一個主要優(yōu)點就是靈活性更強(qiáng),便于程序的移植。
8)UUID。uuid.hex由Hibernate基于128位唯一值產(chǎn)生算法生成16進(jìn)制數(shù)值(編碼后以長度32位的字符串表示)作為主鍵。這種方式能夠保證在不同的環(huán)境下主鍵的一致性。
uuid.string與uuid.hex類似,只是生成的主鍵未進(jìn)行編碼(長度16位)。在某些數(shù)據(jù)庫(例如PostgreSQL)中可能出現(xiàn)問題。
該方式能夠保證數(shù)據(jù)庫中的主鍵唯一性,但是在生成的主鍵占用比較多的存儲空間。
9)ForeignGUID。這種方式用于在一對一的關(guān)系中采用一種特殊的算法來生成主鍵,從而保證了主鍵的唯一性。
10)select。這種方式使用觸發(fā)器生成主鍵,主要用于早期的數(shù)據(jù)庫主鍵生成機(jī)制,現(xiàn)在使用得比較少。
9.
如何實現(xiàn)分頁機(jī)制正確答案:在交互式的應(yīng)用程序中,當(dāng)數(shù)據(jù)量很大時,如果一次性把所需數(shù)據(jù)全部從數(shù)據(jù)庫中查詢出來,不僅非常耗費(fèi)時間,而且還會消耗大量的內(nèi)存,導(dǎo)致用戶操作的延時,嚴(yán)重影響系統(tǒng)的可用性。因此,為了降低系統(tǒng)的響應(yīng)時間,提高系統(tǒng)的性能,往往會使用分頁機(jī)制,即不是把用戶所需數(shù)據(jù)一次性全部查找出來,而是把數(shù)據(jù)分成很多的頁,每一頁只包含指定的記錄數(shù),在查詢時根據(jù)需求每次只查找一頁或多頁的數(shù)據(jù)而不是所有數(shù)據(jù)。由于采用分頁機(jī)制使得查詢的結(jié)果集中數(shù)據(jù)量減少了,同時也降低了內(nèi)存的消耗,因此可以顯著降低響應(yīng)時間,有助于提高系統(tǒng)的可用性,增強(qiáng)用戶體驗。
下面主要介紹兩種分頁的實現(xiàn)方法。
(1)Hibernate自帶的分頁機(jī)制
Hibernate提供了一個支持跨系統(tǒng)的分頁機(jī)制,該機(jī)制保證無論底層是什么樣的數(shù)據(jù)庫都能使用統(tǒng)一的接口進(jìn)行分頁操作。其用法如下:首先,通過Session對象獲取Query對象;其次,使用Query對象的setFirstResult()方法來設(shè)置要查詢的第一行數(shù)據(jù);最后,用setMaxResults()方法來設(shè)置要查詢結(jié)果集的大小。
下列代碼的功能就是從第100條開始取出50條記錄:
Queryq=session_createQuery("fromStudentass");
q.setFirstResult(100);
q.setMaxResults(50);
Listl=q.list();
(2)用SQL語句來實現(xiàn)分頁
以MySQL為例,可以使用limit關(guān)鍵字來實現(xiàn)分頁。其用法如下:
select*fromtableNamewhere條件limitbegin,count
第一個參數(shù)(begin)代表查詢開始的地方,第二個參數(shù)(count)代表每頁顯示多少條數(shù)據(jù)。需要注意的是,第一頁用0表示,例如查詢語句select*fromemployeelimit0,2表示從表employee中第一行開始查找兩行數(shù)據(jù)。
10.
什么是SSH正確答案:SSH是Structs、Spring和Hibernate的首字母組合,它是一種比較流行的用來開發(fā)Web應(yīng)用程序的開源框架,用于構(gòu)建靈活、易于擴(kuò)展的多層Web應(yīng)用。
使用SSH框架開發(fā)的系統(tǒng)從職責(zé)上可以分為4層:表示層、業(yè)務(wù)邏輯層、數(shù)據(jù)持久化層和域模塊層,如圖所示。
SSH模塊圖
其中,Struts實現(xiàn)了MVC模式,它對Model、View和Controller的各個模塊都提供了支持。Struts框架使用JSP實現(xiàn)了視圖部分,模型部分則通過Hibernate框架提供的支持來實現(xiàn)數(shù)據(jù)的持久化,業(yè)務(wù)層則使用了Spring作為支持來管理對象。
接著,Spring把抽象出的模型用Java類來實現(xiàn),同時為這些模型編寫對應(yīng)的DAO接口,同時給出基于Hibernate的DAO的實現(xiàn),即實現(xiàn)Java對象與關(guān)系數(shù)據(jù)庫之間數(shù)據(jù)的轉(zhuǎn)換。然后使用Spring來完成業(yè)務(wù)邏輯,來管理Hibernate與Struts對象。
采用SSH框架,不僅能實現(xiàn)視圖、控制器與模型的徹底分離,而且還能實現(xiàn)業(yè)務(wù)邏輯層與數(shù)據(jù)持久層的分離。無論前端如何變化,模型層只需很少的改動即可滿足要求;此外,數(shù)據(jù)庫的變化也不會對前端有所影響,從而大大提高了系統(tǒng)的可復(fù)用性、可擴(kuò)展性與易維護(hù)性。而且由于不同層之間的低耦合度,使得團(tuán)隊成員能夠并行開發(fā),從而大大節(jié)省了時間,提高了應(yīng)用的開發(fā)效率。
由于SSH提供了很多有用的框架,因此能顯著提高項目的開發(fā)效率。其主要優(yōu)點如下:
1)Struts實現(xiàn)了MVC模式,這種模式的特點是對應(yīng)用程序進(jìn)行了很好的分層,使得開發(fā)人員只需要把開發(fā)重點放在業(yè)務(wù)邏輯的開發(fā)即可。不僅如此,Struts還提供了許多非常有用的標(biāo)簽庫,這些標(biāo)簽?zāi)軌蝻@著地提高開發(fā)人員的開發(fā)效率。
2)Spring可以用來管理對象。使用Spring的IoC容器,把對象之間的依賴關(guān)系交給Spring,降低組件之間的耦合性,讓開發(fā)人員更專注于業(yè)務(wù)邏輯的開發(fā)。Spring采用了IoC和AOP的思想,使得它具有很好的模塊化,程序與可以根據(jù)需求使用其中的一個模塊。Spring還提供了一些非常有用的功能,例如事務(wù)管理等。
3)Hibernate作為一個輕量級的持久性框架,實現(xiàn)了高效的對象關(guān)系映射,使得開發(fā)可以完全采用面向?qū)ο蟮乃枷?,而不需要關(guān)心數(shù)據(jù)庫的關(guān)系模型。使用Hibernate開發(fā)的系統(tǒng)有很好的可移植性,可以很容易地實現(xiàn)不同數(shù)據(jù)庫之間的移植,而不需要關(guān)心不同數(shù)據(jù)庫SQL語句的差異。
11.
SQL語言的功能有哪些正確答案:SQL是結(jié)構(gòu)化查詢語言(StructuredQueryLanguage)的縮寫,其功能包括數(shù)據(jù)查詢、數(shù)據(jù)操縱、數(shù)據(jù)定義和數(shù)據(jù)控制4個部分。
數(shù)據(jù)查詢是數(shù)據(jù)庫中最常見的操作,通過select語句可以得到所需的信息。SQL語言的數(shù)據(jù)操縱語句(DataManipulationLanguage,DML)主要包括插入數(shù)據(jù)、修改數(shù)據(jù)以及刪除數(shù)據(jù)3種語句。SQL語言使用數(shù)據(jù)定義語言(DataDefinitionLanguage,DDL)實現(xiàn)數(shù)據(jù)定義功能,可對數(shù)據(jù)庫用戶、基本表、視圖、索引進(jìn)行定義與撤銷。數(shù)據(jù)控制語句(DataControlLanguage,DCL)用于對數(shù)據(jù)庫進(jìn)行統(tǒng)一的控制管理,保證數(shù)據(jù)在多用戶共享的情況下能夠安全。
基本的SQL語句有select、insert、update、delete、create、drop、grant、revoke等。其具體使用方式見表?;維QL語句的使用方式
關(guān)鍵字描述語法格式數(shù)據(jù)查詢select選擇符合條件的記錄select*fromtablewhere條件語句數(shù)據(jù)操縱insert插入一條記錄insertintotabIe(字段1,字段2...)values(值1,值2...)update更新語句updatetableset字段名=字段值where條件表達(dá)式delete刪除記錄Deletefromtablewhere條件表達(dá)式數(shù)據(jù)定義create數(shù)據(jù)表的建立createtabletablename(字段1,字段2...)drop數(shù)據(jù)表的刪除droptabletablename數(shù)據(jù)控制grant為用戶授予系統(tǒng)權(quán)限grant<系統(tǒng)權(quán)限>|<角色>[,<系統(tǒng)權(quán)限>|<角色>]…to<用戶名>|<角色>|public[,<用戶名>|<角色>]…[withadminoption]revoke收回系統(tǒng)權(quán)限r(nóng)evoke<系統(tǒng)權(quán)限>|<角色>[,<系統(tǒng)權(quán)限>|<角色>]…from<用戶名>|<角色>|public[,<用戶名>|<角色>]…
例如,設(shè)教務(wù)管理系統(tǒng)中有3個基本表:
學(xué)生信息表S(SNO,SNAME,AGE,SEX),其屬性分別表示學(xué)號、學(xué)生姓名、年齡和性別。
選課信息表SC(SNO,CNO,SCGRADE),其屬性分別表示學(xué)號、課程號和成績。
課程信息表C(CNO,CNAME,CTEACHER),其屬性分別表示課程號、課程名稱和任課老師姓名。
下面運(yùn)用SQL語句進(jìn)行相關(guān)操作。
1)把SC表中每門課程的平均成績插入到另外一個已經(jīng)存在的表SC_C(CNO,CNAME,AVG_GRADE)中,其中AVG_GRADE表示每門課程的平均成績。
INSERTINTOSC_C(CNO,CNAME,AVG_GRADE)
SELECTSC.CNO,C.NAME,AVG(SCGRADE)FROMSC,CWHERESC.CNO=C.CNO
2)從SC表中把選何昊老師所授課程的女生的選課記錄刪除。
DELETEFROMSC.S.CWHERESC.SNO=S.SNOANDSC.CNO=C.CNOANDC.CTEACHER='何昊'
3)規(guī)定女生所選修何吳老師的課程的成績都應(yīng)該在80分以上(含80分)。
ALERTTABLESC,S,C
ADDCONSTRAINTCRADECHECK(GRADE>=80)
WHERESC.CNO=C.CNOandSC.SNO=S.SNOANDC.CTEACHER='何昊'
4)找出沒有選修過何昊老師的課程的所有學(xué)生的姓名。
SELECTSNAMEFROMS
WHERENOTEXISTS(
SELECT*FROMSC.CWHERESC.CNO=C.CNOANDCNAME='何昊'ANDSC.SNO=S.SNO)
5)列出有兩門以上(含兩門)不及格課程(成績小于60)的學(xué)生的姓名及其平均成績。
SELECTS.SNO,S.SNAME,AVG_SCGRADE=AVG(SC.SCGRADE)
FROMS,SC,(
SELECTSNOFROMSCWHERESCGRADE<60GROUPBYSNO
HAVINGCOUNT(DISTINCTCNO)>=2)AWHERES.SNO=A.SNOANDSC.SNO=A.SNO
GROUPBYS.SNO,S.SNAME
6)列出既學(xué)過“1”號課程,又學(xué)過“2”號課程的所有學(xué)生的姓名。
SELECTS.SNO,S.SNAME
FROMS,(SELECTSC.SNOFROMSC,C
WHERESC.CNO=C.CNOANDC.CNAMEIN('1','2')
GROUPBYSNO
HAVINGCOUNT(DISTINCTCNO)=2
)SCWHERES.SNO=SC.SNO
7)列出“1”號課成績比“2”號同學(xué)該門課成績高的所有學(xué)生的學(xué)號。
SELECTS.SNO,S.SNAME
FROMS,(
SELECTSC1.SN0
FROMSCSC1,CC1,SCSC2,CC2
WHERESC1.CNO=C1.CN0ANDC1.NAME='1'
ANDSC2.CNO=C2.CN0ANDC2.NAME='2'
ANDSC1.SCGRADE>SC2.SCGRADE
)SCWHERES.SNO=SC.SN0
8)列出“1”號課成績比“2”號課成績高的所有學(xué)生的學(xué)號及其“1”號課和“2”號課的成績。
SELECTS.SNO,S.SNAME,SC.[1號課成績],SC.[2號課成績]
FROMS,(
SELECTSC1.SN0,[1號課成績]=SC1.SCGRADE,[2號課成績]=SC2.SCGRADE
FROMSCSC1.CC1,SCSC2,CC2
WHERESC1.CN0=C1.CN0ANDC1.NAME='1'
ANDSC2.CN0=C2.CN0ANDC2.NAME='2'
ANDSC1.SCGRADE>SC2.SCGRADE
)SCWHERES.SNO=SC.SNO
引申:delete與truncate命令有哪些區(qū)別?
相同點:都可以用來刪除一個表中的數(shù)據(jù)。
不同點:
1)truncate一是一個數(shù)據(jù)定義語言(DataDefinitionLanguage,DDL),它會被隱式地提交,一旦執(zhí)行后將不能回滾。delete執(zhí)行的過程是每次從表中刪除一行數(shù)據(jù),同時將刪除的操作以日志的形式進(jìn)行保存,以便將來進(jìn)行回滾操作。
2)用delete操作后,被刪除的數(shù)據(jù)占用的存儲空間還在,還可以恢復(fù)。而用truncate操作刪除數(shù)據(jù)后,被刪除的數(shù)據(jù)會立即釋放占用的存儲空間,被刪除的數(shù)據(jù)是不能被恢復(fù)的。
3)truneate的執(zhí)行速度比delete快。
常見筆試題:
Oracle數(shù)據(jù)庫的一個表中有若干條數(shù)據(jù),其占用的存儲空間為10MB,如果用delete語句刪除表中的所有數(shù)據(jù),此時該表所占存儲空間為多大?
答案:10MB。數(shù)據(jù)庫中delete操作類似于在Windows系統(tǒng)中把數(shù)據(jù)放到回收站,還可以恢復(fù),因此它不會立即釋放所占的存儲空間。如果想在刪除數(shù)據(jù)后立即釋放存儲空間,可以使用truncate。
12.
內(nèi)連接與外連接有什么區(qū)別正確答案:內(nèi)連接,也被稱為自然連接,只有兩個表相匹配的行才能在結(jié)果集中出現(xiàn)。返回的結(jié)果集選取了兩個表中所有相匹配的數(shù)據(jù),舍棄了不匹配的數(shù)據(jù)。由于內(nèi)連接是從結(jié)果表中刪除與其他連接表中沒有匹配的所有行,所以內(nèi)連接可能會造成信息的丟失。內(nèi)連接的語法如下:
selectfieldlistfromtablel[inner]jointable2ontable1.column=table2.column
內(nèi)連接是保證兩個表中的所有行都滿足連接條件,而外連接則不然。外連接不僅包含符合連接條件的行,而且還包括左表(左外連接時)、右表(右外連接時)或兩個邊接表(全外連接)中的所有數(shù)據(jù)行。SQL的外連接共有3種類型:左外連接(關(guān)鍵字為LEFI、OUTERJOIN)、右外連接(關(guān)鍵字為RIGHTOUTERJOIN)和全外連接(關(guān)鍵字為FULLOUTERJOIN)。外連接的用法和內(nèi)連接一樣,只是將INNERJOIN關(guān)鍵字替換為相應(yīng)的外連接關(guān)鍵字即可。
內(nèi)連接只顯示符合連接條件的記錄,外連接除了顯示符合連接條件的記錄外,還顯示表中的記錄,例如,如果使用左外連接,還顯示左表中的記錄。
下面為學(xué)生表A和學(xué)生表B。表1為學(xué)生表A,表2為學(xué)生表B。表1學(xué)生表A學(xué)號姓名0001張三0002李四0003王五表2學(xué)生表B學(xué)號課程名0001數(shù)學(xué)0002英語0003數(shù)學(xué)0004計算機(jī)對表A和表B進(jìn)行內(nèi)連接后的結(jié)果見表3。表3內(nèi)連接學(xué)號姓名課程名0001張三數(shù)學(xué)0002李四英語0003王五數(shù)學(xué)對表A和表B進(jìn)行左外連接后的結(jié)果見表4。表4左外連接學(xué)號姓名課程名0001張三數(shù)學(xué)0002李四英語0003王五數(shù)學(xué)0004
計算機(jī)
13.
什么是事務(wù)正確答案:事務(wù)是數(shù)據(jù)庫中一個單獨(dú)的執(zhí)行單元(Unit),它通常由高級數(shù)據(jù)庫操作語言(例如SQL)或編程語言(例如C++、Java等)編寫的用戶程序的執(zhí)行所引起。當(dāng)在數(shù)據(jù)庫中更改數(shù)據(jù)成功時,在事務(wù)中更改的數(shù)據(jù)便會提交,不再改變。否則,事務(wù)就取消或者回滾,更改無效。
以網(wǎng)上購物為例,其交易過程至少包括以下幾個步驟:
1)更新客戶所購商品的庫存信息。
2)保存客戶付款信息。
3)生成訂單并且保存到數(shù)據(jù)庫中。
4)更新用戶相關(guān)信息,例如購物數(shù)量等。
在正常情況下,這些操作都將順利進(jìn)行,最終交易成功,與交易相關(guān)的所有數(shù)據(jù)庫信息也成功地更新。但是,如果遇到突然斷電或是其他意外情況,導(dǎo)致這一系列過程中任何一個環(huán)節(jié)出了差錯(例如在更新商品庫存信息時發(fā)生異常、顧客銀行賬戶余額不足等),都將導(dǎo)致整個交易過程失敗。而一旦交易失敗,數(shù)據(jù)庫中所有信息都必須保持交易前的狀態(tài)不變,例如最后一步更新用戶信息時失敗而導(dǎo)致交易失敗,那么必須保證這筆失敗的交易不影響數(shù)據(jù)庫的狀態(tài),即原有的庫存信息沒有被更新、用戶也沒有付款、訂單也沒有生成。否則,數(shù)據(jù)庫的信息將會不一致,或者出現(xiàn)更為嚴(yán)重的不可預(yù)測的后果,數(shù)據(jù)庫事務(wù)正是用來保證這種情況下交易的平穩(wěn)性和可預(yù)測性的技術(shù)。
事務(wù)必須滿足4個屬性,即原子性(atomicity)、一致性(consistency)、隔離性(isolation)、持久性(durability),即ACID4種屬性。
(1)原子性
事務(wù)是一個不可分割的整體,為了保證事務(wù)的總體目標(biāo),事務(wù)必須具有原子性,即當(dāng)數(shù)據(jù)修改時,要么全執(zhí)行,要么全不執(zhí)行,即不允許事務(wù)部分地完成,避免了只執(zhí)行這些操作的一部分而帶來的錯誤。原子性要求事務(wù)必須被完整執(zhí)行。
(2)一致性
一個事務(wù)執(zhí)行之前和執(zhí)行之后,數(shù)據(jù)庫數(shù)據(jù)必須保持一致性狀態(tài)。數(shù)據(jù)庫的一致性狀態(tài)應(yīng)該滿足模式鎖指定的約束,那么在完整執(zhí)行該事務(wù)后數(shù)據(jù)庫仍然處于一致性狀態(tài)。為了維護(hù)所有數(shù)據(jù)的完整性,在關(guān)系型數(shù)據(jù)庫中,所有規(guī)則必
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 教育政策的績效評估與影響研究試題及答案
- 機(jī)電工程考試案例匯編與試題及答案
- 軟件設(shè)計師考試成功之路試題與答案
- 數(shù)據(jù)通訊基礎(chǔ)試題及答案
- 2024年中成藥制藥生產(chǎn)線資金籌措計劃書代可行性研究報告
- 機(jī)電工程各章節(jié)核心要點的試題及答案
- 嵌入式開發(fā)中的常見問題試題及答案
- 西方政治制度改革試題及答案
- 機(jī)電工程服務(wù)與管理試題及答案
- 西方政治制度在民族理解與和諧社會建設(shè)中的作用試題及答案
- 休閑會所轉(zhuǎn)讓合同范本
- 骨科專業(yè)疾病臨床診療規(guī)范2025年版
- 上海市徐匯區(qū)2023-2024學(xué)年八年級下學(xué)期期末語文試題(解析版)
- 2025雅安事業(yè)單位筆試真題
- 血脂異常健康管理專題
- 端午節(jié)文化傳承課件
- 兒童輪狀病毒胃腸炎免疫預(yù)防專家共識(2024年版)解讀
- 經(jīng)濟(jì)學(xué)習(xí)題含參考答案解析
- 檢驗危急值在急危重病臨床應(yīng)用的專家共識
- BIM技術(shù)在建筑行業(yè)工程項目施工質(zhì)量改進(jìn)與持續(xù)改進(jìn)報告
- 2025-2030中國旅游行業(yè)現(xiàn)狀供需分析及市場深度研究發(fā)展前景及規(guī)劃可行性分析研究報告
評論
0/150
提交評論