Java面試題集(五)

3、開源框架

 

什麼是mybaties?

 

Mybaties是支持普通sql查詢,存儲過程和高級映射的優秀持久層框架。Mybaties消除了幾乎全部的jdbc代碼和參數的手工設置以及結果集的檢索。Mybaties使用簡單的xml或註解用於配置和原始映射,將接口和Java的pojos(Plan Old Java Objects 普通的Java對象)映射成數據庫中的記錄。html

Mybaties的動態sql語句是基於ognl表達式的,能夠方便的在sql語句中實現某些邏輯,整體來講mybaties動態sql語句主要有如下幾類:

1:if語句(簡單的條件判斷)java

2:choose(when otherwise),至關於Java語言中的switch與jstl中的choose很相似。git

3:trim(where,set,對包含的內容加上prexif或者suffix等,前綴後綴)程序員

4:where(主要是用來簡化sql語句中where條件判斷,能只能的處理and ,or,沒必要擔憂多餘致使語法報錯)web

5:set(主要用於更新操做)ajax

6:foreach 主要用在構建in條件中,它能夠在sql語句中進行迭代一個集合。Foreach元素的屬性主要有item,index,collector,open,separator,close.spring

Item表示集合中每個元素進行迭代時的別名;sql

Index指定一個名字,用於表示在迭代過程當中,每次迭代到的位置;數據庫

Open表示該語句以什麼開始;express

Separator表示在每次進行迭代之間以什麼符號做爲分隔符;

Close表示該語句以什麼結束。

注意:collector 如果list則爲list,若爲數組則爲array,默認爲map

Mybaties與hibernate的區別?

相對於hibernate的O/R而言,mybaties是一種「sql mapping」的ORM實現。

Hibernate對數據庫結構提供了較爲完整的封裝,hibernate的o/r mapping實現了pojo和數據庫之間的映射,以及sql的自動生成和執行。程序員每每只需定義好pojo到數據庫表的映射關係,便可經過hibernate提供的辦法完成持久層操做。程序員甚至不須要對sql熟練掌握,hibernate會根據制定的存儲邏輯,自動生成對應的sql並調用jdbc接口加以執行。

而mybaties着力點則在於pojo與sql之間的映射關係。也就是說mybaties並不會爲程序員在運行期間自動執行生成sql執行,具體的sql語句須要程序員本身寫,而後經過映射配置文件,將sql所需的參數以及返回的結果字段映射到指定pojo。

Hibernate是一個全自動的orm映射工具,它能夠自動生成sql語句,而mybatis 須要咱們本身在xml配置文件中寫sql語句,hibernate要比ibatis功能負責和強大不少。由於hibernate自動生成sql語句,咱們 沒法控制該語句,咱們就沒法去寫特定的高效率的sql。對於一些不太複雜的sql查詢,hibernate能夠很好幫咱們完成,可是對於特別複雜的查 詢,hibernate就很難適應了,這時候用mybatis就是不錯的選擇,由於mybatis仍是由咱們本身寫sql語句。

springMVC工做原理(重點)

在整個springMVC框架中,dispatcherServlet處於核心位置,負責協調和組織不一樣組件以完成請求處理並返回響應工做

1.客戶端發送一個請求匹配dispatcherServlet的請求映射路徑(web.xml),web容器將該請求轉交給dispatcherServlet處理。

2.dispatcherServlet接收到請求後,將請求信息(包括url,http,請求頭,請求參數,cook等)以及HandlerMapping的配置找處處理請求的處理器Handler

3.dispatcherServlet根據HandlerMapping獲得對應請求的Handler後,經過HandlerAdapter對Handler進行封裝,再以統一的適配器接口調用Handler。

4.處理器完成業務邏輯的處理後將返回一個ModelAndView給dispatcherServlet,ModelAndView包含視圖邏輯名和模型數據信息。

5.dispatcherServlet藉助ViewResoler完成邏輯視圖名到真實視圖對象的解析。

6.獲得真實視圖對象後,dispatcherServlet使用這個view對ModelAndView中的模型數據進行視圖渲染。

SpringMVC註解

1.@RequestMapping(value="url請求地址")寫在類的上面,表示該類的url請求地址

