关于struts,spring,hibernate的几个问题
Struts2:
1.為什么每次請求都要創建一個Action對象?
re: 為了防止線程迸發,如果每次都使用同一個Action進行數據修改和傳遞的話,容易引起線程迸發,使線程不安全。
?
2.ModelDriven攔截器的配置中refreshModelBeforeResult解決了什么問題?
re:在數據輸出之前將數據接收的Bean里面的數據清空。解決了數據混淆的可能性。
?
3.為什么在web.xml中配置的StrutsPrepareAndExecuteFilter要過濾所有的請求?
re: No1.可以將數據進行過濾。
No2.可以對數據進行轉碼處理,將數據進行統一的編碼。
?
4.關于ValueStack(值棧)?
re:堆值,堆里面的值。
struts2背后的數據傳輸機制,實際上就是對OGNL的封裝,OGNL主要的功能就是賦值與取值(context,root兩種方式),Struts2正是通過ValueStack來進行賦值與取值的!
ValueStack是一個接口,而OgnlValueStack是strtus2中的缺省實現。ValueStack中的數據,分兩個部分存放:root和context(這與OGNL中的概念一致),同時ValueStack暴露相關的接口:
void setValue(String expr, Object value);
Object findValue(String expr);
用來通過OGNL表達式對ValueStack中的數據進行操作!
ValueStack中的root對象是CompoundRoot,CompoundRoot繼承了ArraryList,提供了額外的方法:push()和pop()方法,用來對root對象中所包含的數據進行存取!
public class CompoundRoot extends ArrayList {
public CompoundRoot() {
}
public CompoundRoot(List list) {
super(list);
}
public CompoundRoot cutStack(int index) {
return new CompoundRoot(subList(index, size()));
}
public Object peek() {
return get(0);
}
public Object pop() {
return remove(0);
}
public void push(Object o) {
add(0, o);
}
}
正是通過這兩個方法,CompoundRoot變成了一個棧結構!壓棧操作,將導致對象被放到CompoundRoot的第0個元素上(第0個元素是棧頂),其它對象被依次往后移動;出棧操作,將導致CompoundRoot的第0個元素被移除(即棧頂元素被彈出),其它對象被依次往前移動!
OGNL不支持多個root對象,而struts2能夠支持多個root對象,它對OGNL做了擴展。
如果某個OGNL表達式被傳遞給ValueStack(即調用ValueStack的setValue或findValue方法),而表達式中包含有對root對象的訪問操作,ValueStack將依次從棧頂往棧底搜索CompoundRoot對象中所包含的對象,看哪個對象具有相應的屬性,找到之后,立刻返回。
在Struts2中,一個請求在最終到達Action的方法之前,Action對象本身會被壓入ValueStack(實際上就是放到ValueStack的CompoundRoot中),所以Action對象是CompoundRoot中的一個元素。
?
3.Struts2是如何實現MVC設計模式的?
re: 所謂MVC模式,即 模型(Model),視圖(View)和控制,其目的是實現Web系統的職能分工。其中Model層實現系統中的業務邏輯,通常可以用JavaBean或EJB來實現; View層用于與用戶的交互,通常用JSP來實現; Controller層是Model與View之間溝通的橋梁,它可以分派用戶的請求并選擇恰當的視圖以用于顯示,同時它也可以解釋用戶的輸入并將它們映射為模型層可執行的操作。
在Struts2里面是將每次頁面的請求進行處理,然后將請求需要輸出的數據轉發的需要做數據顯示的頁面,Struts2只是起一個數據接受和轉接的功能,就是Controler控制器,而傳來數據的頁面叫View顯示層,Struts2將數據提交給進行處理的類叫Model模型層,專門進行數據處理和數據庫的鏈接。
?
Spring:
1.為什么要用spring?
re:
No1.主要將各個框架進行有效的聯系起來,縮短實際編程的時間,起一個潤滑劑的作用。
No2.可以將各個框架進行有效的管理和控制,讓數據傳輸中安全。
?
2.關于IOC/DI。
re: IOC(控制翻轉或是依賴注入(DI)):所謂控制反轉,即將講程序的控制權由代碼轉交給了容器,當某角色(可能是一個java實例,調用者)需要另外一個角色(另外一個java實例,被調用者)的協助時,在傳統的程序設計中通常有調用者創建被調用者的實例,但是在spring,創建被調用者不再是由調用者完成,而是交由spring容器完成,然后注入被調用者。
這樣將所有組件在Spring提供的外部容器中加載,提高安全性,減低耦合性,使各個框架或者類之間的依賴性降低。
?
3.什么是聲明式的事務管理?為什么要使用聲明式的事務管理?Spring如何實現聲明式的事務管理?
re: Spring的聲明式事務顧名思義就是采用聲明的方式來處理事務。這里所說的聲明,就是指在配置文件中申明。用在Spring配置文件中聲明式的處理事務來代替代碼式的處理事務。這樣的好處是,事務管理不侵入開發的組件(spring為非侵入式框架),具體來說,業務邏輯對象就不會意識到正在事務管理之中,事實上也應該如此,因為事務管理是屬于系統層面的服務,而不是業務邏輯的一部分,如果想要改變事務管理策劃的話,也只需要在定義文件中重新配置即可;在不需要事務管理的時候,只要在設定文件上修改一下,即可移去事務管理服務,無需改變代碼重新編譯,這樣維護起來極其方便。
聲明事物管理主要是將在進行對數據庫中數據進行添加或者修改的時候需要執行事物管理。主要是避免在執行數據修改和添加的時候數據添加或者修改不完全,導致數據丟失。
Spring是使用AOP面向切面的思想*(面向切面編程,可以通過預編譯方式和運行期動態代理實現在不修改源代碼的情況下給程序動態統一添加功能的一種技術)進行事物管理的。因而聲明式事務是以方法為單位,Spring的事務屬性自然就在于描述事務應用至方法上的策略,在Spring中事務屬性有以下四個參數:
No1.傳播行為
No2.隔離級別
No3.只讀提示
No4.事務超時期間
?
4.把spring和hibernate集成,定義事務管理特性的時候,為何要將除了添加、刪除、更新操作之外的方法,即主要執行查詢任務的方法定義為read-only?
re: 因為添加和刪除和更新都涉及到數據庫的修改,而查詢并為涉及數據修改,所以只需要定義只讀,這樣可以提高效率,進行更加方便的事務管理。而事務管理主要是為添加和刪除和更新設計的。
?
Hibernate:
1.請你談談你對OR映射的理解?
re:將每個實體類都映射為數據庫中的一個表,或將數據庫中的表映射為一個實體類。
2.很多人說Hibernate不適合大項目,性能有問題,你是如何理解的?
re:因為Hibernate屬于大型框架,里面對方法的封裝比較多,讓SQL控制權降低。這樣的話,適用性就會降低,在不必要的操作上會浪費時間。但是只要將Hibernate里的配置進行優化,也能提高其性能。(關于hibernate的具體優化請見下回分解吧。)
?
3.Hibernate為什么一定要定義一個數據庫標識?
re:可以讓映射文件變得簡潔,消除無用的噪音(比如TBL_前綴等)。Hibernate使用的默認策略是幾乎什么都不做,所以使用標識的作用就是使數據操作更加簡潔和方便.
?
4.為什么Hibernate建議你的實體類實現hashCode和equals方法?
re:因為Hibernate使用了一級和二級緩存,很多查詢為了提高效率Hibernate都會先從緩存中進行查找,然后再從數據庫進行查找。而HashCode是唯一的,所以這樣避免數據操作出現數據混淆的可能,而equals的作用是對比Hibernate緩存中數據是否一致。
?
5.談談你對Hibernate實體類中的數據庫標識與數據庫主鍵之間關系的認識?
re:數據庫標識是為了方便和簡潔映射文件,而主鍵是為了使數據不會重復。
?
6.談談你對Hibernate關聯映射與數據庫外鍵之間關系的認識?
re:Hibernate在進行映射的時候會將數據庫的關系也進行映射將數據庫中的外鍵也使用標簽的形式進行管理,這樣在人為操作的時候就不需要手動的管理數據庫關系了。
?
7.調用session.save()方法,hibernate一定會發出insert語句嗎?談談你的理解
re:不會,具體執行步驟如下:
No1. 首先在Session內部緩存中進行查找,如果發現則直接返回。
No2. 執行實體類對應的Interceptor.isUnsaved方法(如果有的話),判斷對象是否為未保存狀態。
No3. 根據unsaved-value判斷對象是否處于未保存狀態。
No4. 如果對象未保存(Transient狀態),則調用save方法保存對象。
No5. 如果對象未已保存(Detached狀態),則調用update方法將對象與Session重新關聯。
?
8.調用session.update()方法,hibernate一定會發出update語句嗎?談談你的理解
re:不會,具體步驟同上。
?
9.請你聊一下以下名詞、概念或用法:lazy、lazy="extra"、inverse、fetch、fetch="join"、fetch="subselect"、batch-size
re:
lazy懶加載,hibernate映射文件默認的lazy = true.lazy="extra"extra屬性是不大容易重視的,其實它和true差不多,但有個小的智能的地方是,即調用集合的size/contains等方法的時候,hibernate并不會去加載整個集合的數據,而是發出一條聰明的SQL語句,以便獲得需要的值,只有在真正需要用到這些集合元素對象數據的時候,才去發出查詢語句加載所有對象的數據
inverse控制翻轉,主要是為了讓誰去維護關系,一般是在主表中配置,將維護關系的只能交給主鍵。
fetch取值,fetch="join"主要是在查詢的時候Hibernate會自動查詢有關聯的表。fetch="join",hibernate會通過select語句使用外連接來加載其關聯實體或集合,此時lazy會失效.(也可以通過設置lazy為false,實現加載關聯表)
fetch="subselect",另外發送一條select語句抓取在前面查詢到的所有實體對象的關聯集合
batch-size配置這個屬性是讓Hibernate在執行批量的數據庫操作
?
10.配置了lazy="true"一定會實現懶加載嗎?
re:不一定,因為如果再配置中你也使用fetch屬性的話此時lazy就會失效。(lazy設為true,同理)
?
11.請你談談Hibernate中的"N+1"問題
re:
所謂N+1問題,即hibernate在做關聯查詢的時候有幾個關聯對象,就會有多少個查詢語句,這便是N,而+1是查詢實體本生還需要一個查詢語句,所以hibernate查詢一個有關聯的實體便會產生N+1條查詢語句,這便是N+1.對于hibernate的N+1問題。而Hibernate中使用N+1策略時執行Criteria時,會將自動進行SQL構造,并且映射到實體Bean中,就只會返回一個結果,這樣不僅提高了性能,而且在處理返回值的時候也變得比較輕松。
?
12.請你談談Hibernate有哪些最佳實踐?
re:
就目前本人沒有用過太多的框架,就不和其他框架做比較。在此就簡單說一下心得吧。
No1.對象-關系映射。
hibernate支持關系型數據庫,并且它與sql緊密結合的程度較高,有自己的查詢語言hql,它與sql的區別在于hql是面向對象的而不是針對數據模型。但是如果需要也可以在hibernate中使用 sql.并且hibernate還提供了靈活的映射機制,以及session級緩存,和sessionfactosy級緩存。只是session級緩存是非線程安全的,如果多線程訪問可能引起數據存取的不一致,甚至系統宕機。
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的关于struts,spring,hibernate的几个问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 解决逆向工程mapper映射文件不发布问
- 下一篇: 商城项目使用到的主要技术分析