SSH經典知識點整合

1、Hibernate工作原理及爲什麼要用?

 

 

  1. 1.       答:hibernate,通過對jdbc進行封裝,對 java類和關係數據庫進行mapping,實現了對關係數據庫的面向對象方式的操作.

1.對JDBC訪問數據庫的代碼做了封裝,大大簡化了數據訪問層繁瑣的重複性代碼。hibernate的性能非常好,因爲它是個輕量級框架。

1.它支持各種關係數據庫,從一對一到多對多的各種複雜關係。

 

1).讀取並解析配置文件

 

2).讀取並解析映射信息,創建SessionFactory

 

3).打開Sesssion

 

4).創建事務Transation

 

5).持久化操作

 

6).提交事務

 

7).關閉Session

 

8).關閉SesstionFactory

 

 

2.什麼是Hibernate延遲加載?

 

延遲加載機制是爲了避免一些無謂的性能開銷而提出來的,所謂延遲加載就是當在真正需要數據的時候,才真正執行數據加載操作。

 

答:對象關係映射(Object—Relational Mapping,簡稱 ORM)是一種爲了解決

面向對象與面向關係數據庫存在的互不匹配的現象的技術;

 

 

3.數據庫,比如 100 用戶同時來訪,要採取什麼技術解決?

 

答:可採用連接池。

 

 

4.什麼是 ORM?

 

     答:對象關係映射(Object—Relational Mapping,簡稱 ORM)是一種爲了解決

面向對象與面向關係數據庫存在的互不匹配的現象的技術;

 

5.Hibernate 有哪 5 個核心接口?

 

 

    Configuration 接口:配置 Hibernate,根據其啓動 hibernate,創建SessionFactory 對象

SessionFactory 接口:初始化 Hibernate,充當數據存儲源的代理,創建session對象sessionFactory 是線程安全的.

Session 接口:負責保存、更新、刪除、加載和查詢對象,是線程不安全的,避免多個線程共享同一個 session,是輕量級、一級緩存;

Transaction (tr?n'z?k??n) 接口:管理事務;

Query 和 Criteria([krai'ti?ri?]) 接口:執行數據庫的查詢。

 

6.關於 hibernate: 【基礎】

 

 

1)在 hibernate 中,在配置文件呈標題一對多,多對多的標籤是什麼;

 

2)Hibernate 的二級緩存是什麼;

 

 

Hibernate 是如何處理事務的;

 

  答: 1)一對多的標籤爲<one-to-many> ;多對多的標籤爲<many-to-many>;

 

   2)sessionFactory 的緩存爲 hibernate 的二級緩存;

  

3)Hibernate 的事務實際上是底層的 JDBC Transaction 的封裝或者是 JTA

Transaction 的封裝;默認情況下使用 JDBCTransaction。

 

 

 

7.Hibernate 的應用(Hibernate 的結構)?【基礎】

 

 

答:

//首先獲得 SessionFactory 的對象

 SessionFactory sessionFactory = new Configuration().configure().

                                         buildSessionFactory();

  

//然後獲得 session 的對象

       Session session = sessionFactory.openSession();

 

//其次獲得 Transaction 的對象

 Transaction tx = session.beginTransaction();

 

 //執行相關的數據庫操作:增,刪,改,查

 

 session.save(user);

//增加, user 是 User 類的對象

 

 session.delete(user);

//刪除

       session.update(user);

//更新

 

 Query query = session.createQuery(“from User”);

//查詢

       List list = query.list();

 

 //提交事務

 

 tx.commit();

 

 //如果有異常,我們還要作事務的回滾,恢復到操作之前

 

 tx.rollback();

 

 //最後還要關閉 session,釋放資源

  

session.close();

 

 

8.Hibernate的查詢方式

 

 

本地SQL查詢、Criteria、Hql

 

9.說說在hibernate中使用Integer做映射和使用int做映射之間有什麼差別

 

Integer?? code和int?? code;的區別:Integer是對象.???? code?? =?? null;?? 對象可以爲空.? int?? 是普通類型,???? 不可能?? =?? null.????? 根據你的數據庫code是可以空的,?? 故應該映射成Integer.?

 

 

10.請說出Hibernate中持久化對象的生命週期以及各種狀態直接的區別,並描述相互之間是如何轉換的?

 

 

Hibernate中持久化對象的生命週期有臨時態、持久態和遊離態三種。

 

處於臨時態的對象主鍵值爲空,並且未與session關聯,數據未保存到數據庫中

處於持久態的對象與session關聯起來,持久化後對象中的數據被保存到數據庫中,並且主鍵值按照.hbm.xml文件中配置的生成方式生成相應的值

處於遊離態的對象脫離了session的管理,是持久化後的一種狀態,主鍵值按照.hbm.xml文件中配置的生成方式生成相應的值

當new一個新的對象時,該對象處於臨時態

當該對象被當作session的參數使用的時候,該對象處於持久態

事務提交,session關閉後,該對象處於遊離態

 

 

 

11.用Hibernate的session時要注意幾點

 

 

1).在更新數據時,要用open()

 

2).使用完之後,要close(),這樣連接池會回收該連接。

 

 

12.Spring和Hibernate的事務管理方式有什麼不同?

 

 

hibernate的事務管理方式僅僅就是託管給JDBC(如果用JTA那麼就是JTA),而JDBC的一切行爲包括事務是基於一個connection的.

spring也是調用hibernate中事務管理的API。hibernate的事務管理,一般是編程性的。

 

 

13.Hibernate如何獲取指定主鍵id的某對象,請舉例,並進行可能的優劣

 

比較

三種方式:get(),load()和find()

Get()和load()是先在緩存中查找對象,如果找不到再去數據庫中查詢;

Find()是無論何時都在數據庫中查詢對象。

 

 

14.請描述Hibernate中的緩存機制

 

第一級是Session的緩存。由於Session對象的生命週期通常對應一個數據庫事務或者一個應用事務,因此它的緩存是事務範圍的緩存。

 

第二級緩存是一個可插拔的的緩存插件,它是由SessionFactory負責管理。由於SessionFactory對象的生命週期和應用程序的整個過程對應,因此第二級緩存是進程範圍或者集羣範圍的緩存。

 

 

15.Hibernate的二級緩存策略的一般過程如下:

 

 

1) 條件查詢的時候,總是發出一條select * from table_name where …. (選擇所有字段)這樣的SQL語句查詢數據庫,一次獲得所有的數據對象。

 

2) 把獲得的所有數據對象根據ID放入到第二級緩存中。

 

3) 當Hibernate根據ID訪問數據對象的時候,首先從Session一級緩存中查;查不到,如果配置了二級緩存,那麼從二級緩存中查;查不到,再查詢數據庫,把結果按照ID放入到緩存。

 

 

 

16.get與load區別

 

1:如果數據庫中,沒有userId的對象。如果通過get方法加載,則返回的是一個null;如果通過load加載,則返回一個代理對象,如果後面代碼如果調用user對象的某個屬性(比如user.getPassword())會拋出異常:org.hibernate.ObjectNotFoundException;

區別2:load支持延遲加載,get不支持延遲加載。

 

 

s1.什麼是重量級?什麼是輕量級?【基礎】

 

 

答:輕量級是指它的創建和銷燬不需要消耗太多的資源,意味着可以在程序中經

常創建和銷燬 session 的對象;重量級意味不能隨意的創建和銷燬它的實例,會

佔用很多的資源.

 

 

s2.事務處理?【基礎】

 

 

答:Connection 類中提供了 3 個事務處理方法:

   setAutoCommit(Boolean autoCommit):設置是否自動提交事務,默認爲自動

提交事務,即爲 true,通過設置 false 禁止自動提交事務;

   commit():提交事務;

   rollback():回滾事務。

 

 

 

s3.Java 中訪問數據庫的步驟?Statement 和 PreparedStatement 之間的區別?【基礎】

 

 

答:Java 中訪問數據庫的步驟如下:

 

   1)註冊驅動;

 

 2)建立連接;

 

 3)創建 Statement;

 

 4)執行 sql 語句;

  

5)處理結果集(若 sql 語句爲查詢語句);

 

 6)關閉連接。

 

 PreparedStatement 被創建時即指定了 SQL 語句,通常用於執行多次結構相

同的 SQL 語句。

 

 

s4.JDBC,Hibernate 分頁怎樣實現?【中等難度】

 

答:方法分別爲:

 

1)      Hibernate 的分頁:

 

Query query = session.createQuery("from Student");

 

query.setFirstResult(firstResult);

 

//設置每頁開始的記錄號

 

query.setMaxResults(resultNumber);

 

//設置每頁顯示的記錄數

 

Collection students = query.list();

 

 

s5.如何優化Hibernate?

 

 

1.使用雙向一對多關聯,不使用單向一對多

 

2.不用一對一,用多對一取代

 

 

3.配置對象緩存,不使用集合緩

 

         

 

                                             S2SH經典面試題:

Struts2面試題

struts2工作流程

 

Struts 2框架本身大致可以分爲3個部分:

核心控制器FilterDispatcher、業務控制器Action和用戶實現的企業業務邏輯組件。

核心控制器FilterDispatcher是Struts 2框架的基礎,

包含了框架內部的控制流程和處理機制。

業務控制器Action和業務邏輯組件是需要用戶來自己實現的。

用戶在開發Action和業務邏輯組件的同時,還需要編寫相關的配置文件,

供核心控制器FilterDispatcher來使用。

Struts 2的工作流程相對於Struts 1要簡單,與WebWork框架基本相同,

所以說Struts 2是WebWork的升級版本。基本簡要流程如下:

1 、客戶端初始化一個指向Servlet容器的請求;

2、 這個請求經過一系列的過濾器(Filter)

(這些過濾器中有一個叫做ActionContextCleanUp的可選過濾器,

  這個過濾器對於Struts2和其他框架的集成很有幫助,例如:SiteMesh Plugin)

3 、接着FilterDispatcher被調用,

     FilterDispatcher詢問ActionMapper來決定這個請是否需要調用某個Action

4、如果ActionMapper決定需要調用某個Action,

     FilterDispatcher把請求的處理交給ActionProxy

5、ActionProxy通過Configuration Manager詢問框架的配置文件,

     找到需要調用的Action類

6、ActionProxy創建一個ActionInvocation的實例。

7、ActionInvocation實例使用命名模式來調用,

     在調用Action的過程前後,涉及到相關攔截器(Intercepter)的調用。

8、一旦Action執行完畢,ActionInvocation負責根據struts.xml中的配置找到對應的返回結果   。返回結果通常是(但不總是,也可 能是另外的一個Action鏈)一個需要被表示的JSP或者FreeMarker的模版。    在表示的過程中可以使用Struts2 框架中繼承的標籤。   在這個過程中需要涉及到ActionMapper

9、響應的返回是通過我們在web.xml中配置的過濾器
10、如果ActionContextCleanUp是當前使用的,則FilterDispatecher將不會清理sreadlocalActionContext;如果ActionContextCleanUp不使用,則將會去清理sreadlocals。

Struts工作機制?