2.@RequestMaping(value="請求路徑",method={RequestMethod.GET})寫在方法的上面,方法的路徑。

3.@RequestParam 綁定單個請求數據,能夠是url中的數據,表單提交的數據或者上傳的文件。

4.@ResponseBody 用來返回數據給客戶端。例如:

    @ResponseBody

    @RequestMapping(value = "/getGoodsByType", method = RequestMethod.POST)

    public ResultModel<Goods> getGoodsByType(@RequestParam int typeId) {

       return 「modelresult」

    }

5.@RequestBody 用來處理Content-type不是application/x-www-form-urlencoded編碼的內容,例如application/json ,application/xml等。

6.@PathVariable 綁定url模板變量值,@PathVariable(value="id")Integer id這裏value值必須和請求參數一致。

7.@ModelAttribute 綁定數據到Model

8.@SessionAttributes 綁定數據到session

9.@RequestPart 綁定multipart/data數據,並能夠根據類型進行對象轉換。

10.@RequestHeader 綁定請求頭數據

11.@CookieValue 綁定Cookie數據

Springmvc經常使用標籤?

首先在jsp頁面引入springmvc標籤標識符

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

form標籤:<form:form modelAttribute=」contentModel」 method=」post」>

input標籤:<form:input path=」username」>

password標籤:<form:password path=」password」>

checkbox標籤:

<form:checkbox path=」selectArray」 value=${contentModel.testArray}>

SpringMVC與Struts2比較(重點)

1.springmvc是方法級別的攔截,攔截到方法後根據參數上的註解,把request數據注入進去,一個方法對應一個request上下文,而方法同時又跟一個url對應,而struts2是類級別的攔截,每次來了請求就建立一個Action,而後調用setter getter方法把request中的數據注入,struts2中一個Action對象對應一個request上下文,struts2中action一個方法對應一個url,可是其類的屬性被全部方法所共享。

2.springmvc的方法之間基本上獨立的,獨享request response數據,請求數據經過參數獲取,方法之間不共享變量。而struts2雖然方法之間也是獨立的,但其全部Action變量是共享的,這不會影響程序運行,卻給咱們編碼讀程序時帶來麻煩。

3.springmvc的驗證也是一個亮點,支持JSR303,處理ajax的請求更是方便只需一個註解@ResponseBody而後直接返回響應文本便可,以下:

@RequestMapping(value=「/whitelists」)  
public String index(ModelMap map) {  
  Account account = accountManager.getByDigitId(SecurityContextHolder.get().getDigitId());  
  List groupList = groupManager.findAllGroup(account.getId());  
  map.put(「account」, account);  
  map.put(「groupList」, groupList);  
  return 「/group/group-index」;  
}  
 

// @ResponseBody ajax響應,處理Ajax請求也很方便

 

 

 

Spring最核心的2點:IOC和AOP(重點)

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

IOC(控制反轉也稱爲 DI依賴注入):一個對象依賴的其對象經過被動的方式傳遞進來,而不是這個對象本身建立或者查找依賴對象,spring容器初始化時就將依賴傳遞給對象。

IOC(控制反轉):得到依賴對象被反轉,即得到依賴對象的過程由自身管理變爲由IOC容器主動注入。依賴注入就是由IOC容器在運行期間,動態地將某種依賴關係注入到對象中。

一個對象依賴的其餘對象經過被動的方式傳遞過來,而不是這個對象本身建立或者查找依賴對象,容器在對象初始化時不等對象請求就主動將依賴傳遞給它。

AOP:面向方面編程。可以將那些與業務無關,卻爲業務模塊所共同調用的邏輯或責任,例持久化管理,事務管理、日誌管理、權限控制,調試管理等封裝起來,便於減小系統的重複代碼,下降模塊間的耦合度,提升開發和調試效率

Spring的目的就是讓對象與對象之間的關係沒有經過代碼來關聯,都是經過配置類說明管理的(spring根據配置,內部經過反射去動態組裝對象)。

項目中如何體現spring的AOP和IOC的?

項目中體現AOP:

主要是橫切一個關注點,將一個關注點模塊化成一個切面,在切面上聲明一個通知(Advice)和切入點。通知中定義了要插入的方法,切入點內容是一個表達式,以描述須要在哪些對象的哪些方法上插入通知定義的方法。

項目中用到的spring中的切面編程最多的地方是聲明式事務管理。

1.定義一個事務管理

2.配置事務特性(至關於聲明通知,通常在業務層的類的一些方法上定義事務)

3.配置哪些類的哪些方法須要配置事務(至關於切入點,通常在業務類的方法上)

例如:

1.註解方式配置事務

@AspectJ風格的切面能夠經過@Compenent註解標識其爲Spring管理Bean,而@Aspect註解不能被Spring自動識別並註冊爲Bean,

 必須經過@Component註解來完成,以下:

 

@Component    
@Aspect    
public class TestAspect {    
    @Pointcut(value="execution(* *(..))")    
    private void pointcut() {}    
    @Before(value="pointcut()")    
    public void before() {    
        System.out.println("=======before");    
    }    
}   

 

2.攔截方式配置事務(在spring-hibernate.xml中配置)

 Spring的聲明式事務配置:

首先配置sessionfactory

 

<bean id=」sessionFactory」 class=」org.springframework.orm.hibernate4.LocalSessionFactoryBean」>  
   <property name=」configLocation」>  
     <value>/WEB/INF/classes/hibernate.cfg.xml</value>  
   </property>  
</bean>  
 

 

 

 

而後配置事務管理器

 

<bean id=」transactionManager」 class=」org.springframework.orm.hibernate4.HibernateTransactionManager」>  
   <property name="sessionFactory" ref="sessionFactory"></property>  
</bean>  

 

 

配置事務特徵

  1. <tx:advice id=」txAdvice」 transaction-manager=」transactionManager」>  
       <tx:attributes>  
          <tx:method:nametx:method:name=」add.*」 progagation=」REQUIRED」>  
          <tx:method:nametx:method:name=」update.*」 progagation=」SUPPORTS」>  
          <tx:method name="delete*" rollback-for="Exception" />  
       </tx:attributes>  
    </tx:advice>  

     

 

配置哪些類的哪些方法配置事務

 

<aop:config>  
  <aop:pointcut id=」transactionPoitcut」expression=」execution(*.com.ftsc.service.impl.*.*(..))」/>  
   <aop:advisor advice-ref=」txAdvice」pointcut-ref=」transactiomPointcut」>  
</aop:config>  

 

 

Spring的傳播機制:progagation定義了7個事務傳播機制。

REQUIRED:若是存在一個事務,則支持當前事務。若是沒有事務則開啓一個新的事務

SUPPORTS:若是存在一個事務,支持當前事務。若是沒有事務,則非事務的執行,可是對於事務同步的事務管理器,supports與不使用有少量不一樣。

REQUIRES_NEW:老是開啓一個新的事務若是一個事務已經存在,則將當前事務掛起

NOT_SUPPORTED:老是非事務執行,並掛起任務存在的事務

NEVER:老是非事務的執行,若是存在一個活動事務,則拋出異常

NESTED:若是一個活動的事務存在,則運行在一個嵌套的事務中,若是沒有活動事務,則按

TransactionDefinition.PROPAGATION_REQUIRED屬性執行

注:嵌套事務一個很是的概念及時內層事務依賴於外層事務。外層事務失敗時,會回滾內層事務所作的動做。而內層事務操做失敗並不會引發外層事務的回滾。

項目中體現IOC:

例如spring整合struts,讓spring的IOC容器管理struts2的action

首先在web.xml中引入struts配置文件如struts的過濾器,spring的配置文件如:

 

<context-parm>  
  <param-name>contextConfigLocation</param-name>  
  <param-name>classpath:applicationContext.xml</param-name>  
</context-parm>  

 

啓動IOC容器的listener:

 

<listener>  
  <listener-class>  
     org.springframework.web.context.ContextLoaderListener  
  </listener-class>  
</listener>  

 

 

spring整合struts的插件struts-spring-plugin,該插件包的做用是:覆蓋struts的objectFactory來加強核心框架對象的建立,當建立一個對象的時候,它會用struts配置文件的class屬性去和spring配置文件中的id屬性進行關聯,若是能找到,則由spring建立,不然由struts框架自身建立,而後由spring來裝配

