Spring部分面試知識

對Spring的理解

spring是一個輕量級的開源框架,貫穿持久層、業務邏輯層、控制層。讓每個功能模塊均可以獨立的分開,下降耦合度,提升代碼複用度。spring經過控制反轉下降耦合性,一個對象的依賴經過被動的注入而非主動的new。spring還包括面向切面、MVC整合等等。以上是我對spring的淺顯認識。html

Spring IOC的理解

控制反轉,指由Spring來控制對象的生命週期和對象間的關係。之前對象的建立時機是由本身把握的,開發人員主動建立對象,如今由IOC容器建立,而後注入。全部的類都會在IOC容器中註冊,告訴spring你是什麼,你須要什麼,spring容器在合適的時機將你所須要的東西給你,控制對象生命週期的再也不是引用它的對象而是spring容器。前端

spring先加載xml文件,Bean先在spring容器中註冊,而後會進行初始化Bean,再將Bean存到容器的緩存區(Map),誰須要就給它注入,並且緩存區的對象還在,一直在,這屬於單例,直到關閉spring。(scope見下面)java

DI:依賴注入,動態的向某個對象注入它所須要的對象。spring

SpringAOP(攔截器的實現原理)

http://www.cnblogs.com/xiaolovewei/p/7919763.htmlsql

Spring事務

http://www.cnblogs.com/xiaolovewei/p/9418874.html數據庫

Spring 中的scope  ,也就是Bean的做用域

scope有Singleton、Prototype、request、session、global session。其中主要的是singleton和prototype。編程

singleton指的是IOC容器中只存在一個實例,全部對該對象的引用都要共享該實例。該對象自從第一次被建立之後,直到容器退出纔會被銷燬。就像上面說的,容器中有一個緩存區(MAP)保管這個單例。設計模式

prototype:IOC容器接收到對該對象的請求時,就會新建一個對象實例給對方。返回給對方之後,IOC容器就不在持有該對象的引用,也就是IOC只負責建立該對象實例,置於銷燬,就無論了緩存

request:XmlWebApplicationContext會爲每一個HTTP請求建立一個對象,當請求結束,該對象也就被銷燬。安全

session:會爲每一個session建立一個對象,存活時間爲session

Spring常見建立對象的註解?

@Component@Controller@ Service@ Repository   <context:compenent-scan  base-package="">

xml:<bean>無參構造器、靜態工廠(get方法)。

對象(屬性)注入的方式

xml:set方法(<property name  value>)、構造器(<constructor-arg name value>)

註解:Autowired、Resource

Spring中用到的設計模式

答:簡單工廠、工廠方法單例模式、適配器、包裝器、代理、觀察者、策略、模板方法

Spring的優勢?

答:1.下降了組件之間的耦合性 ,實現了軟件各層之間的解耦 
2.可使用容易提供的衆多服務,如事務管理,消息服務等 
3.容器提供單例模式支持 
4.容器提供了AOP技術,利用它很容易實現如權限攔截,運行期監控等功能 
5.容器提供了衆多的輔助類,能加快應用的開發 
6.spring對於主流的應用框架提供了集成支持,如hibernate,JPA,Struts等 
7.spring屬於低侵入式設計,代碼的污染極低 
8.獨立於各類應用服務器 
9.spring的DI機制下降了業務對象替換的複雜性 
10.Spring的高度開放性,並不強制應用徹底依賴於Spring,開發者能夠自由選擇spring 的部分或所有 

Spring 的自動裝配

https://www.cnblogs.com/xiaolovewei/p/9424804.html

byName/byType/constructor

咱們在xml中注入對象,使用<property>屬於手動裝配,自動裝配不須要寫這個。如byName,類中對象的屬性名與bean的名字同樣(id)則直接注入。

Autowired和Resource

https://www.cnblogs.com/xiaolovewei/p/9424856.html

Autowired默認使用byType,單例沒問題,Spring的註解。若是想使用byName,則和Qualifier("")一塊兒使用。

Resource(name="")默認byName。J2EE的註解

Spring保證安全性

首先,Controller、Dao、service都是單例的,就有可能出現多線程的安全問題----有類成員變量,這樣多線程訪問就會使用到共享變量了。

避免:不要使用類成員變量,這樣就不會有共享變量了。或者使用ThreadLocal

         使用多例,scope="property"。這樣每一個線程都有本身的對象,就不會出現問題。

 SpringMVC理解

spring MVC 其實就是 spring 本身作了一套很合適的 controller層 框架。結合性更好。 這個東西的核心就是 Dispatcher(能夠理解成一個servlet),根據配置映射的JSP文件路徑進行跳轉。controller層也可使用annotation(註解)的方式來描述。MVC的中的C。

 SpringMVC流程(原理)

1 用戶發送請求至前端控制器DispatcherServlet;

2 前端控制器調用處理器映射器HandlerMapping,處理器映射器根據URL找到具體的處理器(Handler,也就是Controller),並返回給前端控制器。

3 前端控制器經過處理器適配器HandlerAdapter調用處理器。

4  執行處理器(Controller),執行完後返回給前端控制器一個ModelAndView

