01-什麼是Spring IOC 和DI ? IOC : 控制翻轉 , 它把傳統上由程式代碼直接操控的對象的調用權交給容 器,通過容器來實現對 象組件的裝配和管理。所謂的“控制反轉”概念就是對組件對象控制權的轉 移,從程式代碼本身 轉移到了外部容器。 DI : 依賴註入,在我們創建對象的過程中,把對 ...
01-什麼是Spring IOC 和DI ?
IOC : 控制翻轉 , 它把傳統上由程式代碼直接操控的對象的調用權交給容 器,通過容器來實現對
象組件的裝配和管理。所謂的“控制反轉”概念就是對組件對象控制權的轉 移,從程式代碼本身
轉移到了外部容器。
DI : 依賴註入,在我們創建對象的過程中,把對象依賴的屬性註入到我們的類中。
02-有哪些不同類型的依賴註入實現方式?
依賴註入分為介面註入,Setter方 法註入和構造器註入以及註解註入
-
構造器註入 : 顧名思義, 就是在類中提供有參構造方法, 創建Bean的時候會自動執行構造方
法將依賴數據註入進去
-
Setter方法註入 : 顧名思義, 就是提供屬性對應的setter方法 , 創建Bean的時候會自動執行
Setter方法將依賴數據註入進去
-
註解註入 : 就是在屬性上使用一些註入註入數據, 經常用的有 @Autowired , @Resource
,@Qualifier 註解
@Autowired : 預設根據類型註入 , 按照類型匹配多個Bean,再按照屬性名稱註入
@Resource : 預設按照名稱註入 , 如果找不到對應的Bean,按照類型註入 , 也可以指定
按照名稱註入(name)或者按照類型註入(type)
@Qualifier : 結合@Autowired註解一起使用, 如果按照類型匹配多個Bean , 通過
@Qualifier註解指定按照名稱註入的屬性名稱
03- Spring支持的幾種bean的作用域 Scope
Spring框架支持以下五種bean的作用域:
-
singleton : bean在每個Spring ioc 容器中只有一個實例。
-
prototype:一個bean的定義可以有多個實例。
-
request:每次http請求都會創建一個bean,該作用域僅在基於web的Spring
ApplicationContext情形下有效。
-
session:在一個HTTP Session中,一個bean定義對應一個實例。該作用域僅在基於web
的 Spring ApplicationContext情形下有效。
-
global-session:在一個全局的HTTP Session中,一個bean定義對應一個實例。該作用域
僅在基 於web的Spring ApplicationContext情形下有效。
04- Spring框架中的單例bean是線程安全的嗎?
不是,Spring框架中的單例bean不是線程安全的 , spring 中的 bean 預設是單例模式,spring 框架並沒有對單例 bean 進行多線程的封裝處理。
但是我們一般在使用單例Bean的時候, 不會設置共用數據, 所以也就不會存線上程安全問題 ! 從這個角度講單例bean也是線程安全的
05- spring 自動裝配 bean 有哪些方式?
在Spring框架xml配置中共有5種自動裝配:
-
byName:通過bean的名稱進行自動裝配,如果一個bean的 property 與另一bean 的
name 相 同,就進行自動裝配。
-
byType:通過參數的數據類型進行自動裝配。
-
constructor:利用構造函數進行裝配,並且構造函數的參數通過byType進行裝配。
-
setter方法 : 根據屬性的setter方法註入
-
註解註入
09- JDK動態代理和CGLIB動態代理的區別
Spring AOP中的動態代理主要有兩種方式,JDK動態代理和CGLIB動態代理:
-
JDK動態代理只提供介面的代理,不支持類的代理
Proxy.newProxyInstance(類載入器, 代理對象實現的所有介面, 代理執行器)
-
CGLIB是通過繼承的方式做的動態代理 , 如果某個類被標記為final,那麼它是無法使用 CGLIB做動態代理的。
Enhancer.create(父類的位元組碼對象, 代理執行器)
10- 什麼是AOP , 你們項目中有沒有使用到AOP
AOP一般稱為面向切麵編程,作為面向對象的一種補充,用於 將那些與業務無關,但卻對多個
對象產生影響的公共行為和邏輯,抽取並封裝為一個可重用的模 塊,這個模塊被命名為“切麵”
(Aspect),減少系統中的重覆代碼,降低了模塊間的耦合度,同時 提高了系統的可維護性。
在我們的項目中我們自己寫AOP的場景其實很少 , 但是我們使用的很多框架的功能底層都是AOP
, 例如 : 許可權認證、日誌、事務處理等
11- SpringMVC的執行流程知道嘛
-
用戶發送請求至前端控制器DispatcherServlet;
-
DispatcherServlet收到請求後,調用HandlerMapping處理器映射器,請求獲取Handle;
-
處理器映射器根據請求url找到具體的處理器,生成處理器對象及處理器攔截器(如果有則生
成)一併返回給DispatcherServlet;
-
DispatcherServlet 調用 HandlerAdapter處理器適配器;
-
HandlerAdapter 經過適配調用具體處理器(Handler,也叫後端控制器);
-
Handler執行完成返回ModelAndView;
-
HandlerAdapter將Handler執行結果ModelAndView返回給DispatcherServlet;
-
DispatcherServlet將ModelAndView傳給ViewResolver視圖解析器進行解析;
-
ViewResolver解析後返回具體View;
-
DispatcherServlet對View進行渲染視圖(即將模型數據填充至視圖中)
-
DispatcherServlet響應用戶
12- Spring MVC常用的註解有哪些?
@RequestMapping:用於處理請求 url 映射的註解,可用於類或方法上。用於類上,則表示類中 的所有響應請求的
方法都是以該地址作為父路徑。
@RequestBody:註解實現接收http請求的json數據,將json轉換為java對象。
@ResponseBody:註解實現將conreoller方法返回對象轉化為json對象響應給客戶。
@Controller:控制器的註解,表示是表現層,不能用用別的註解代替
@RestController : 組合註解 @Conntroller + @ResponseBody
@GetMapping , @PostMapping , @PutMapping , @DeleteMapping ...
@PathVariable : 接收請求路徑中的變數
@RequestParam : 接收請求參數
13- Mybatis #{}和${}的區別
#{}是占位符,預編譯處理;${}是拼接符,字元串替換,沒有預編譯處理。
Mybatis在處理#{}時,#{}傳入參數是以字元串傳入,會將SQL中的#{}替換為?號,調用 PreparedStatement的set方
法來賦值。
#{} 可以有效的防止SQL註入,提高系統安全性;${} 不能防止SQL 註入
#{} 的變數替換是在資料庫系統中; ${} 的變數替換是在資料庫系統外
14- Mybatis 如何獲取生成的主鍵
我知道的有二種方式
-
在insert標簽上, 使用
useGeneratedKeys="true"
和keyProperty="userId"
-
在insert表內部, 使用
selectKey
標簽 , 裡面使用select last_insert_id()
查詢生成的ID返回
15- 當實體類中的屬性名和表中的欄位名不一樣 ,怎麼辦
第1種: 通過在查詢的SQL語句中定義欄位名的別名,讓欄位名的別名和實體類的屬性名一致。
第2種: 通過 ResultMap來映射欄位名和實體類屬性名
16- Mybatis如何實現多表查詢
Mybatis是新多表查詢的方式也有二種 :
第一種是 : 編寫多表關聯查詢的SQL語句 , 使用ResultMap建立結果集映射 , 在ResultMap中建立多表結果集映射
的標簽有association
和collection
<resultMap id="Account_User_Map" type="com.heima.entity.Account">
<id property="id" column="id"></id>
<result property="uid" column="uid"></result>
<result property="money" column="money"></result>
<association property="user">
<id property="id" column="uid"></id>
<result property="username" column="username"></result>
<result property="birthday" column="birthday"></result>
<result property="sex" column="sex"></result>
<result property="address" column="address"></result>
</association>
</resultMap>
<!--public Account findByIdWithUser(Integer id);-->
<select id="findByIdWithUser" resultMap="Account_User_Map">
select a.*, username, birthday, sex, address from account a , user u where a.UID = u.id and a.ID = #{id} ;
</select>
第二種是 : 將多表查詢分解為多個單表查詢, 使用ResultMap表的子標簽association
和collection
標簽的
select
屬性指定另外一條SQL的定義去執行, 然後執行結果會被自動封裝
<resultMap id="Account_User_Map" type="com.heima.entity.Account" autoMapping="true">
<id property="id" column="id"></id>
<association property="user" select="com.heima.dao.UserDao.findById" column="uid" fetchType="lazy"></association>
</resultMap>
<!--public Account findByIdWithUser(Integer id);-->
<select id="findByIdWithUser" resultMap="Account_User_Map">
select * from account where id = #{id}
</select>
17-Mybatis都有哪些動態sql?能簡述一下動 態sql的執行原理嗎?
Mybatis動態sql可以讓我們在Xml映射文件內,以標簽的形式編寫動態sql,完成邏輯判斷和動態 拼接sql的功能,
Mybatis提供了9種動態sql標簽 trim|where|set|foreach|if|choose|when|otherwise|bind。
其執行原理為,使用OGNL從sql參數對象中計算表達式的值,根據表達式的值動態拼接sql,以此 來完成動態sql的功
能。
18- Mybatis是否支持延遲載入?
Mybatis僅支持association關聯對象和collection關聯集合對象的延遲載入,association指的就是 一對一,
collection指的就是一對多查詢。在Mybatis配置文件中,可以配置是否啟用延遲載入
lazyLoadingEnabled=true|false。
19- 如何使用Mybatis實現批量插入 ?
使用foreach標簽 , 它可以在SQL語句中進行迭代一個集合。foreach標簽的屬性主 要有item,index,collection,
open,separator,close。
- collection : 代表要遍歷的集合 ,
- item 表示集合中每一個元素進行迭代時的別名,隨便起的變數名;
- index 指定一個名字,用於表示在迭代過程中,每次迭代到的位置,不常用;
- open 表示該語句以什麼開始
- separator 表示在每次進行迭代之間以什麼符號作為分隔符
- close 表示以什麼結束
20- Mybatis 批量插入是否能夠返回主鍵
可以, 返回的主鍵在傳入集合的每個對象屬性中封裝的
21- Mybatis的一級、二級緩存 ?
一級緩存: 基於SqlSession級別的緩存 , 預設開啟
二級緩存 : 基於SqlSessionFactory的NameSpace級別緩存 , 預設沒有開啟, 需要手動開啟
# 配置cacheEnabled為true
<settings>...
<!-- 開啟二級緩存 -->
<setting name="cacheEnabled" value="true"/>
...
</settings>
# 在映射配置文件中配置cache相關配置
<cache eviction="FIFO" flushInterval="60000" readOnly="false" size="1024">
</cache>