接着在spring的配置文件中配置struts的action實例,(注意須要配置scope屬性爲prototype,由於struts的action是單例,這是爲了解決線程安全問題。)在struts配置文件中配置action,但其class屬性再也不指向該action的實現類,而是指向spring容器中action實例的ID

Spring依賴注入方式?

spring注入有3中方法:屬性名稱,setter方法,構造方法

開發中主要使用spring的什麼技術?

1.IOC容器管理各層組件

2.使用aop配置事務

3.整合其餘框架

Spring註解?

@Component:通用註解,可用於任何bean

@Repository:一般用於註解dao類,即持久層

@Service:一般用於註解service類,即服務層。

@Controller:一般用於controller類,即控制層(MVC)

在聲明action時,須要指定爲多例,解決線程安全問題。

 

 

Spring過濾器和攔截器區別?

Spring的攔截器與servlet的filter有類似之處,好比兩者都是AOP編程思想的體現,都能實現權限檢查,日誌記錄等。

區別:

1.使用範圍不一樣:filter是servlet規範規定的,只能用於web程序中,而攔截器既能夠用於web程序,也能夠用於application,swing程序中;

2.規範不一樣:filter是在servlet規範中定義的,是servlet容器支持的,而攔截器是在spring容器內的,是spring框架支持的;

3.使用資源不一樣:同其餘的代碼塊同樣,攔截器也是一個spring的組件,歸spring管理,配置在spring文件中,所以能使用spring裏的任何資源,對象。例如service對象,數據源,事務管理等,經過ioc注入到攔截器便可,而過濾器則不能;

4.深度不一樣:filter只在servlet先後起做用,而攔截器可以深刻到方法先後,異常拋出先後等,所以攔截器的使用具備更大的彈性,因此在spring框架的程序中,要優先使用攔截器。

案例:在web.xml中使用filter如字符集編碼

 

 

Struts2工做原理?

1.客戶端發送一個請求給strtusPrepareAndExecueFilter(在web.xml中),

2.strutsPrepareAndExecuteFilter詢問ActionMapper:該請求是不是一個strtus2的請求,

3.若actionMapper認爲該請求是一個strtus請求,則strutsPrepareAndExecuteFilter把請求的處理交給actionProxy,

4.ActionProxy經過ConfigurationManager詢問框架的配置文件,肯定須要調用action類及action方法,

5.actionProxy建立一個actionInvocation的實例,並進行初始化,

6.actionInvocation實例在調用action過程先後,涉及到相關攔截器(Intercepter)的調用,

7.Action執行完畢,actionInvocation負責根據strtus.xml找到對應的返回結果。調用結果的execute方法,渲染結果,在渲染的過程當中可使用strtus2框架的標籤,

8.執行各個攔截器invocation.invoke()以後的代碼

9.把結果發送給客戶端

Struts2:注意在頁面中展現的數據,都一視同仁的成爲字符串在頁面上展示出來。

Struts2經常使用標籤?

首先在jsp頁面中引入strtus2標籤庫<%@taglib prefix=」s」uri=」/struts-tags」>

1.往action傳值:<input name=」userName」 type=」text」 >

2.顯示標籤property用於輸出指定值:<s:property value=」userName」>

3.用於從頁面往action中(user)的對象傳值:

<s:text name=」user.userName」id=」userName」>

4.迭代<s:iterator>用於將list,Map,ArrayList等集合數據循環遍歷

<s:iterator id=」user」status=」u」value=」userList」>

  <s:property value=」userName」>

</s:iterator>

5.Set標籤用於將某個值放入指定範圍內如application,session

<s:set name=」user」value=」userName」 scope=」request」>

El表達式:如

<s:set name=」name」 value=」<%=request.getParamter(「name」)%>」/>

攔截器和過濾器的區別?

1.過濾器依賴於servlet容器,而攔截器不依賴於servlet容器。

2.Struts2攔截器只能對action請求起做用,而過濾器則對全部請求起做用。

3.攔截器能夠訪問action的上下文,值棧裏的對象,而過濾器不能。