5 前端控制器調用視圖解析器ViewResolver解析視圖,並返回View給前端控制器。

6 前端控制器渲染並顯示視圖。

 SpringMVC優勢

 1. 能夠任意使用各類視圖技術,而不只僅侷限於JSP

2. 支持各類請求資源的映射策略

3 .它應是易於擴展的

SpringMVC對請求的攔截方式

<servlet-mapping> 中的<url-pattern>/<url-pattern>。/表明攔截全部請求,包括靜態資源。 .action攔截對應action結尾的路徑,不會攔截靜態資源。

對於/,解決靜態資源不被攔截的方法:<mvc:resource location="/WEB-INF/js/" mapping="/js/**">  全部對mapping的訪問,都轉到location位置。

<mvc:annotation-driven>

springmvc須要配置HandlerMapping、HandlerAdapter、ViewResolver。而<mvc:annotation-driven>會自動配置RequestMappingHandlerMapping和RequestMaappingHandlerAdapter。

 

MyBatis

MyBatis是一個優秀的持久層框架,它對jdbc的操做數據庫的過程進行封裝,使開發者只須要關注 SQL 自己,而不須要花費精力去處理例如註冊驅動、建立connection、建立statement、手動設置參數、結果集檢索等jdbc繁雜的過程代碼。

Mybatis經過xml或註解的方式將要執行的各類statement(statement、preparedStatemnt、CallableStatement)配置起來,並經過java對象和statement中的sql進行映射生成最終執行的sql語句,最後由mybatis框架執行sql並將結果映射成java對象並返回。

Mybatis解決jdbc編程的問題

一、  數據庫連接建立、釋放頻繁形成系統資源浪費從而影響系統性能,若是使用數據庫連接池可解決此問題。

解決:在SqlMapConfig.xml中配置數據連接池,使用鏈接池管理數據庫連接。

二、  Sql語句寫在代碼中形成代碼不易維護,實際應用sql變化的可能較大,sql變更須要改變java代碼。

解決:將Sql語句配置在XXXXmapper.xml文件中與java代碼分離。

三、  向sql語句傳參數麻煩,由於sql語句的where條件不必定,可能多也可能少,佔位符須要和參數一一對應。

解決:Mybatis自動將java對象映射至sql語句,經過statement中的parameterType定義輸入參數的類型。

四、  對結果集解析麻煩,sql變化致使解析代碼變化,且解析前須要遍歷,若是能將數據庫記錄封裝成pojo對象解析比較方便。

解決:Mybatis自動將sql執行結果映射至java對象,經過statement中的resultType定義輸出結果的類型。

 

Mapper接口開發的一些規範

1.mapper.xml中的namespace和mapper接口類路徑相同;

2.mapper.xml中的SQL對應的id與mapper接口的方法名相同;

3.mapper.xml中的每一個sql的parameterType和接口的輸入參數類型相同;

4.mapper.xml中的每一個sql的resultType要與接口的返回參數類型相同

#{name}獲取parameterType中的屬性的值,若輸入對象,name就是對應的字段,輸入hashmap,name就是key。

resultType總結:

resultType中對象的字段名和查詢出來的結果的字段名相同。

返回單個pojo對象要保證sql查詢出來的結果集爲單條,內部使用sqlsession.selectOne方法調用,mapper接口使用pojo對象做爲方法返回值。

 返回pojo列表表示查詢出來的結果集可能爲多條,內部使用sqlsession.selectList方法,mapper接口使用List<pojo>對象做爲方法返回值。

resultMap

若是sql查詢字段名和對象的屬性名不一致,能夠經過resultMap將字段名和屬性名做一個對應關係 ,resultMap實質上還須要將查詢結果映射到pojo對象中

resultMap處理關聯查詢返回的結果

 一對一:類中除了基本的屬性,還包含其餘對象,orders中含有User,使用association標籤

<resultMap type="cn.itcast.mybatis.po.Orders" id="userordermap">
<!-- 這裏的id,是mybatis在進行一對一查詢時將user字段映射爲user對象時要使用,必須寫 -->
    <id property="id" column="id"/>
    <result property="user_id" column="user_id"/>
    <result property="number" column="number"/>
    <association property="user" javaType="cn.itcast.mybatis.po.User">
    <!-- 這裏的id爲user的id,若是寫上表示給user的id屬性賦值 -->
        <id property="id" column="user_id"/>
        <result property="username" column="username"/>
        <result property="address" column="address"/>
    </association>
</resultMap>

一對多:類中除了基本的屬性外,還包含對象的集合,orders中含有List<Orderdetail>。使用collection標籤

<resultMap type="cn.itcast.mybatis.po.Orders" id="userorderdetailmap">
<id property="id"column="id"/>
<result property="user_id" column="user_id"/>
<result property="number" column="number"/>
<collection property="orderdetails" ofType="cn.itcast.mybatis.po.Orderdetail">
    <id property="id" column="orderdetail_id"/>
    <result property="items_id" column="items_id"/>
    <result property="items_num" column="items_num"/>
</collection>
</resultMap>