工作機制:
Struts的工作流程:
在web應用啓動時就會加載初始化ActionServlet,ActionServlet從
struts-config.xml文件中讀取配置信息,把它們存放到各種配置對象
當ActionServlet接收到一個客戶請求時,將執行如下流程.
-(1)檢索和用戶請求匹配的ActionMapping實例,如果不存在,就返回請求路徑無效信息;
-(2)如果ActionForm實例不存在,就創建一個ActionForm對象,把客戶提交的表單數據保存到ActionForm對象中;
-(3)根據配置信息決定是否需要表單驗證.如果需要驗證,就調用ActionForm的validate()方法;
-(4)如果ActionForm的validate()方法返回null或返回一個不包含ActionMessage的ActuibErrors對象, 就表示表單驗證成功;
-(5)ActionServlet根據ActionMapping所包含的映射信息決定將請求轉發給哪個Action,如果相應的Action實例不存在,就先創建這個實例,然後調用Action的execute()方法;
-(6)Action的execute()方法返回一個ActionForward對象,ActionServlet在把客戶請求轉發給 ActionForward對象指向的JSP組件;
-(7)ActionForward對象指向JSP組件生成動態網頁,返回給客戶;

說下Struts的設計模式

MVC模式: web應用程序啓動時就會加載並初始化ActionServler。用戶提交表單時,一個配置好的ActionForm對象被創建,並被填入表單相應的數據,ActionServler根據Struts-config.xml文件配置好的設置決定是否需要表單驗證,如果需要就調用ActionForm的Validate()驗證後選擇將請求發送到哪個Action,如果Action不存在,ActionServlet會先創建這個對象,然後調用Action的execute()方法。Execute()從ActionForm對象中獲取數據,完成業務邏輯,返回一個ActionForward對象,ActionServlet再把客戶請求轉發給ActionForward對象指定的jsp組件,ActionForward對象指定的jsp生

成動態的網頁,返回給客戶。

攔截器和過濾器的區別

1、攔截器是基於java反射機制的,而過濾器是基於函數回調的。
2、過濾器依賴於servlet容器,而攔截器不依賴於servlet容器。
3、攔截器只能對Action請求起作用,而過濾器則可以對幾乎所有請求起作用。
4、攔截器可以訪問Action上下文、值棧裏的對象,而過濾器不能。
5、在Action的生命週期中,攔截器可以多次調用,而過濾器只能在容器初始化時被調用一次。

struts1於struts2的比較

1、Action   類: 
    Struts1要求Action類繼承一個抽象基類。Struts1的一個普遍問題是使用抽象類編程而不是接口。 
  Struts   2   Action類可以實現一個Action接口,也可實現其他接口,使可選和定製的服務成爲可能。Struts2提供一個ActionSupport基類去 實現常用的接口。Action接口不是必須的,任何有execute標識的POJO對象都可以用作Struts2的Action對象。
2、線程模式: 
    Struts1   Action是單例模式並且必須是線程安全的,因爲僅有Action的一個實例來處理所有的請求。單例策略限制了Struts1  Action能作的事,並且要在開發時特別小心。Action資源必須是線程安全的或同步的。 
Struts2   Action對象爲每一個請求產生一個實例,因此沒有線程安全問題。(實際上,servlet容器給每個請求產生許多可丟棄的對象,並且不會導致性能和垃圾回收問題)
3、Servlet   依賴: 
    Struts1   Action   依賴於Servlet  API   ,因爲當一個Action被調用時HttpServletRequest   和  HttpServletResponse   被傳遞給execute方法。 
Struts   2   Action不依賴於容器,允許Action脫離容器單獨被測試。如果需要,Struts2   Action仍然可以訪問初始的request和response。但是,其他的元素減少或者消除了直接訪問HttpServetRequest  和   HttpServletResponse的必要性。
4、可測性: 
   測試Struts1   Action的一個主要問題是execute方法暴露了servlet   API(這使得測試要依賴於容器)。一個第三方擴展--Struts   TestCase--提供了一套Struts1的模擬對象(來進行測試)。
Struts   2   Action可以通過初始化、設置屬性、調用方法來測試,“依賴注入”支持也使測試更容易。 
5、捕獲輸入: 
   Struts1   使用ActionForm對象捕獲輸入。所有的ActionForm必須繼承一個基類。因爲其他JavaBean不能用作ActionForm,開發者經 常創建多餘的類捕獲輸入。動態Bean(DynaBeans)可以作爲創建傳統ActionForm的選擇,但是,開發者可能是在重新描述(創建)已經存 在的JavaBean(仍然會導致有冗餘的javabean)。
Struts   2直接使用Action屬性作爲輸入屬性,消除了對第二個輸入對象的需求。輸入屬性可能是有自己(子)屬性的rich對象類型。Action屬性能夠通過   web頁面上的taglibs訪問。Struts2也支持ActionForm模式。rich對象類型,包括業務對象,能夠用作輸入/輸出對象。這種   ModelDriven   特性簡化了taglib對POJO輸入對象的引用。
6、表達式語言: 
   Struts1   整合了JSTL,因此使用JSTL   EL。這種EL有基本對象圖遍歷,但是對集合和索引屬性的支持很弱。
Struts2可以使用JSTL,但是也支持一個更強大和靈活的表達式語言-- "Object   Graph   Notation   Language "  (OGNL).
7、綁定值到頁面(view): 
   Struts   1使用標準JSP機制把對象綁定到頁面中來訪問。
   Struts   2   使用  "ValueStack "技術,使taglib能夠訪問值而不需要把你的頁面(view)和對象綁定起來。ValueStack策略允許通過一系列名稱相同但類型不同的屬性重用頁面(view)。
8、類型轉換: 
   Struts   1   ActionForm   屬性通常都是String類型。Struts1使用Commons-Beanutils進行類型轉換。每個類一個轉換器,對每一個實例來說是不可配置的。
  Struts2   使用OGNL進行類型轉換。提供基本和常用對象的轉換器。
9、校驗: 
   Struts   1支持在ActionForm的validate方法中手動校驗,或者通過Commons   Validator的擴展來校驗。同一個類可以有不同的校驗內容,但不能校驗子對象。
   Struts2支持通過validate方法和XWork校驗框架來進行校驗。XWork校驗框架使用爲屬性類類型定義的校驗和內容校驗,來支持chain校驗子屬性
10、Action執行的控制: 
   Struts1支持每一個模塊有單獨的Request  Processors(生命週期),但是模塊中的所有Action必須共享相同的生命週期。 
   Struts2支持通過攔截器堆棧(Interceptor   Stacks)爲每一個Action創建不同的生命週期。堆棧能夠根據需要和不同的Action一起使用。

爲什麼要使用Struts2

Struts2 是一個相當強大的JavaWeb開源框架,是一個基於POJO的Action的MVC Web框架。它基於當年的Webwork和XWork框架,繼承其優點,同時做了相當的改進。
1.Struts2基於MVC架構,框架結構清晰,開發流程一目瞭然,開發人員可以很好的掌控開發的過程。
2使用OGNL進行參數傳遞。
OGNL提供了在Struts2裏訪問各種作用域中的數據的簡單方式,你可以方便的獲取Request,Attribute,Application,Session,Parameters中的數據。大大簡化了開發人員在獲取這些數據時的代碼量。
3強大的攔截器
Struts2 的攔截器是一個Action級別的AOP,Struts2中的許多特性都是通過攔截器來實現的,例如異常處理,文件上傳,驗證等。攔截器是可配置與重用的,可以將一些通用的功能如:登錄驗證,權限驗證等置於攔截器中以完成一些Java Web項目中比較通用的功能。在我實現的的一Web項目中,就是使用Struts2的攔截器來完成了系統中的權限驗證功能。
4易於測試
Struts2的Action都是簡單的POJO,這樣可以方便的對Struts2的Action編寫測試用例,大大方便了5Java Web項目的測試。
易於擴展的插件機制在Struts2添加擴展是一件愉快而輕鬆的事情,只需要將所需要的Jar包放到WEB-INF/lib文件夾中,在struts.xml中作一些簡單的設置就可以實現擴展。
6模塊化管理
Struts2已經把模塊化作爲了體系架構中的基本思想,可以通過三種方法來將應用程序模塊化:將配置信息拆分成多個文件把自包含的應用模塊創建爲插件創建新的框架特性,即將與特定應用無關的新功能組織成插件,以添加到多個應用中去。
7全局結果與聲明式異常
爲應用程序添加全局的Result,和在配置文件中對異常進行處理,這樣當處理過程中出現指定異常時,可以跳轉到特定頁面。
他的如此之多的優點,是很多人比較的青睞,與spring ,Hibernate進行結合,組成了現在比較流行的ssh框架,當然每個公司都要自己的框架,也是ssh變異的產品。

struts2有哪些優點?

1)在軟件設計上Struts2的應用可以不依賴於Servlet API和struts API。 Struts2的這種設計屬於無侵入式設計;  

2)攔截器,實現如參數攔截注入等功能;  

3)類型轉換器,可以把特殊的請求參數轉換成需要的類型;  

4)多種表現層技術,如:JSP、freeMarker、Velocity等;  

5)Struts2的輸入校驗可以對指定某個方法進行校驗;  

6)提供了全局範圍、包範圍和Action範圍的國際化資源文件管理實現 

struts2是如何啓動的?

 struts2框架是通過Filter啓動的,即StrutsPrepareAndExecuteFilter,此過濾器爲struts2的核心過濾器;  

StrutsPrepareAndExecuteFilter的init()方法中將會讀取類路徑下默認的配置文件struts.xml完成初始化操作。struts2讀取到struts.xml的內容後,是將內容封裝進javabean對象然後存放在內存中,以後用戶的每次請求處理將使用內存中的數據,而不是每次請求都讀取struts.xml文件。

struts2框架的核心控制器是什麼?它有什麼作用?  

1)Struts2框架的核心控制器是StrutsPrepareAndExecuteFilter。  