4.在action的生命週期中,攔截器能夠調用屢次,而過濾器只能在容器初始化時被調用一次。

談談你對MVC的理解?

MVC即Model-View-Controller的縮寫

Model:表示業務數據和業務處理,至關於Javabean,一個模型爲多個視圖提供數據

View:用戶看到並與之交互的頁面,向用戶顯示相關數據,並接受用戶的輸入,如jsp

Controller:接受用戶請求並調用相應模型去處理請求,而後根據處理的結果調用相應的視圖來顯示處理的結果如servlet,struts2

MVC處理過程:首先控制器接受用戶的請求,並決定應該調用哪一個模型來進行處理;而後根據用戶請求進行相應的業務邏輯處理,並返回數據;最後控制器調用相應的視圖格式化返回的數據,並經過視圖呈現給用戶。

Action 是單例仍是多例?爲何?

Action是單例,當多個用戶訪問一個請求時候,服務器內存中只有一個與之對應的 action類對象。由於當服務器第一次加載struts的配置文件時,建立一個action後,每發送一個請求,服務器都會去檢索相應的範圍是否存在這 樣一個action實例,若是存在,則使用這個實例,不然建立一個action實例。

Hibernate的緩存機制:一級緩存session緩存和二級緩存sessionfactory緩存?

hibernate:一個基於元數據的輕量級(佔用資源少,沒有浸入性)orm(對象關係數據庫映射)框架。

Session是一級緩存,它是屬於事務範圍的緩存,由Hibernate管理,無需進行干預。

SessionFactory是二級緩存,它是屬於進程範圍或羣集範圍的緩存,能夠進行配置和更改.

一級緩存又叫session緩存,輕量級的,建立和銷燬不須要消耗太多資源,可是它是線程不安全的,要避免多個線程共享一個session實例。咱們框架使用的get,load,save,update,delete等都支持一級緩存的。

二級緩存又叫sessionfactory緩存,重量級的,建立和銷燬須要消耗太多資源,它是線程安全的,一個實例能夠被應用的多個線程共享。

須要在配置文件中啓用二級緩存

<!--啓用二級緩存 -->

<property name="hibernate.cache.use_second_level_cache">true</property>

緩存的操做數據原理:

查詢數據時,會首先從一級緩存中取數據,若是取上,則直接使用,不然到二級緩存中取,若是取到則直接使用,不然,就會發送語句查詢數據庫。這樣利用一級和二級緩存會提升訪問效率。

lazy(Hibernate的延遲加載功能):表示查詢當前對象或關聯對象數據時,不真正訪問數據庫,當使用對象非主鍵屬性時,才真正發送查詢語句,訪問數據庫。

Hibernate工做原理?

1.讀取並解析配置文件

2.讀取並解析映射信息,建立sessionfantory

3.打開session

4.建立事務transaction

5.持久化操做

6.提交事務

7.關閉session

8.關閉sessionfactory

Hibernate的核心接口有5個:session,sessionFactory,transaction,query,configuration?

Session接口:負責進行被持久化對象的crud操做。Session是一級緩存,輕量級的,線程不安全的。

SessionFactory接口:負責初始化Hibernate,它充當數據存儲源的代理,並負責建立session對象,這裏用到工廠模式,sessionFactory是二級緩存,重量級的。

Configuration接口:負責配置並啓動Hibernate,建立sessionFactory對象。在Hibernate啓動過程當中,configuration類的實例首先定義映射文件位置,讀取配置,而後建立sessionFactory對象。

Transact接口:負責相關事務相關的操做。

Query和criteria接口:負責各類數據庫查詢,用sql或者hql語句表達方式。

Hibernate中Java對象的狀態有哪些?

1.臨時態(transient)不處於session緩存中。Oid爲null或等於id的unsaved-value屬性值

2.持久態(persistent)加入session緩存中

3.遊離態(detached)已經被持久化,但再也不處於session的緩存中

Session的清理和清空有什麼區別?

清理緩存調用的是session.flush()方法,而清空調用的是session.clean()方法。

Session清理緩存是指按照緩存中對象的狀態變化來同步更新數據庫,但不清空緩存。而清空則是把session的緩存置空,不一樣步更新到數據庫。