多對多:User中包含List<Orders>,Orders中包含List<Orderdetail>。collection中嵌套collection。

MyBatis延遲加載

查詢關聯信息時(須要關聯對象,要查關聯表),首次查詢只查詢主要信息(單表查詢),關聯信息等用戶獲取時再查詢(須要查詢關聯表),大大緩解了數據庫壓力。association和collection都具有延遲加載的功能。

這個跟 本身在作項目時同樣,先查詢單表,若是還須要其餘表關聯信息,再查詢其餘表。

sqlmapconfig.xml中

<settings>
     <!--開啓延遲加載-->
     <setting name="lazyLoadingEnabled" value="true"/>
     <!--關閉積極加載-->
     <setting name="aggressiveLazyLoading" value="false"/>
 </settings>
<!--查詢訂單和建立訂單的用戶,使用延遲加載-->
 <resultMap id="OrderAndUserLazyLoad" type="Orders">
     <id column="id" property="id"/>
     <result column="user_id" property="userId" />
     <result column="number" property="number" />
     <result column="createtime" property="createtime" />
     <result column="note" property="note" />
     <!--
     select:要延遲加載的statement的id colunm:關聯兩張表的那個列的列名 -->
     <association property="user" javaType="User" select="findUser" column="user_id">
<--select中就是延遲加載再去執行的sql-->
     </association>
 </resultMap>
<select id="findOrdersByLazyLoad" resultMap="OrderAndUserLazyLoad"> SELECT * FROM orders </select>

 <select id="findUser" parameterType="int" resultType="User"> SELECT * FROM User WHERE id = #{value} </select>

從上面看,其實就是單表查詢兩次。

Mybatis緩存

Mybatis一級緩存的做用域是同一個SqlSession,在同一個sqlSession中兩次執行相同的sql語句,第一次執行完畢會將數據庫中查詢的數據寫到緩存(內存),第二次會從緩存中獲取數據將再也不從數據庫查詢,從而提升查詢效率。當一個sqlSession結束後該sqlSession中的一級緩存也就不存在了。當遇到增刪改時會清空緩存。Mybatis默認開啓一級緩存。

Mybatis二級緩存是多個SqlSession共享的,其做用域是mapper的同一個namespace,不一樣的sqlSession兩次執行相同namespace下的sql語句且向sql中傳遞參數也相同即最終執行相同的sql語句,第一次執行完畢會將數據庫中查詢的數據寫到緩存(內存),第二次會從緩存中獲取數據將再也不從數據庫查詢,從而提升查詢效率。當遇到增刪改時會清空緩存。Mybatis默認沒有開啓二級緩存須要在setting全局參數中配置開啓二級緩存。

#{}和${}的區別

#{}是預編譯處理,${}是字符串替換。 Mybatis在處理#{}時,會將sql中的#{}替換爲?號,調用PreparedStatement的set方法來賦值; Mybatis在處理${}時,就是把${}替換成變量的值。 使用#{}能夠有效的防止SQL注入,提升系統安全性。

當實體類中的屬性名和表中的字段名不同 ,怎麼辦 ?

1。查詢語句中,給字段名取別名。

2.。resultMap

模糊查詢like語句該怎麼寫?

1.在Java代碼中寫。string wildcardname = 「%smi%」;    list<name> names = mapper.selectlike(wildcardname);

2.Java代碼中傳入變量,SQL語句中拼接通配符,會引發SQL注入。select * from foo where bar like "%"${value}"%"

mapper如何傳遞多個參數

1.包裝成pojo對象。

2.map

Mybatis的Xml映射文件中,不一樣的Xml映射文件,id是否能夠重複?

不一樣的Xml映射文件,若是配置了namespace,那麼id能夠重複;若是沒有配置namespace,那麼id不能重複;畢竟namespace不是必須的,只是最佳實踐而已。

一般一個Xml映射文件,都會寫一個Dao接口與之對應,請問,這個Dao接口的工做原理是什麼?Dao接口裏的方法,參數不一樣時,方法能重載嗎?

        Dao接口,就是人們常說的Mapper接口,接口的全限名,就是映射文件中的namespace的值,接口的方法名,就是映射文件中MappedStatement的id值,接口方法內的參數,就是傳遞給sql的參數。Mapper接口是沒有實現類的,當調用接口方法時,接口全限名+方法名拼接字符串做爲key值,可惟必定位一個MappedStatement,舉例:com.mybatis3.mappers.StudentDao.findStudentById,能夠惟一找到namespace爲com.mybatis3.mappers.StudentDao下面id = findStudentById的MappedStatement。在Mybatis中,每個<select>、<insert>、<update>、<delete>標籤,都會被解析爲一個MappedStatement對象。

        Dao接口裏的方法,是不能重載的,由於是全限名+方法名的保存和尋找策略。

        Dao接口的工做原理是JDK動態代理,Mybatis運行時會使用JDK動態代理爲Dao接口生成代理proxy對象,代理對象proxy會攔截接口方法,轉而執行MappedStatement所表明的sql,而後將sql執行結果返回。

相關文章
相關標籤/搜索