2)作用:  

 負責攔截由<url-pattern>/*</url-pattern>指定的所有用戶請求,當用戶請求到達時,該Filter會過濾用戶的請求。默認情況下,如果用戶請求的路徑  

不帶後綴或者後綴以.action結尾,這時請求將被轉入struts2框架處理,否則struts2框架將略過該請求的處理。  

可以通過常量"struts.action.extension"修改action的後綴,如:  

<constant name="struts.action.extension" value="do"/>  

如果用戶需要指定多個請求後綴,則多個後綴之間以英文逗號(,)隔開。

<constant name="struts.action.extension" value="do,go"/>  

struts2配置文件的加載順序?  

struts.xml ——> struts.properties  

常量可以在struts.xml或struts.properties中配置,如果在多個文件中配置了同一個常量,則後一個文件中配置的常量值會覆蓋前面文件中配置的常量值.  

struts.xml文件的作用:通知Struts2框架加載對應的Action資源

struts2常量的修改方式?  

常量可以在struts.xml或struts.properties中配置,兩種配置方式如下:  

1)在struts.xml文件中配置常量  

<constant name="struts.action.extension" value="do"/>  

2)在struts.properties中配置常量(struts.properties文件放置在src下):  

struts.action.extension=do

struts2如何訪問HttpServletRequest、HttpSession、ServletContext三個域對象?  

方案一:  

HttpServletRequestrequest =ServletActionContext.getRequest();  

HttpServletResponse response =ServletActionContext.getResponse();  

HttpSession  session=   request.getSession(); 

ServletContextservletContext=ServletActionContext.getServletContext();  

方案二:  

類 implements ServletRequestAware,ServletResponseAware,SessionAware,ServletContextAware  

注意:框架自動傳入對應的域對象 

struts2是如何管理action的?這種管理方式有什麼好處?  

struts2框架中使用包來管理Action,包的作用和java中的類包是非常類似的。  

主要用於管理一組業務功能相關的action。在實際應用中,我們應該把一組業務功能相關的Action放在同一個包下。  

struts2中的默認包struts-default有什麼作用?  

1)struts-default包是由struts內置的,它定義了struts2內部的衆多攔截器和Result類型,而Struts2很多核心的功能都是通過這些內置的攔截器實現,如:從請求中  

把請求參數封裝到action、文件上傳和數據驗證等等都是通過攔截器實現的。當包繼承了struts-default包才能使用struts2爲我們提供的這些功能。   

2)struts-default包是在struts-default.xml中定義,struts-default.xml也是Struts2默認配置文件。 Struts2每次都會自動加載 struts-default.xml文件。  

3)通常每個包都應該繼承struts-default包。      

struts2如何對指定的方法進行驗證?  

1)validate()方法會校驗action中所有與execute方法簽名相同的方法;  

2)要校驗指定的方法通過重寫validateXxx()方法實現, validateXxx()只會校驗action中方法名爲Xxx的方法。其中Xxx的第一個字母要大寫;  

3)當某個數據校驗失敗時,調用addFieldError()方法往系統的fieldErrors添加校驗失敗信息(爲了使用addFieldError()方法,action可以繼承ActionSupport), 如果系統 的fieldErrors包含失敗信息,struts2會將請求轉發到名爲input的result;  

4)在input視圖中可以通過<s:fielderror/>顯示失敗信息。  

5)先執行validateXxxx()->validate()->如果出錯了,會轉發<result name="input"/>所指定的頁面,如果不出錯,會直接進行Action::execute()方法 

struts2默認能解決get和post提交方式的亂碼問題嗎?  

不能。struts.i18n.encoding=UTF-8屬性值只能解析POST提交下的亂碼問題。 

請你寫出struts2中至少5個的默認攔截器?  

fileUpload      提供文件上傳功能  

i18n            記錄用戶選擇的locale  

cookies         使用配置的name,value來是指cookies  

checkbox        添加了checkbox自動處理代碼,將沒有選中的checkbox的內容設定爲false,而html默認情況下不提交沒有選中的checkbox。  

chain           讓前一個Action的屬性可以被後一個Action訪問,現在和chain類型的result()結合使用。  

alias           在不同請求之間將請求參數在不同名字件轉換,請求內容不變 

值棧ValueStack的原理與生命週期?  

1)ValueStack貫穿整個 Action 的生命週期,保存在request域中,所以ValueStack和request的生命週期一樣。當Struts2接受一個請求時,會迅速創建ActionContext,  

ValueStack,action。然後把action存放進ValueStack,所以action的實例變量可以被OGNL訪問。 請求來的時候,action、ValueStack的生命開始,請求結束,action、    ValueStack的生命結束;  

2)action是多例的,和Servlet不一樣,Servelt是單例的;  

3)每個action的都有一個對應的值棧,值棧存放的數據類型是該action的實例,以及該action中的實例變量,Action對象默認保存在棧頂;  

4)ValueStack本質上就是一個ArrayList;  

5)關於ContextMap,Struts 會把下面這些映射壓入 ContextMap 中:  

parameters  :   該 Map 中包含當前請求的請求參數  

request     :   該 Map 中包含當前 request 對象中的所有屬性  session :該 Map 中包含當前 session 對象中的所有屬性  

application :該 Map 中包含當前 application 對象中的所有屬性  

attr:該 Map 按如下順序來檢索某個屬性: request, session, application           

6)使用OGNL訪問值棧的內容時,不需要#號,而訪問request、session、application、attr時,需要加#號;  

7)注意: Struts2中,OGNL表達式需要配合Struts標籤纔可以使用。如:<s:property value="name"/>  

8)在struts2配置文件中引用ognl表達式 ,引用值棧的值 ,此時使用的"$",而不是#或者%;  

ActionContext、ServletContext、pageContext的區別?  

1)ActionContext是當前的Action的上下文環境,通過ActionContext可以獲取到request、session、ServletContext等與Action有關的對象的引用;  

2)ServletContext是域對象,一個web應用中只有一個ServletContext,生命週期伴隨整個web應用;  

3)pageContext是JSP中的最重要的一個內置對象,可以通過pageContext獲取其他域對象的應用,同時它是一個域對象,作用範圍只針對當前頁面,當前頁面結束時,pageContext銷燬,  

生命週期是JSP四個域對象中最小的。  

result的type屬性中有哪幾種結果類型?  

一共10種:    

dispatcher          

struts默認的結果類型,把控制權轉發給應用程序裏的某個資源不能把控制權轉發給一個外部資源,若需要把控制權重定向到一個外部資源, 應該使用  

redirect結果類型  

redirect    把響應重定向到另一個資源(包括一個外部資源)  

redirectAction      把響應重定向到另一個 Action  

freemarker、velocity、chain、httpheader、xslt、plainText、stream 

攔截器的生命週期與工作過程?  

1)每個攔截器都是實現了Interceptor接口的 Java 類;  

2)init(): 該方法將在攔截器被創建後立即被調用, 它在攔截器的生命週期內只被調用一次. 可以在該方法中對相關資源進行必要的初始化;  

3)intercept(ActionInvocation invocation): 每攔截一個動作請求, 該方法就會被調用一次;  

4)destroy: 該方法將在攔截器被銷燬之前被調用, 它在攔截器的生命週期內也只被調用一次;  

5)struts2中有內置了18個攔截器。

爲什麼要用struts2

JSP、Servlet、JavaBean技術的出現給我們構建強大的企業應用系統提供了可能。但用這些技術構建的系統非常的繁亂,所以在此之上,我們需要一個規則、一個把這些技術組織起來的規則,這就是框架,Struts便應運而生。

基於Struts開發的應用由3類組件構成:控制器組件、模型組件、視圖組件

struts2的validate框架是如何運作的

在struts配置文件中配置具體的錯誤提示,再在FormBean中的validate()方法具體調用。

說下struts2的設計模式

MVC模式: web應用程序啓動時就會加載並初始化ActionServler。用戶提交表單時,一個配置好的ActionForm對象被創建,並被填入表單相應的數據,ActionServler根據Struts-config.xml文件配置好的設置決定是否需要表單驗證,如果需要就調用ActionForm的 Validate()驗證後選擇將請求發送到哪個Action,如果Action不存在,ActionServlet會先創建這個對象,然後調用 Action的execute()方法。Execute()從ActionForm對象中獲取數據,完成業務邏輯,返回一個ActionForward對象,ActionServlet再把客戶請求轉發給ActionForward對象指定的jsp組件,ActionForward對象指定的jsp生成動態的網頁,返回給客戶。

struts2如何完成文件的上傳?  

1、JSP頁面:  

1)JSP頁面的上傳文件的組件:<s: file name=”upload” />,如果需要一次上傳多個文件, 就必須使用多個 file 標籤, 但它們的名字必須是相同的,即:  

 name=“xxx”的值必須一樣;  

2)必須把表單的enctype屬性設置爲:multipart/form-data;  

 3)表單的方法必須爲post,因爲post提交的數據在消息體中,而無大小限制。  

2、對應的action:  

 1)在 Action 中新添加 3 個和文件上傳相關的屬性;  

2)如果是上傳單個文件, uploadImage屬性的類型就是 java.io.File, 它代表被上傳的文件, 第二個和第三個屬性的類型是 String, 它們分別代表上傳文  

件的文件名和文件類型,定義方式是分別是:  

jsp頁面file組件的名稱+ContentType,  jsp頁面file組件的名稱+FileName  

3)如果上上傳多個文件, 可以使用數組或 List 

struts2學習總結

1:在action中定義的變量,在jsp頁面中顯示用:<s:property value="變量名" />

2:在頁面中實現自動增加的序號用iterator的statuts的index屬性 eg:

<s:iterator value="#request.inOutAccountList"id="data" status="listStat">

<s:property value="#listStat.index+1"/>

</s:iterator>

3:在action類中取得request和session對象的方法

Map session = ActionContext.getContext().getSession();
HttpServletRequest request = ServletActionContext.getRequest ();

設置它們的值的方法

session.put("operation", "add");
request.setAttribute("name", name);

頁面中取得它們的值:

<s:property value="#session.operation"/>
<s:property value="#request.name"/>

4:頁面中奇偶行樣式不一樣的控制方法:

<tr class="<s:if test='#listStat.odd == true'>tableStyle-tr1</s:if><s:else>tableStyle-tr2</s:else>">

5:單選框和複選框的使用方法

1):可以設置默認選中值,注意list的值的設置,通過這種方式使key和value不一樣,這種方法比較常用(checkboxlist or radio)

<s:radio name="uncarInsPolicy.policyStateCode"
list="#{'5':'通過' , '2':'不通過'}"
listKey="key"
listValue="value"
value='5'
/>

2):這裏的key和value的值是一樣的(checkboxlist or radio)

<s:checkboxlist
list="{'Red', 'Blue', 'Green'}"
name="favoriteColor"/>

6:struts2 中的標籤會生成類似由<tr><td></td></tr>構成的字串(具體什麼標籤生成什麼,可以查看生成後的頁面的源代碼)如果不限制這些多餘代碼的生成,頁面將變得無法控制,所以一般我們是不希望它生成多餘的代碼的,具體的設置方法如果,在struts.xml中統一配置
<constant name="struts.ui.theme" value="simple"/>加上該句即可
也可以通過在頁面中將tag的theme屬性設爲"simple"取消其默認的表格佈局
不過最好是:自定義一個theme,並將其設爲默認應用到整個站點,如此一來就可以得到統一的站點風格

7:jsp頁面中格式化日期的方法

<s:date name="unCarInsModificationInfo.createTime"format="yyyy-MM-dd" nice="false"/>這樣就可以將日期格式化爲yyyy-MM-dd的形式

8:默認情況下,當請求action發生時,Struts運行時(Runtime)根據struts.xml裏的Action映射集(Mapping),實例化action對應的類,並調用其execute方法。當然,我們可以通過以下兩種方法改變這種默認調用

1)在classes/sturts.xml中新建Action,並指明其調用的方法
比如想調用action類中的

public String aliasAction() {
message ="自定義Action調用方法";
return SUCCESS;
}
則在classes/sturts.xml中加入下面代碼:
<action name="AliasHelloWorld"class="tutorial.HelloWorld" method="aliasAction">
<result>/HelloWorld.jsp</result>
</action>
既可用action名調用該方法了

2)(比較常用)

訪問Action時,在Action名後加上“!xxx”(xxx爲方法名)。

9:Struts 2.0有兩個配置文件,struts.xml和struts.properties都是放在WEB-INF/classes/下。
struts.xml用於應用程序相關的配置
struts.properties用於Struts 2.0的運行時(Runtime)的配置

10:在action類中取得web下某一文件夾物理路徑(絕對路徑)的方法
filePath = ServletActionContext.getServletContext().getRealPath("/upLoadFiles")

11:要想返回的頁面不是一個直接JSP頁面而是要先通過返回action中的方法讀取相應的數據再返回到jsp頁面,有兩種方法

1)在struts.xml中這麼設置

<result name="list"type="redirect-action">sysmanage/UserBaseInfoAction!findUserBaseInfo.action</result>

2)在action中返回時直接調用這個方法即可

return findList();

12:設置checkboxlist中默認值的方法

<s:checkboxlist name="skills1"
="Skills 1"
list="{ 'Java', '.Net', 'RoR', 'PHP' }"
value="{ 'Java', '.Net' }" />
<s:checkboxlist name="skills2"
label="Skills 2"
list="#{ 1:'Java', 2: '.Net', 3: 'RoR', 4: 'PHP' }"
listKey="key"
listValue="value"
value="{ 1, 2, 3 }"/>

13:二級級連下拉框

<s:set name="foobar"
value="#{'Java': {'Spring', 'Hibernate', 'Struts 2'}, '.Net': {'Linq', 'ASP.NET 2.0'}, 'Database': {'Oracle', 'SQL Server', 'DB2', 'MySQL'}}"/>
<s:doubleselect list="#foobar.keySet()"
doubleName="technology"
doubleList="#foobar[top]"
label="Technology" />

在Struts1.*中,要想訪問request、response以及session等Servlet對象是很方便的,因爲它們一直是作爲形參在各個方法之間進行傳遞的,而在Struts2中我們就很難看到它們的芳蹤了,因爲我們獲得表單中的值都是通過預先設置好了的get方法來得到的,那麼如果有些參數我們必須通過request.getParametre或者session.getAttribute來得到,那麼應該怎麼做呢?按照Max的教程上的說法,可以分爲兩種:IoC方式和非IoC方式,如何理解這兩種方式的區別呢?IoC是Spring裏面的特徵之一,字面意思是反轉控制,說白了就是依賴注入,比方說類A依賴類B,那麼就主動的給A注入一個類B的對象,下面看一下這兩種方法的具體實現。

1.非Ioc方式

這種方式主要是利用了com.opensymphony.xwork2.ActionContext類以及org.apache.struts2.ServletActionContext類,具體的方法如下所示。

獲得request對象:

A.HttpServletRequest request =ServletActionContext.getRequest ();

B.ActionContext ct= ActionContext.getContext()

   HttpServletRequest request=

(HttpServletRequest)ct.get(ServletActionContext.HTTP_REQUEST);

獲得session對象:

在Struts2中底層的session都被封裝成了Map類型,我們稱之爲SessionMap,而平常我們所說的session則是指HttpSession對象,具體的獲得方法如下所示。

A.Mapsession=ActionContext.getSession();

B.Mapsession=(Map)ActionContext.getContext().get(ActionContext.SESSION);

得到這個SessionMap之後我們就可以對session進行讀寫了,如果我們想得到原始的HttpSession可以首先得到HttpServletRequest對象,然後通過request.getSession()來取得原始的HttpSession對象。一般情況下SessionMap已經可以完成所有的工作,我們不必再去碰底層的session了。

2.IoC方式

這種方式相對來說變化就比較少了,具體流程如下所示。

獲得request對象:

第一步:讓action實現ServletRequestAware接口

第二步:在action中聲明一個HttpServletRequest類型的實例變量

第三步:在action中實現ServletRequestAware接口的setServletRequest方法,實現方式很簡單,如下所示。

        privateHttpServletRequest request;

publicvoid setServletRequest(HttpServletRequestrequest) {

            this.request= request;

    }

獲得Session對象(注意,此時的session是SessionMap類型):

第一步:讓action實現SessionAware接口

第二步:在action中聲明一個HttpServletRequest類型的實例變量

第三步:在action中實現SessionAware接口的setSession方法,實現方式很簡單,如下所示。

 

Spring 面試題

Spring框架有哪些模塊?

Spring框架由七個模塊組成組成,這7個模塊(或組件)均可以單獨存在,也可以與其它一個或多個模塊聯合使用,如下所示:

(1)Spring 核心容器——IoC容器

(2) Spring AOP

(3) SpringORM

(4) SpringDAO

(5) SpringWEB

(6) Spring上下文(Context)

(7) SpringMVC

爲什麼要使用Spring框架,它有什麼優點?

(1) 輕量級的框架

(2) 非侵入性的

(3) 可以整合其它的框架,比如Struts, Hibernate等

(4) 可以提供事務管理

Spring框架的工作機制是什麼?

(1) Spring MVC將所有的請求都提交給DispatcherServlet,它會委託應用系統的其它模塊負責對請求進行真正的處理工作。

(2) DispatcherServlet查詢一個或多個HandlerMapping,找到處理請求的Controller。

(3) DispatcherServlet請請求提交到目標Controller。

(4) Controller進行業務邏輯處理後,會返回一個ModelAndView。

(5) Dispathcher查詢一個或多個ViewResolver(視圖解析器),找到ModelAndView對象指定的視圖對象。

(6) 視圖對象負責將結果返回給客戶端。

怎麼使用Spring配置事務 ?

    Spring同時支持編程式事務策略和聲明式事務策略,大部分時候都採用聲明式事務策略。

聲明式事務管理的配置方式,通常有以下4種:

(1) 使用TransactionProxyFactoryBean爲目標Bean生成事務代理的配置。此方式是最傳統、配置文件最臃腫、最難以閱讀的方式。

(2) 採用Bean繼承的事務代理配置方式,比較簡潔,但依然是增量式配置。

(3) 採用BeanNameAutoProxyCreator,根據Bean Name自動生成事務代理的方式。這是直接利用Spring的AOP框架配置事務代理的方式,需要對Spring的AOP框架有所理解。但這種方式避免了增量式配置,效果非常不錯。

(4) 採用DefaultAdvisorAutoProxyCreator,直接利用Spring的AOP框架配置事務代理的方式,效果非常不錯,只是這種配置方式的可讀性不如第3種方式。

請你談談SSH整合

SSH整合:

(1) Struts(表示層)+ Spring(業務層)+ Hibernate(持久層)

(2) Struts:

Struts是一個表示層框架,主要作用是界面展示、接收請求和分發請求。

在MVC框架中,Struts屬於VC層次,負責界面表現,負責MVC關係的分發。

View:沿用 JSP,HTTP,Form,Tag,Resourse;

Controller:ActionServlet,struts-config.xml,Action。

(3) Hibernate:

Hibernate是一個持久層框架,它只負責與關係數據庫的操作。

(4) Spring:

Spring是一個業務層框架,是一個整合的框架,能夠很好地黏合表示層與持久層。

在Spring框架中如何配置數據庫驅動?

使用org.springframework.jdbc.datasource.DriverManagerDataSource數據源來配置數據庫驅動。

示例:
<bean id=”dataSource”> 
    <property name=”driverClassName”> <value>org.hsqldb.jdbcDriver</value></property>
    <property name=”url”><value>jdbc:hsqldb:db/appfuse</value></property>
    <property name=”username”><value>sa</value></property>
    <property name=”password”><value></value></property>
</bean>

在Spring框架中applicationContext.xml文件能不能改成其它文件名?

ContextLoaderListener是一個ServletContextListener,在啓動Tomcat應用服務器時,它會讀取WEB-INF目錄下的applicationContext.xml文件,初始化Spring配置。

如果你想改變applicationContext.xml文件的名字或改變它的存儲位置,可以通過在web.xml文件中定義一個<context-param>元素來解決這個問題。

示例:
<listener> 
   <listener-class>org.springframework.web.context.ContextLoaderListener 

<context-param>
         <param-name>contextConfigLocation</param-name>
         <param-value>/WEB-INF/xyz.xml</param-value>
     </context-param>

</listener-class>
</listener> 

如何在Web應用裏配置Spring?

在/WEB-INF/web.xml文件中,加入如下內容:

<servlet>

<servlet-name>context</servlet-name>

<servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class><load-on-startup>1</load-on-startup>

</servlet>

在啓動Web應用服務器(Tomcat)時,將加載/WEB-INF/applicationContext.xml文件中的內容。

在應用程序中,可以通過如下方式獲取ApplicationContext實例

WebApplicationContextUtils.getWebApplicationContext

Spring裏如何定義Hibernate Mapping?

添加hibernatemapping 文件到WEB-INF目錄下的applicationContext.xml文件中。

示例:
<property name=”mappingResources”>
    <list>
       <value>org/appfuse/model/User.hbm.xml</value>
    </list>
</property>

解釋一下Dependency Injection(DI,依賴注入)和IoC(Inversion of Control,控制反轉)?

依賴注入DI是一種設計模式,通常也稱作控制反轉,儘管在技術上來講,依賴注入是一個IoC的特殊實現,依賴注入是指一個對象應用另外一個對象來提供一種特殊的能力。例如,把一個數據庫連接以參數的形式傳到一個對象的構造函數裏面而不是在那個對象內部自行創建一個連接。

控制反轉和依賴注入的基本思想就是把類的依賴從類內部轉化到外部以減少依賴。

應用控制反轉,對象在被創建的時候,由一個調控系統內所有對象的外界實體,將其所依賴的對象的引用,傳遞給它。也可以說,依賴被注入到對象中。所以,控制反轉是,關於一個對象如何獲取它依賴的對象的引用,這個責任的反轉。

Spring中的BeanFactory與ApplicationContext的作用有哪些?

(1) BeanFactory負責讀取Bean配置文檔,管理Bean的加載和實例化,維護Bean之間的依賴關係,負責Bean的生命週期。

(2)ApplicationContext除了提供上述BeanFactory所能提供的功能之外,還提供了更完整的框架功能:

a. 國際化支持

b. 資源訪問:Resource rs = ctx. getResource(”classpath:config.properties”);

c. 事件傳遞:通過實現ApplicationContextAware接口

(3) 常用的獲取ApplicationContext的方法:

FileSystemXmlApplicationContext:從文件系統或者URL指定的xml配置文件創建,參數爲配置文件名或文件名數組

ClassPathXmlApplicationContext:從classpath的xml配置文件創建,可以從jar包中讀取配置文件。

WebApplicationContextUtils:從web應用的根目錄讀取配置文件,需要先在web.xml中配置,可以配置監聽器或者 servlet來實現
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener> 
<servlet> 
    <servlet-name>context</servlet-name>
    <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet> 
    這兩種方式都默認配置文件爲WEB-INF/applicationContext.xml,也可使用context-param指定配置文件

<context-param>

<param-name>contextConfigLocation</param-name>

<param-value>/WEB-INF/myApplicationContext.xml</param-value>

</context-param>

如何在Spring中實現國際化?

在applicationContext.xml文件中配置一個bean:
<bean id=”messageSource” class=”org.springframework.context.support.ResourceBundleMessageSource”>
    <property name=”basename”><value>message</value></property> 
</bean>
    在src目錄下建多個properties文件,其命名格式是message_語言_國家。
    在頁面中顯示信息時,通過applictionContext.getMessage(“鍵名”,”參數”,”區域”)取出相關的信息。

Spring中的核心類有那些,各有什麼作用?

BeanFactory:產生一個新的實例,可以實現單例模式。

BeanWrapper:提供統一的get及set方法。

ApplicationContext:提供Spring框架的實現,包括BeanFactory的所有功能。

什麼是AOP,AOP的作用是什麼?

面向切面編程(AOP)提供另外一種角度來思考程序結構,通過這種方式彌補了面向對象編程(OOP)的不足。

除了類(classes)以外,AOP提供了切面。切面對關注點進行模塊化,例如橫切多個類型和對象的事務管理。

Spring的一個關鍵的組件就是AOP框架,可以自由選擇是否使用AOP,提供聲明式企業服務,特別是爲了替代EJB聲明式服務。最重要的服務是聲明性事務管理,這個服務建立在Spring的抽象事物管理之上。

允許用戶實現自定義切面,用AOP來完善OOP的使用,可以把Spring AOP看作是對Spring的一種增強。

使用Spring有什麼好處?

(1) Spring能有效地組織你的中間層對象,無論你是否選擇使用了EJB。如果你僅僅使用了Struts或其它的包含了J2EE特有APIs的 framework,你會發現Spring關注了遺留問題。

(2) Spring能消除在許多工程上對Singleton的過多使用。

(3) Spring能消除使用各種格式的屬性定製文件的需要,在整個工程中,可通過一種一致的方法來進行配置。曾經感到迷惑,一個特定類要查找迷幻般的屬性關鍵字或系統屬性,爲此不得不讀Javadoc乃至源編碼嗎?有了Spring,你可很簡單地看到類的JavaBean屬性。

(4) Spring能通過接口而不是類促進好的編程習慣,減少編程代價到幾乎爲零。

(5) Spring被設計爲讓使用它創建的應用儘可能少的依賴於它的APIs。在Spring應用中的大多數業務對象沒有依賴於Spring。

(6) 使用Spring構建的應用程序易於單元測試。

(7) Spring能使EJB的使用成爲一個實現選擇,而不是應用架構的必然選擇。你能選擇用POJOs或local EJBs來實現業務接口,卻不會影響調用代碼。

(8) Spring幫助你解決許多問題而無需使用EJB。Spring能提供一種EJB的替換物,它們適於許多web應用。例如,Spring能使用AOP提供聲明性事務而不通過使用EJB容器,如果你僅僅需要與單個的數據庫打交道,甚至不需要JTA實現。

(9) Spring爲數據存取提供了一致的框架,不論是使用JDBC或O/Rmapping產品(如Hibernate)。

什麼是Spring,它有什麼特點?

Spring是一個輕量級的控制反轉(IoC)和麪向切面(AOP)的容器框架。

(1) 輕量——從大小與開銷兩方面而言Spring都是輕量的。完整的Spring框架可以在一個大小隻有1MB多的JAR文件裏發佈,並且Spring所需的處理開銷也是微不足道的。此外,Spring是非侵入式的:典型地,Spring應用中的對象不依賴於Spring的特定類。

(2) 控制反轉——Spring通過一種稱作控制反轉(IoC)的技術促進了鬆耦合。當應用了IoC,一個對象依賴的其它對象會通過被動的方式傳遞進來,而不是這個對象自己創建或者查找依賴對象。你可以認爲IoC與JNDI相反——不是對象從容器中查找依賴,而是容器在對象初始化時不等對象請求就主動將依賴傳遞給它。

(3) 面向切面——Spring提供了面向切面編程的豐富支持,允許通過分離應用的業務邏輯與系統級服務(例如審計(auditing)和事務管理)進行內聚性的開發。應用對象只實現它們應該做的——完成業務邏輯——僅此而已。它們並不負責其它的系統級關注點,例如日誌或事務支持。

(4) 容器——Spring包含並管理應用對象的配置和生命週期,在這個意義上它是一種容器,你可以配置你的每個bean如何被創建——基於一個可配置原型(prototype),你的bean可以創建一個單獨的實例或者每次需要時都生成一個新的實例——以及它們是如何相互關聯的。然而,Spring不應該被混同於傳統的重量級的EJB容器,它們經常是龐大與笨重的,難以使用。

(5) 框架——Spring可以將簡單的組件配置、組合成爲複雜的應用。在Spring中,應用對象被聲明式地組合,典型地是在一個XML文件裏。 Spring也提供了很多基礎功能(事務管理、持久化框架集成等等),將應用邏輯的開發留給了你。

AOP裏面幾個重要名詞概念的解釋

(1) 切面(Aspect)

一個關注點的模塊化,這個關注點可能會橫切多個對象。事務管理是J2EE應用中一個關於橫切關注點的很好的例子。 在Spring AOP中,切面可以使用通用類(基於模式的風格)或者在普通類中以 @Aspect 註解來實現。

(2) 連接點(Joinpoint)

在程序執行過程中某個特定的點,比如某方法調用的時候或者處理異常的時候。在Spring AOP中,一個連接點總是代表一個方法的執行。 通過聲明一個org.aspectj.lang.JoinPoint類型的參數可以使通知(Advice)的主體部分獲得連接點信息。

(3) 通知(Advice)

在切面的某個特定的連接點(Joinpoint)上執行的動作。通知有各種類型,其中包括“around”、“before”和“after”等通知。通知的類型將在後面部分進行討論。許多AOP框架,包括Spring,都是以攔截器做通知模型,並維護一個以連接點爲中心的攔截器鏈。

(4) 切入點(Pointcut)

匹配連接點(Joinpoint)的斷言。通知和一個切入點表達式關聯,並在滿足這個切入點的連接點上運行(例如,當執行某個特定名稱的方法時)。切入點表達式如何和連接點匹配是AOP的核心:Spring缺省使用AspectJ切入點語法。

(5) 引入(Introduction)

也被稱爲內部類型聲明(inter-typedeclaration))。聲明額外的方法或者某個類型的字段。 Spring允許引入新的接口(以及一個對應的實現)到任何被代理的對象。例如,你可以使用一個引入來使bean實現 IsModified 接口,以便簡化緩存機制。

(6) 目標對象(TargetObject)

被一個或者多個切面(aspect)所通知(advise)的對象。也有人把它叫做被通知(advised) 對象。 既然Spring AOP是通過運行時代理實現的,這個對象永遠是一個被代理(proxied)對象。

(7) AOP代理(AOP Proxy)

AOP框架創建的對象,用來實現切面契約(aspect contract)(包括通知方法執行等功能)。 在Spring中,AOP代理可以是JDK動態代理或者CGLIB代理。 注意:Spring 2.0最新引入的基於模式(schema-based)風格和@AspectJ註解風格的切面聲明,對於使用這些風格的用戶來說,代理的創建是透明的。

(8) 織入(Weaving)

把切面(aspect)連接到其它的應用程序類型或者對象上,並創建一個被通知(advised)的對象。 這些可以在編譯時(例如使用AspectJ編譯器),類加載時和運行時完成。 Spring和其它純Java AOP框架一樣,在運行時完成織入。

 spring工作機制及爲什麼要用?

1.spring mvc請所有的請求都提交給DispatcherServlet,它會委託應用系統的其他模塊負責負責對請求進行真正的處理工作。
2.DispatcherServlet查詢一個或多個HandlerMapping,找到處理請求的Controller.
3.DispatcherServlet請求提交到目標Controller
4.Controller進行業務邏輯處理後,會返回一個ModelAndView
5.Dispathcher查詢一個或多個ViewResolver視圖解析器,找到ModelAndView對象指定的視圖對象
6.視圖對象負責渲染返回給客戶端。

爲什麼用Spring:

{AOP 讓開發人員可以創建非行爲性的關注點,稱爲橫切關注點,並將它們插入到應用程序代碼中。使用 AOP 後,公共服務  (比 如日誌、持久性、事務等)就可以分解成方面並應用到域對象上,同時不會增加域對象的對象模型的複雜性。
IOC 允許創建一個可以構造對象的應用環境,然後向這些對象傳遞它們的協作對象。正如單詞 倒置 所表明的,IOC就像反 過來的 JNDI。沒有使用一堆抽象工廠、服務定位器、單元素(singleton)和直接構造(straight construction),每一個對象都是用其協作對象構造的。因此是由容器管理協作對象(collaborator)。
Spring即使一個AOP框架,也是一IOC容器。 Spring 最好的地方是它有助於您替換對象。有了 Spring,只要用 JavaBean 屬性和配置文件加入依賴性(協作對象)。然後可以很容易地在需要時替換具有類似接口的協作對象。}

 

 Hibernate 面試題

 

比較Hibernate的三種檢索策略優缺點

1立即檢索;
優點:對應用程序完全透明,不管對象處於持久化狀態,還是遊離狀態,應用程序都可以方便的從一個對象導航到與它關聯的對象;
缺點:1.select語句太多;2.可能會加載應用程序不需要訪問的對象白白浪費許多內存空間;
2延遲檢索:
優點:由應用程序決定需要加載哪些對象,可以避免可執行多餘的select語句,以及避免加載應用程序不需要訪問的對象。因此能提高檢索性能,並且能節省內存空間;
缺點:應用程序如果希望訪問遊離狀態代理類實例,必須保證他在持久化狀態時已經被初始化;
3 迫切左外連接檢索
優點:1對應用程序完全透明,不管對象處於持久化狀態,還是遊離狀態,應用程序都可以方便地衝一個對象導航到與它關聯的對象。2使用了外連接,select語句數目少;
缺點:1 可能會加載應用程序不需要訪問的對象,白白浪費許多內存空間;2複雜的數據庫表連接也會影響檢索性能;

如何在控制檯看到hibernate生成並執行的sql

在定義數據庫和數據庫屬性的文件applicationConfig.xml裏面,把hibernate.show_sql 設置爲true
這樣生成的SQL就會在控制檯出現了
注意:這樣做會加重系統的負擔,不利於性能調優

hibernate都支持哪些緩存策略

Read-only:  這種策略適用於那些頻繁讀取卻不會更新的數據,這是目前爲止最簡單和最有效的緩存策略
* Read/write:這種策略適用於需要被更新的數據,比read-only更耗費資源,在非JTA環境下,每個事務需要在session.close和session.disconnect()被調用
* Nonstrict read/write: 這種策略不保障兩個同時進行的事務會修改同一塊數據,這種策略適用於那些經常讀取但是極少更新的數據
* Transactional: 這種策略是完全事務化得緩存策略,可以用在JTA環境下

hibernate裏面的sorted collection 和ordered collection有什麼區別

sorted collection是在內存中通過java比較器進行排序的
ordered collection是在數據庫中通過order by進行排序的

Hibernate工作原理及爲什麼要用?

原理:
1.讀取並解析配置文件
2.讀取並解析映射信息,創建SessionFactory
3.打開Sesssion
4.創建事務Transation
5.持久化操作
6.提交事務
7.關閉Session
8.關閉SesstionFactory

爲什麼要用:
1.    對JDBC訪問數據庫的代碼做了封裝,大大簡化了數據訪問層繁瑣的重複性代碼。

2.   Hibernate是一個基於JDBC的主流持久化框架,是一個優秀的ORM實現。他很大程度的簡化DAO層的編碼工作

3.   hibernate使用Java反射機制,而不是字節碼增強程序來實現透明性。

4.   hibernate的性能非常好,因爲它是個輕量級框架。映射的靈活性很出色。它支持各種關係數據庫,從一對一到多對多的各種複雜關係。

Hibernate是如何延遲加載?

1.  Hibernate2延遲加載實現:a)實體對象 b)集合(Collection)

2. Hibernate3 提供了屬性的延遲加載功能

當Hibernate在查詢數據的時候,數據並沒有存在與內存中,當程序真正對數據的操作時,對象才存在與內存中,就實現了延遲加載,他節省了服務器的內存開銷,從而提高了服務器的性能。

Hibernate中怎樣實現類之間的關係?(如:一對多、多對多的關係)

類與類之間的關係主要體現在表與表之間的關係進行操作,它們都是對對象進行操作,我們程序中把所有的表與類都映射在一起,它們通過配置文件中的many-to-one、one-to-many、many-to-many、

說下Hibernate的緩存機制

1. 內部緩存存在Hibernate中又叫一級緩存,屬於應用事物級緩存

2. 二級緩存:
a) 應用及緩存
b) 分佈式緩存
條件:數據不會被第三方修改、數據大小在可接受範圍、數據更新頻率低、同一數據被系統頻繁使用、非關鍵數據
c) 第三方緩存的實現

Hibernate的查詢方式

Sql、Criteria,objectcomposition
Hql:
1、 屬性查詢
2、 參數查詢、命名參數查詢
3、 關聯查詢
4、 分頁查詢
5、 統計函數

如何優化Hibernate?

1.使用雙向一對多關聯,不使用單向一對多
2.靈活使用單向一對多關聯
3.不用一對一,用多對一取代
4.配置對象緩存,不使用集合緩存
5.一對多集合使用Bag,多對多集合使用Set
6. 繼承類使用顯式多態
7. 表字段要少,表關聯不要怕多,有二級緩存撐腰

Hibernate有哪幾種查詢數據的方式

3種:hql、條件查詢QBC(QueryBy Criteria)、原生sql (通過createSQLQuery建立)

談談Hibernate中inverse的作用

inverse屬性默認是false,就是說關係的兩端都來維護關係。
比如Student和Teacher是多對多關係,用一箇中間表TeacherStudent維護。Gp)i
如果Student這邊inverse=”true”, 那麼關係由另一端Teacher維護,就是說當插入Student時,不會操作TeacherStudent表(中間表)。只有Teacher插入或刪除時纔會觸發對中間表的操作。所以兩邊都inverse=”true”是不對的,會導致任何操作都不觸發對中間表的影響;當兩邊都inverse=”false” 或默認時,會導致在中間表中插入兩次關係。

說說Hibernate中的update()和saveOrUpdate()的區別,session的load()和get()的區別。

saveOrUpdate()方法可以實現update()的功能,但會多些步驟,具體如下:
如果對象在該session中已經被持久化,不進行操作;對象的標識符屬性(identifier property)在數據庫中不存在或者是個暫時的值,調用save()方法保存它;如果session中的另一個對象有相同的標識符拋出一個異常;以上皆不符合則調用update()更新之。
Session.load/get方法均可以根據指定的實體類和id從數據庫讀取記錄,並返回與之對應的實體對象。session的get()和load()其區別在於:
如果未能發現符合條件的記錄,get方法返回null,而load方法會拋出一個ObjectNotFoundException;load方法可返回實體的代理類實例,而get方法永遠直接返回實體類;load方法可以充分利用內部緩存和二級緩存中的現有數據,而get方法則僅僅在內部緩存中進行數據查找,如沒有發現對應數據,將越過二級緩存,直接調用SQL完成數據讀取。

hibernate中對象的三種狀態

瞬時態(Transient)、持久態(Persistent)、脫管態(Detached)。處於持久態的對象也稱爲PO(Persistence Object),瞬時對象和脫管對象也稱爲VO(Value Object)。

瞬時態

由new命令開闢內存空間的java對象,

eg. Person person =new Person(”amigo”, “女”);

如果沒有變量對該對象進行引用,它將被java虛擬機回收。

瞬時對象在內存孤立存在,它是攜帶信息的載體,不和數據庫的數據有任何關聯關係,在Hibernate中,可通過session的save()或 saveOrUpdate()方法將瞬時對象與數據庫相關聯,並將數據對應的插入數據庫中,此時該瞬時對象轉變成持久化對象。

持久態

處於該狀態的對象在數據庫中具有對應的記錄,並擁有一個持久化標識。如果是用hibernate的delete()方法,對應的持久對象就變成瞬時對象,因數據庫中的對應數據已被刪除,該對象不再與數據庫的記錄關聯。

當一個session執行close()或clear()、evict()之後,持久對象變成脫管對象,此時持久對象會變成脫管對象,此時該對象雖然具有數據庫識別值,但它已不在HIbernate持久層的管理之下。

持久對象具有如下特點:

1. 和session實例關聯;n

2. 在數據庫中有與之關聯的記錄。

脫管態

當與某持久對象關聯的session被關閉後,該持久對象轉變爲脫管對象。當脫管對象被重新關聯到session上時,並再次轉變成持久對象。

脫管對象擁有數據庫的識別值,可通過update()、saveOrUpdate()等方法,轉變成持久對象。

脫管對象具有如下特點:

1. 本質上與瞬時對象相同,在沒有任何變量引用它時,JVM會在適當的時候將它回收;

2.   比瞬時對象多了一個數據庫記錄標識值。4RESA3ES  B

Detached Object(遊離對象)有什麼好處

Detached Object(遊離對象)可以傳遞到任何層直到表現層而不是用任何DTO(DataTransfer Objects). 然後你還可以重新把遊離對象賦給另外一個Session.

JDBC hibernate 和 ibatis 的區別

jdbc:手動
  手動寫sql
  delete、insert、update要將對象的值一個一個取出傳到sql中,不能直接傳入一個對象。
  select:返回的是一個resultset,要從ResultSet中一行一行、一個字段一個字段的取出,然後封裝到一個對象中,不直接返回一個對象。
 ibatis的特點:半自動化
  sql要手動寫
  delete、insert、update:直接傳入一個對象
  select:直接返回一個對象   
 hibernate:全自動
  不寫sql,自動封裝
  delete、insert、update:直接傳入一個對象
  select:直接返回一個對象

hibernate如何實現數據表映射的繼承關係

1、兩個表,子類重複父類的屬性。
 2、一個表,子類父類共用一個表
    <class name=”Users” table=”users”discriminator-value=”Users”>
   <discriminator column=”DISCRIMINATOR_USERTYPE” type=”string”/>
<subclass name=”admin”discriminator-value=”admin”>
           <property name=”adminRemark” column=”admin_remark” type=”string” />
        </subclass>
    </class>
 3、兩個表,子類引用父類的主鍵,享用公共的字段或屬性。
    <class name=”Users” table=”users”>
        <id name=”userid” column=”USERID” type=”string”>
           <generator class=”assigned”/>
        </id>
        <property name=”pwd” column=”pwd” type=”string” />
   <joined-subclass name=”Guest” table=”guest”>
    <key column=”USERID”/>
         <property name=”guestRemark” column=”guest_remark” type=”string” />
        </joined-subclass>
</class>
批量刪除
 Query query=session.createQuery(”update”或”delete”);
 query.executeUpdate();

hibernate中Query對象的使用

1 個或多個屬性查詢:
 Query query=session.createQuery(”selectcustomername,customerid from Customer”)
 List l=query.list();
 For(int i=0;i<l.size();i++)
{
 Obejct[] object=(Object[])l.get(i);
 Object[0]  object[1]
}
}
分組: “selectcount(*),productname from Product group by productname order by productname”
取值與屬性一樣
配置的查詢,在*.hbm.xml中
 <query name=”sql”>
    <![CDATA[
     from Product where productid=:productid
    ]]>
</query>
 Query query=session.getNamedQuery(sql);
聯接1
 ”from Customer as customer join fetchcustomer.buySet”:將多的放到buySet屬性中,得出的結是Customer有一個,Buy有多個
聯接2
“from Customer as customer join customer.buySet”:得出的對象,customer與buy是1對1
子查詢:
 ”from Customer as customer where (select count(*)from customer.buySet)>1″

hibernate中Criteria和DetachedCriteria的作用是什麼?

Criteriac=session.createCriteria(Customer.class);
 //設置條件
 c.add(Expression.ge(“字段名”,”值對象”))
  ge:>=
  gt:>
  le:<=
  lt:<
  eq:=
 //排序
  c.addOrder(Order.asc(“字段名”))
 //分頁
  c.setFirstResult(1)//從第2行開始提取
  c.setMaxResults(5)//返回5行

 DetachedCriteria產生時不需要session
 DetachedCriteria dc= DetachedCriteria.forClass(Customer.class)
 Criteriac=Dc.getExecutableCriteria(session)

hibernate中數據表映射關係主要有什麼類型?

one-to-many
 inverse:主控方,外鍵的關係有誰控制
  inverse=false 是主控方,外鍵是由它控制的   
  inverse=true 是被控方,外鍵與它沒關係
  要想實現主控方的控制必須將被控方作爲主控方的屬性
 cascade:級聯
  主表增從表增
  主表修從表修
  主表刪從表刪
 lazy:延遲
  lazy=false:一下將所有的內容取出,不延時(常用)
  lazy=true:取出部分內容,其餘內容動態去取
  通過get可以取出對方的所有內容

hibernate的核心是什麼,他們的相互關係是什麼,重要的方法是什麼

Configuration
SessionFactory
  Session如下方法
   Save
   load
   Update
   Delete
      Query q=CreateQuery(“fromCustomer where customerName=:customerName”)
   beginTransaction
   close
   Transaction
   Commit()

MyEclipse加入hibernate的全過程是什麼

1.Db-browers加入配置連接
2.新建工程
3.加入hibernate環境,指定*.hbm.xml及HibernateSessionFactory文件所在的位置

面試中常出現的兩個hibernate面試題及答案

1.在數據庫中條件查詢速度很慢的時候,如何優化?
1.建索引
2.減少表之間的關聯
3.優化sql,儘量讓sql很快定位數據,不要讓sql做全表查詢,應該走索引,把數據量大的表排在前面
4.簡化查詢字段,沒用的字段不要,已經對返回結果的控制,儘量返回少量數據

2.在hibernate中進行多表查詢,每個表中各取幾個字段,也就是說查詢出來的結果集並沒有一個實體類與之對應,如何解決這個問題?
解決方案一,按照Object[]數據取出數據,然後自己組bean
解決方案二,對每個表的bean寫構造函數,比如表一要查出field1,field2兩個字段,那麼有一個構造函數就是Bean(type1 filed1,type2 field2) ,然後在hql裏面就可以直接生成這個bean了。具體怎麼用請看相關文檔,我說的不是很清楚。
session.load()和session.get()的區別
Session.load/get方法均可以根據指定的實體類和id從數據庫讀取記錄,並返回與之對應的實體對象。其區別在於:

如果未能發現符合條件的記錄,get方法返回null,而load方法會拋出一個ObjectNotFoundException。
Load方法可返回實體的代理類實例,而get方法永遠直接返回實體類。
load方法可以充分利用內部緩存和二級緩存中的現有數據,而get方法則僅僅在內部緩存中進行數據查找,如沒有發現對應數據,將越過二級緩存,直接調用SQL完成數據讀取。
Session在加載實體對象時,將經過的過程:

首先,Hibernate中維持了兩級緩存。第一級緩存由Session實例維護,其中保持了Session當前所有關聯實體的數據,也稱爲內部緩存。而第二級緩存則存在於SessionFactory層次,由當前所有由本 SessionFactory構造的Session實例共享。出於性能考慮,避免無謂的數據庫訪問,Session在調用數據庫查詢功能之前,會先在緩存中進行查詢。首先在第一級緩存中,通過實體類型和id進行查找,如果第一級緩存查找命中,且數據狀態合法,則直接返回。
之後,Session會在當前“NonExists”記錄中進行查找,如果“NonExists”記錄中存在同樣的查詢條件,則返回null。 “NonExists”記錄了當前Session實例在之前所有查詢操作中,未能查詢到有效數據的查詢條件(相當於一個查詢黑名單列表)。如此一來,如果 Session中一個無效的查詢條件重複出現,即可迅速作出判斷,從而獲得最佳的性能表現。
對於load方法而言,如果內部緩存中未發現有效數據,則查詢第二級緩存,如果第二級緩存命中,則返回。
如在緩存中未發現有效數據,則發起數據庫查詢操作(Select SQL),如經過查詢未發現對應記錄,則將此次查詢的信息在“NonExists”中加以記錄,並返回null。
根據映射配置和Select SQL得到的ResultSet,創建對應的數據對象。
將其數據對象納入當前Session實體管理容器(一級緩存)。
執行Interceptor.onLoad方法(如果有對應的Interceptor)。
將數據對象納入二級緩存。
如果數據對象實現了LifeCycle接口,則調用數據對象的onLoad方法。
返回數據對象。

Hibernate的主鍵生成機制

1) assigned
主鍵由外部程序負責生成,無需Hibernate參與。
2) hilo
通過hi/lo 算法實現的主鍵生成機制,需要額外的數據庫表保存主鍵生成歷史狀態。
3) seqhilo
與hilo 類似,通過hi/lo 算法實現的主鍵生成機制,只是主鍵歷史狀態保存在Sequence中,適用於支持Sequence的數據庫,如Oracle。
4) increment
主鍵按數值順序遞增。此方式的實現機制爲在當前應用實例中維持一個變量,以保存着當前的最大值,之後每次需要生成主鍵的時候將此值加1作爲主鍵。這種方式可能產生的問題是:如果當前有多個實例訪問同一個數據庫,那麼由於各個實例各自維護主鍵狀態,不同實例可能生成同樣的主鍵,從而造成主鍵重複異常。因此,如果同一數據庫有多個實例訪問,此方式必須避免使用。
5) identity
採用數據庫提供的主鍵生成機制。如DB2、SQL Server、MySQL中的主鍵生成機制。
6) sequence
採用數據庫提供的sequence 機制生成主鍵。如Oralce中的Sequence。
7) native
由Hibernate根據底層數據庫自行判斷採用identity、hilo、sequence其中一種作爲主鍵生成方式。
8) uuid.hex
由Hibernate基於128 位唯一值產生算法生成16 進制數值(編碼後以長度32 的字符串表示)作爲主鍵。
9) uuid.string
與uuid.hex 類似,只是生成的主鍵未進行編碼(長度16)。在某些數據庫中可能出現問題(如PostgreSQL)。
10) foreign
使用外部表的字段作爲主鍵。一般而言,利用uuid.hex方式生成主鍵將提供最好的性能和數據庫平臺適應性。
這10中生成OID標識符的方法,increment 比較常用,把標識符生成的權力交給Hibernate處理.但是當同時多個Hibernate應用操作同一個數據庫,甚至同一張表的時候.就推薦使用identity依賴底層數據庫實現,但是數據庫必須支持自動增長,當然針對不同的數據庫選擇不同的方法.如果你不能確定你使用的數據庫具體支持什麼的情況下.可以選擇用native 讓Hibernate來幫選擇identity,sequence,或hilo.
另外由於常用的數據庫,如Oracle、DB2、SQLServer、MySql 等,都提供了易用的主鍵生成機制(Auto-Increase 字段或者Sequence)。我們可以在數據庫提供的主鍵生成機制上,採用generator-class=native的主鍵生成方式。
不過值得注意的是,一些數據庫提供的主鍵生成機制在效率上未必最佳,大量併發insert數據時可能會引起表之間的互鎖。數據庫提供的主鍵生成機制,往往是通過在一個內部表中保存當前主鍵狀態(如對於自增型主鍵而言,此內部表中就維護着當前的最大值和遞增量),之後每次插入數據會讀取這個最大值,然後加上遞增量作爲新記錄的主鍵,之後再把這個新的最大值更新回內部表中,這樣,一次Insert操作可能導致數據庫內部多次表讀寫操作,同時伴隨的還有數據的加鎖解鎖操作,這對性能產生了較大影響。因此,對於併發Insert要求較高的系統,推薦採用uuid.hex 作爲主鍵生成機制

hibernate面試題:怎麼得到一個Collection的大小而不用初始化它

Integer size = (Integer) s.createFilter( collection, "select count(*)" ).uniqueResult();

hibernate面試題:怎麼得到查詢結果的記錄數而不用返回查詢結果

Integer count = (Integer) session.createQuery("select count(*) from ....").uniqueResult();

什麼是SessionFactory,她是線程安全麼?

SessionFactory isHibernates concept of a single datastore and is threadsafe so that many threadscan access it concurrently and request for sessions and immutable cache ofcompiled mappings for a single database. A SessionFactory is usually only builtonce at startup. SessionFactory should be wrapped in some kind of singleton sothat it can be easily accessed in an application code.

SessionFactorysessionFactory = new Configuration().configure().buildSessionfactory();

SessionFactory 是Hibrenate單例數據存儲和線程安全的,以至於可以多線程同時訪問。一個SessionFactory 在啓動的時候只能建立一次。SessionFactory應該包裝各種單例以至於它能很簡單的在一個應用代碼中儲存.

如何配置Hibernate?

The configurationfiles hibernate.cfg.xml (or hibernate.properties) and mapping files *.hbm.xmlare used by the Configuration class to create (i.e. configure and bootstraphibernate) the SessionFactory, which in turn creates the Session instances.Session instances are the primary interface for the persistence service.

”hibernate.cfg.xml (alternatively can use hibernate.properties): These two filesare used to configure the hibernate sevice (connection driver class, connectionURL, connection username, connection password, dialect etc). If both files arepresent in the classpath then hibernate.cfg.xml file overrides the settingsfound in the hibernate.properties file.

” Mapping files(*.hbm.xml): These files are used to map persistent objects to a relationaldatabase. It is the best practice to store each object in an individual mappingfile (i.e mapping file per class) because storing large number of persistentclasses into one mapping file can be difficult to manage and maintain. Thenaming convention is to use the same name as the persistent (POJO) class name.For example Account.class will have a mapping file named Account.hbm.xml.Alternatively hibernate annotations can be used as part of your persistentclass code instead of the *.hbm.xml files.

優化hibernate性能的幾點建議

1、針對oracle數據庫而言,Fetch Size 是設定JDBC的Statement讀取數據的時候每次從數據庫中取出的記錄條數,一般設置爲30、50、100。Oracle數據庫的JDBC驅動默認的FetchSize=15,設置Fetch Size設置爲:30、50,性能會有明顯提升,如果繼續增大,超出100,性能提升不明顯,反而會消耗內存。

即在hibernate配製文件中進行配製:

1 <property name=”hibernateProperties”>
2 <props>
3 <prop key=”hibernate.dialect”>org.hibernate.dialect.Oracle9Dialect</prop>
4 <prop key=”hibernate.show_sql”>false</prop>
5 <!– Create/update thedatabase tables automatically when the JVM starts up
6 <prop key=”hibernate.hbm2ddl.auto”>update</prop> –>
7 <!– Turn batching off forbetter error messages under PostgreSQL
8 <prop key=”hibernate.jdbc.batch_size”>100</prop> –>
9 <prop key=”hibernate.jdbc.batch_size”>50</prop>
10 </props>
11 </property>Fetch Size設的越大,讀數據庫的次數越少,速度越快;Fetch Size越小,讀數據庫的次數越多,速度越慢。
2、如果是超大的系統,建議生成htm文件。加快頁面提升速度。

3、不要把所有的責任推在hibernate上,對代碼進行重構,減少對數據庫的操作,儘量避免在數據庫查詢時使用in操作,以及避免遞歸查詢操作,代碼質量、系統設計的合理性決定系統性能的高低。

4、 對大數據量查詢時,慎用list()或者iterator()返回查詢結果,

(1). 使用List()返回結果時,Hibernate會所有查詢結果初始化爲持久化對象,結果集較大時,會佔用很多的處理時間。

(2). 而使用iterator()返回結果時,在每次調用iterator.next()返回對象並使用對象時,Hibernate才調用查詢將對應的對象初始化,對於大數據量時,每調用一次查詢都會花費較多的時間。當結果集較大,但是含有較大量相同的數據,或者結果集不是全部都會使用時,使用iterator()纔有優勢。

5、在一對多、多對一的關係中,使用延遲加載機制,會使不少的對象在使用時方會初始化,這樣可使得節省內存空間以及減少數據庫的負荷,而且若PO中的集合沒有被使用時,就可減少互數據庫的交互從而減少處理時間。

6、對含有關聯的PO(持久化對象)時,若default-cascade=”all”或者 “save-update”,新增PO時,請注意對PO中的集合的賦值操作,因爲有可能使得多執行一次update操作。

7、 對於大數據量新增、修改、刪除操作或者是對大數據量的查詢,與數據庫的交互次數是決定處理時間的最重要因素,減少交互的次數是提升效率的最好途徑,所以在開發過程中,請將show_sql設置爲true,深入瞭解Hibernate的處理過程,嘗試不同的方式,可以使得效率提升。儘可能對每個頁面的顯示,對數據庫的操作減少到100—-150條以內。越少越好。

如何進行hibernate性能調優

大體上,對於HIBERNATE性能調優的主要考慮點如下:
Ø 數據庫設計調整
Ø HQL優化
Ø API的正確使用(如根據不同的業務類型選用不同的集合及查詢API)
Ø 主配置參數(日誌,查詢緩存,fetch_size,batch_size等)
Ø 映射文件優化(ID生成策略,二級緩存,延遲加載,關聯優化)
Ø 一級緩存的管理
Ø 針對二級緩存,還有許多特有的策略
Ø 事務控制策略。
1、 數據庫設計
a) 降低關聯的複雜性
b) 儘量不使用聯合主鍵
c) ID的生成機制,不同的數據庫所提供的機制並不完全一樣
d) 適當的冗餘數據,不過分追求高範式
2、 HQL優化
HQL如果拋開它同HIBERNATE本身一些緩存機制的關聯,HQL的優化技巧同普通的SQL優化技巧一樣,可以很容易在網上找到一些經驗之談。
3、 主配置
a) 查詢緩存,同下面講的緩存不太一樣,它是針對HQL語句的緩存,即完全一樣的語句再次執行時可以利用緩存數據。但是,查詢緩存在一個交易系統(數據變更頻繁,查詢條件相同的機率並不大)中可能會起反作用:它會白白耗費大量的系統資源但卻難以派上用場。
b) fetch_size,同JDBC的相關參數作用類似,參數並不是越大越好,而應根據業務特徵去設置
c) batch_size同上。
d) 生產系統中,切記要關掉SQL語句打印。
4、 緩存
a) 數據庫級緩存:這級緩存是最高效和安全的,但不同的數據庫可管理的層次並不一樣,比如,在ORACLE中,可以在建表時指定將整個表置於緩存當中。
b) SESSION緩存:在一個HIBERNATESESSION有效,這級緩存的可干預性不強,大多於HIBERNATE自動管理,但它提供清除緩存的方法,這在大批量增加/更新操作是有效的。比如,同時增加十萬條記錄,按常規方式進行,很可能會發現OutofMemeroy的異常,這時可能需要手動清除這一級緩存:Session.evict以及Session.clear
c) 應用緩存:在一個SESSIONFACTORY中有效,因此也是優化的重中之重,因此,各類策略也考慮的較多,在將數據放入這一級緩存之前,需要考慮一些前提條件:
i. 數據不會被第三方修改(比如,是否有另一個應用也在修改這些數據?)
ii. 數據不會太大
iii. 數據不會頻繁更新(否則使用CACHE可能適得其反)
iv. 數據會被頻繁查詢
v. 數據不是關鍵數據(如涉及錢,安全等方面的問題)。
緩存有幾種形式,可以在映射文件中配置:read-only(只讀,適用於很少變更的靜態數據/歷史數據),nonstrict-read-write,read-write(比較普遍的形式,效率一般),transactional(JTA中,且支持的緩存產品較少)
d) 分佈式緩存:同c)的配置一樣,只是緩存產品的選用不同,在目前的HIBERNATE中可供選擇的不多,oscache, jboss cache,目前的大多數項目,對它們的用於集羣的使用(特別是關鍵交易系統)都持保守態度。在集羣環境中,只利用數據庫級的緩存是最安全的。
5、 延遲加載
a) 實體延遲加載:通過使用動態代理實現
b) 集合延遲加載:通過實現自有的SET/LIST,HIBERNATE提供了這方面的支持
c) 屬性延遲加載:
6、 方法選用
a) 完成同樣一件事,HIBERNATE提供了可供選擇的一些方式,但具體使用什麼方式,可能用性能/代碼都會有影響。顯示,一次返回十萬條記錄(List/Set/Bag/Map等)進行處理,很可能導致內存不夠的問題,而如果用基於遊標(ScrollableResults)或Iterator的結果集,則不存在這樣的問題。
b) Session的load/get方法,前者會使用二級緩存,而後者則不使用。
c) Query和list/iterator,如果去仔細研究一下它們,你可能會發現很多有意思的情況,二者主要區別(如果使用了Spring,在HibernateTemplate中對應find,iterator方法):
i. list只能利用查詢緩存(但在交易系統中查詢緩存作用不大),無法利用二級緩存中的單個實體,但list查出的對象會寫入二級緩存,但它一般只生成較少的執行SQL語句,很多情況就是一條(無關聯)。
ii. iterator則可以利用二級緩存,對於一條查詢語句,它會先從數據庫中找出所有符合條件的記錄的ID,再通過ID去緩存找,對於緩存中沒有的記錄,再構造語句從數據庫中查出,因此很容易知道,如果緩存中沒有任何符合條件的記錄,使用iterator會產生N+1條SQL語句(N爲符合條件的記錄數)
iii. 通過iterator,配合緩存管理API,在海量數據查詢中可以很好的解決內存問題,如:
while(it.hasNext()){
YouObject object = (YouObject)it.next();
session.evict(youObject);
sessionFactory.evice(YouObject.class, youObject.getId());
}
如果用list方法,很可能就出OutofMemory錯誤了。
iv. 通過上面的說明,我想你應該知道如何去使用這兩個方法了。
7、 集合的選用
在HIBERNATE 3.1文檔的“19.5.Understanding Collection performance”中有詳細的說明。
8、 事務控制
事務方面對性能有影響的主要包括:事務方式的選用,事務隔離級別以及鎖的選用
a) 事務方式選用:如果不涉及多個事務管理器事務的話,不需要使用JTA,只有JDBC的事務控制就可以。
b) 事務隔離級別:參見標準的SQL事務隔離級別
c) 鎖的選用:悲觀鎖(一般由具體的事務管理器實現),對於長事務效率低,但安全。樂觀鎖(一般在應用級別實現),如在HIBERNATE中可以定義VERSION字段,顯然,如果有多個應用操作數據,且這些應用不是用同一種樂觀鎖機制,則樂觀鎖會失效。因此,針對不同的數據應有不同的策略,同前面許多情況一樣,很多時候我們是在效率與安全/準確性上找一個平衡點,無論如何,優化都不是一個純技術的問題,你應該對你的應用和業務特徵有足夠的瞭解。
9、 批量操作
即使是使用JDBC,在進行大批數據更新時,BATCH與不使用BATCH有效率上也有很大的差別。我們可以通過設置batch_size來讓其支持批量操作。
舉個例子,要批量刪除某表中的對象,如“delete Account”,打出來的語句,會發現HIBERNATE找出了所有ACCOUNT的ID,再進行刪除,這主要是爲了維護二級緩存,這樣效率肯定高不了,在後續的版本中增加了bulkdelete/update,但這也無法解決緩存的維護問題。也就是說,由於有了二級緩存的維護問題,HIBERNATE的批量操作效率並不盡如人意!
從前面許多要點可以看出,很多時候我們是在效率與安全/準確性上找一個平衡點,無論如何,優化都不是一個純技術的問題,你應該對你的應用和業務特徵有足夠的瞭解,一般的,優化方案應在架構設計期就基本確定,否則可能導致沒必要的返工,致使項目延期,而作爲架構師和項目經理,還要面對開發人員可能的抱怨,必竟,我們對用戶需求更改的控制力不大,但技術/架構風險是應該在初期意識到並制定好相關的對策。
還有一點要注意,應用層的緩存只是錦上添花,永遠不要把它當救命稻草,應用的根基(數據庫設計,算法,高效的操作語句,恰當API的選擇等)纔是最重要的。

JDBC ,hibernate分頁顯示怎麼實現?

答:方法分別爲:
1) Hibernate 的分頁:
Query query = session.createQuery(”from Student”);
query.setFirstResult(firstResult);//設置每頁開始的記錄號
query.setMaxResults(resultNumber);//設置每頁顯示的記錄數
Collection students = query.list();
2) JDBC 的分頁:根據不同的數據庫採用不同的sql 分頁語句
例如: Oracle 中的sql 語句爲: “SELECT * FROM (SELECT a.*, rownum r FROM
TB_STUDENT) WHERE r between 2 and 10″ 查詢從記錄號2 到記錄號10 之間的
所有記錄。

Hibernate的應用(hibernate的結構)

答://首先獲得SessionFactory 的對象
SessionFactory sessionFactory = new Configuration().configure().
buildSessionFactory();
//然後獲得session 的對象
Session session = sessionFactory.openSession();
//其次獲得Transaction 的對象
Transaction tx = session.beginTransaction();
//執行相關的數據庫操作:增,刪,改,查
session.save(user); //增加, user 是User 類的對象
session.delete(user); //刪除
session.update(user); //更新
Query query = session.createQuery(“from User”); //查詢
List list = query.list();
//提交事務
tx.commit();
//如果有異常,我們還要作事務的回滾,恢復到操作之前
tx.rollback();
//最後還要關閉session,釋放資源
session.close();

關於hibernate的幾個面試題

1)在hibernate 中,在配置文件呈標題一對多,多對多的標籤是什麼;
2)Hibernate 的二級緩存是什麼;
3)Hibernate 是如何處理事務的;
答:1)一對多的標籤爲<one-to-many> ;多對多的標籤爲<many-to-many>;
2)sessionFactory 的緩存爲hibernate 的二級緩存;
3)Hibernate 的事務實際上是底層的JDBCTransaction 的封裝或者是JTA
Transaction 的封裝;默認情況下使用JDBCTransaction

Hibernate的五個核心接口

Configuration 接口:配置Hibernate,根據其啓動hibernate,創建
SessionFactory 對象;
SessionFactory 接口:初始化Hibernate,充當數據存儲源的代理,創建
session 對象,sessionFactory 是線程安全的,意味着它的同一個實例可以被應
用的多個線程共享,是重量級、二級緩存;
Session 接口:負責保存、更新、刪除、加載和查詢對象,是線程不安全的,
避免多個線程共享同一個session,是輕量級、一級緩存;
Transaction 接口:管理事務;
Query 和Criteria 接口:執行數據庫的查詢。

如何優化hibernate

1. 使用雙向一對多關聯,不使用單向一對多
2. 靈活使用單向一對多關聯
3. 不用一對一,用多對一取代
4. 配置對象緩存,不使用集合緩存
5. 一對多集合使用Bag,多對多集合使用Set
6. 繼承類使用顯式多態
7. 表字段要少,表關聯不要怕多,有二級緩存撐腰

說下hibernate的緩存機制

1. 內部緩存存在Hibernate中又叫一級緩存,屬於應用事物級緩存
2. 二級緩存:
a) 應用及緩存
b) 分佈式緩存
條件:數據不會被第三方修改、數據大小在可接受範圍、數據更新頻率低、同一數據被系統頻繁使用、非關鍵數據
c) 第三方緩存的實現

hibernate怎麼實現類之間的關係

類與類之間的關係主要體現在表與表之間的關係進行操作,它們都是對對象進行操作,我們程序中把所有的表與類都映射在一起,它們通過配置文件中的many-to-one、one-to-many、many-to-many、

hibernate如何實現延遲加載

1. Hibernate2延遲加載實現:a)實體對象 b)集合(Collection)
2. Hibernate3 提供了屬性的延遲加載功能
當Hibernate在查詢數據的時候,數據並沒有存在與內存中,當程序真正對數據的操作時,對象才存在與內存中,就實現了延遲加載,他節省了服務器的內存開銷,從而提高了服務器的性能。

Hibernate數據查詢的幾種方式

1.使用主鍵id加載對象(load(),get());

2.通過對象導航,比如通過stu.getTeam()得到team的實例;

3 使用hql;

4使用qbc(query by criteria)

5直接使用sql語句取得記錄集;

一般都使用後面三種方式.

注意.hql是面向對象的查詢.語法和sql是基本一樣的.不區分大小寫的,但是注意的是對與對象.必須遵循對象的大小寫.因爲hql是對像查詢..同時我們必須清楚.hql只能取得對象,而不支持uid(update,insert.delete)

Hibernate中:不看數據庫,不看XML文件,不看查詢語句,怎麼能知道表的結構

看錶結構對應的類文件,比如UserInfo表對應的UserInfo.java文件



S2SH部分

請你談談SSH整合

SSH:
Struts(表示層)+Spring(業務層)+Hibernate(持久層)
Struts:
Struts是一個表示層框架,主要作用是界面展示,接收請求,分發請求。
在MVC框架中,Struts屬於VC層次,負責界面表現,負責MVC關係的分發。(View:沿用JSP,HTTP,Form,Tag,Resourse ;Controller:ActionServlet,struts-config.xml,Action)
Hibernate:
Hibernate是一個持久層框架,它只負責與關係數據庫的操作。
Spring:
Spring是一個業務層框架,是一個整合的框架,能夠很好地黏合表示層與持久層。



綜合面試題

1、 簡述你對IoC(Inversion of Control)的理解,描述一下Spring中實現DI(Dependency Injection)的幾種方式。

spring的IOC有三種注入方式  第一是根據屬性注入  也叫set方法注入;第二種是根據構造方法進行注入;第三種是根據註解進行注入,這種方式我認爲比較好,方便,要是bean多的話,使用前兩種方式會使得配置文件過於臃腫。

2、 Spring的Bean有多種作用域,包括:
singleton、prototype、request、session、globalsession、application、自定義

3、 簡單描述Spring Framework與Struts的不同之處,整合Spring與Struts有哪些方法,哪種最好,爲什麼?

答、 Spring是完整的一站式框架,而Struts僅是MVC框架,且着重於MVC中的C。Spring有三種方式整合Struts:使用 Spring 的 ActionSupport 類整合 Struts;使用 Spring 的DelegatingRequestProcessor 覆蓋 Struts 的 RequestProcessor;將 Struts Action 管理委託給 Spring 框架,動作委託最好。(詳見使用Spring 更好地處理Struts 動作)

Spring 2.0新增一種方式:AutowiringRequestProcessor。(詳見http://www.javaeye.com/topic/24239)

4、 Hibernate中的update()和saveOrUpdate()的區別

答、saveOrUpdate()方法可以實現update()的功能,但會多些步驟,具體如下:

如果對象在該session中已經被持久化,不進行操作;

對象的標識符屬性(identifierproperty)在數據庫中不存在或者是個暫時的值,調用save()方法保存它;

如果session中的另一個對象有相同的標識符拋出一個異常;

以上皆不符合則調用update()更新之。

5、 Spring對多種ORM框架提供了很好的支持,簡單描述在Spring中使用Hibernate的方法,並結合事務管理。

答、 在context中定義DataSource,創建SessionFactoy,設置參數;DAO類繼承HibernateDaoSupport,實現具體接口,從中獲得HibernateTemplate進行具體操作。

在使用中如果遇到OpenSessionInView的問題,可以添加OpenSessionInViewFilter或OpenSessionInViewInterceptor。(詳見Spring framework 2.0 Reference的12.2節Hibernate)

聲明式事務需聲明事務管理器,在context中設置指定屬性,用確定和。


原文鏈接:http://www.cnblogs.com/shiguangshuo/p/4101289.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章