Hibernate的load()方法與get()方法的區別?

Get加載數據不支持延遲加載,若沒有oid對象則返回的是null,而load加載數據支持延遲加載,返回的是一個代理對象

Hibernate優缺點?

優勢:

1.對JDBC訪問數據庫的代碼作了封裝,簡化了數據訪問層繁瑣的重複性代碼

2.映射的靈活性, 它支持各類關係數據庫,從一對一到多對多的各類複雜關係.

3.非侵入性、移植性會好

4.緩存機制: 提供一級緩存和二級緩存。

缺點:

1.沒法對 SQL 進行優化

2.框架中使用 ORM 原則, 致使配置過於複雜

3.執行效率和原生的JDBC相比誤差: 特別是在批量數據處理的時候

4.不支持批量修改、刪除

Hibernate的openSessionView問題?

用於解決懶加載異常問題,主要功能就是把hibernate session和一個請求的線程綁定在一塊兒,直到頁面完整輸出,這樣就能夠保證頁面讀取數據的時候session一直處於開啓狀態,若是去獲取延遲加載對象也不會報錯。

注意配置filter要放在strtus2過濾器的前面,由於它要頁面顯示完後再退出。

Hibernate的getCurrentSession()和openSession()的區別?

1.getCurrentSession()它會先檢查當前線程中是否綁定了session若是有則直接返回,沒有再建立,而openSession()則是直接new一個新的session並返回。

2.使用ThreadLocal來實現線程session的隔離。

3.getCurrentSession()在事務提交的時候會自動關閉session,而openSession()要手動關閉。


項目中爲何使用SSH?

1.使用struts2是由於struts2是基於MVC設計模式,很好的將應用程序進行分層,使開發者更關注業務邏輯實現,其次struts有豐富的taglib,靈活運用,大大提升開發效率。

2.使用hibernate是由於它是基於orm模式的輕量級框架。

3.使用spring是由於基於IOC和AOP架構多層j2ee框架,採用IOC使得很容易實現bean的裝配,採用AOP實現事務管理。

Hibernate的update()和saveOrUpdate()的區別?

Update()和saveOrUpdate()是用來對跨session的po進行狀態管理的。

Update()方法操做的對象必須是持久化的對象,若是此對象在數據庫中不存在的話,就不能使用update()方法。

saveOrUpdate()方法操做的對象便可以是持久化的,也能夠是未持久化的對象,若是該對象是已經持久化的則調用該方法會更新數據庫對象,若是該對象是未持久化的則調用該方法會save到數據庫。

什麼是hibernate的併發機制?怎麼去處理併發問題?

Hibernate的併發機制:1.hibernate的session對象是非線程安全的,對於單個請求,單個會話,單個工做單元,它一般只使用一次而後就丟棄。若是一個session實例會話容許共享的話,那些支持併發運行的,例如http request,session bean將會致使出現資源爭用。若是在http session中hibernate的session話,就可能出現同步訪問http session,只要用戶足夠快點擊瀏覽器的「刷新」。2.多個事務併發訪問同一塊資源,可能會引起第一類丟失更新,髒讀,幻讀,不可重複讀,第二類丟失更新一系列的問題。

解決方案:

1.設置事務隔離級別

Serializable串行化。隔離級別最高

Repeatable read:可重複讀

Read committed:已提交數據讀

Read uncommitted:未提交數據讀。隔離級別最差

設置鎖:樂觀鎖和悲觀鎖。

樂觀鎖:使用版本號或者時間戳檢測更新丟失,在<class>映射中設置optimistic-lock=「all」能夠在沒有版本或者時間戳屬性映射的狀況下實現版本檢查,此時hibernate將比較一行記錄的每一個字段的狀態行。

悲觀鎖:hibernate老是使用數據庫的鎖定機制,從不在內存中鎖定對象,只要爲jdbc鏈接指定一下隔離級別,而後讓數據庫去搞定一切就夠了。類LockMode定義了hibernate所需的不一樣的鎖定級別:

LockMode.UPGRADE,LockMode.UPGRADE_NOWAIT,LockMode.READ

相關文章
相關標籤/搜索