面試專題(框架) 原

Spring

Spring有哪些特點?

 

使用Spring有什麼好處?

1  應用解耦

2  依賴注入

3  AOP

4  事務管理

5  MVC

6  集成開發

 

Spring應用程序看起來像什麼?

一些接口及其實現

一些POJO類

一些xml配置文件

 

Spring核心容器模塊是什麼?

Spring core/IOC/BeanFactory

核心容器(Spring Core)

核心容器提供Spring框架的基本功能。Spring以bean的方式組織和管理Java應用中的各個組件及其關係。Spring使用BeanFactory來產生和管理Bean,它是工廠模式的實現。BeanFactory使用控制反轉(IoC)模式將應用的配置和依賴性規範與實際的應用程序代碼分開。

爲了降低Java開發的複雜性, Spring採取了哪幾種策略

POJO/IOC/AOP/Template

基於POJO的輕量性和最小侵入性編程

通過依賴注入和麪向接口實現鬆耦合

基於切面和慣例進行聲明式編程

通過切面和模板減少樣板式代碼

 

談談Spring框架幾個主要部分組成

Spring core/beans/context/aop/jdbc/tx/web mvc/orm

 

說一下Spring中支持的bean作用域

Singleton/prototype/request/session

singleton:單例模式,在整個Spring IoC容器中,使用singleton定義的Bean將只有一個實例。

prototype:原型模式,每次通過容器的getBean方法獲取prototype定義的Bean時,都將產生一個新的Bean實例。

request:對於每次HTTP請求,使用request定義的Bean都將產生一個新實例,即每次HTTP請求將會產生不同的Bean實例。只有在Web應用中使用Spring時該作用域纔有效。

session:對於每次HTTP Session,使用session定義的Bean都將產生一個新實例。同樣只有在Web應用中使用Spring時該作用域纔有效。

 

Spring框架中單例beans是線程安全的嗎?爲什麼?

不是線程安全(默認singleton)

當多個線程併發執行該請求對應的業務邏輯(成員方法),如果該處理邏輯中有對單例狀態的修改(單例的成員屬性),則必須考慮線程同步問題。

 

解釋Spring框架中bean的生命週期

哪些是最重要的bean生命週期方法?能重寫它們嗎?

Setup/teardown

Xml中對應Init-method/destory-method

@PostConstruct @PreDestory

bean標籤有兩個重要的屬性(init-method 和 destroy-method),可以通過這兩個屬性定義自己的初始化方法和析構方法。Spring也有相應的註解:@PostConstruct 和 @PreDestroy。

 

Spring容器實例化Bean有多少種方法?分別是什麼?

使用類構造器

使用靜態工廠方法

Xml配置文件factory-method

 

如何減少Spring XML的配置數量

使用Java配置文件,使xml中的bean轉爲Javaconfig文件方式

註解的方式

 

什麼是bean自動裝配?並解釋自動裝配的各種模式?

Spring容器可以自動配置相互協作beans之間的關聯關係。這意味着Spring可以自動配置一個bean和其他協作bean之間的關係,通過檢查BeanFactory 的內容裏沒有使用和< property>元素。

一個類就是一個Bean,Spring框架是一個Bean容器,替我們管理這些Bean,Spring就是來組織各個角色之間的關係,然後對這些角色進行調動。

自動裝配:

  1. default(beans這個標籤的default-autowired屬性)
  2. 通過byName自動裝配
  3. 通過byType自動裝配
  4. 通過構造函數自動裝配
  5. no不使用自動裝配

 

 

自動裝配有哪些好處和壞處?

自動裝配的優點如下:

  1. 自動裝配能顯著減少裝配的數量,因此在配置數量相當多時採用自動裝配,可以減少工作量。
  2. 自動裝配可以使配置與Java代碼同步更新。例如:如果需要給一個Java類增加一個依賴,那麼該依賴將自動實現而不需要修改配置。因此強烈在開發過程中採用自動裝配,而在系統趨於穩定的時候改爲顯式裝配的方式。

雖然自動裝配具有上面這些優點,但不是說什麼時候都可以使用它,因爲它還有如下一些缺點:

  1. 儘管自動裝配比顯式裝配更神奇,但是,Spring會盡量避免在裝配不明確時進行猜測,因爲裝配不明確可能出現難以預料的結果,而Spring所管理的對象之間的關聯關係也不再能清晰地進行文檔化。
  2. 對於那些根據Spring配置文件生成文檔的工具來說,自動裝配將會使這些工具無法生成依賴信息。

 

是不是所有類型都能自動裝配?如果不是請舉例

不是。原生類型/字符串類型不可以自動裝配

 

什麼是循環依賴?

循環依賴就是N個類中循環嵌套引用,如果在日常開發中我們用new 對象的方式發生這種循環依賴的話程序會在運行時一直循環調用,直至內存溢出報錯。

public class PersonA {
	private PersonB personB;
	public PersonA(PersonB personB) {
		this.personB = personB;
	}
}
public class PersonB {
	private PersonC personC;
	public PersonB(PersonC personC) {
		this.personC = personC;
	}
}
public class PersonC {
	private PersonA personA;
	public PersonC(PersonA personA) {
		this.personA = personA;
	}
}

 

Spring如何解決循環依賴?

DefaultSingletonBeanRegistry.getSingleton源碼中有3個cache:

  1. singletonFactories : 單例對象工廠的cache
  2. earlySingletonObjects :提前暴光的單例對象的Cache
  3. singletonObjects:單例對象的cache

getSingleton()的整個過程,Spring首先從一級緩存singletonObjects中獲取。如果獲取不到,並且對象正在創建中,就再從二級緩存earlySingletonObjects中獲取。如果還是獲取不到且允許singletonFactories通過getObject()獲取,就從三級緩存singletonFactory.getObject()(三級緩存)獲取。

解析:

PersonA的setter依賴了PersonB的實例對象,同時PersonB的setter依賴了PersonA的實例對象”這種循環依賴的情況。

PersonA首先完成了初始化的第一步,並且將自己提前曝光到singletonFactories中,此時進行初始化的第二步,發現自己依賴對象PersonB,此時就嘗試去get(PersonB),發現PersonB還沒有被create,所以執行create流程,PersonB在初始化第一步的時候發現自己依賴了對象PersonA,於是嘗試get(PersonA),嘗試一級緩存singletonObjects(肯定沒有,因爲A還沒初始化完全),嘗試二級緩存earlySingletonObjects(也沒有),嘗試三級緩存singletonFactories,由於PersonA通過ObjectFactory將自己提前曝光了,所以PersonB能夠通過ObjectFactory.getObject拿到PersonA對象(雖然PersonA還沒有初始化完全),PersonB拿到PersonA對象後順利完成了初始化階段1、2、3,完全初始化之後將自己放入到一級緩存singletonObjects中。此時返回PersonA中,PersonA此時能拿到PersonB的對象順利完成自己的初始化階段2、3,最終A也完成了初始化,進去了一級緩存singletonObjects中。而且,由於PersonB拿到了PersonA的對象引用,所以PersonB現在中的PersonA對象完成了初始化。

 

SpringMVC的工作流程和原理是什麼?

 

SpringMVC與Struts2的主要區別?

區別1:

Struts2 的核心是基於一個Filter即StrutsPreparedAndExcuteFilter

SpringMvc的核心是基於一個Servlet即DispatcherServlet(前端控制器)

區別2:

Struts2是基於類開發的,傳遞的參數是通過類的屬性傳遞(屬性驅動和模型驅動),所以只能設計成多例prototype

SpringMvc是基於類中的方法開發的,也就是一個url對應一個方法,傳遞參數是傳到方法的形參上面,所以既可以是單例模式也可以是多例模式singiton

區別3:

Struts2採用的是值棧存儲請求以及響應數據,OGNL存取數據

SpringMvc採用request來解析請求內容,然後由其內部的getParameter給方法中形參賦值,再把後臺處理過的數據通過ModelAndView對象存儲,Model存儲數據,View存儲返回的頁面,再把對象通過request傳輸到頁面去。

 

SpringMVC的控制器是不是單例模式,如果是有什麼問題,怎麼解決

是。單例如果有非靜態成員變量保存狀態會有線程安全問題。

解決辦法1:不要有成員變量,都是方法。

解決辦法2:@Scope(“prototype”)

 

Spring註解的基本概念和原理

註解(Annotation),也叫元數據。一種代碼級別的說明。

Spring註解分爲:

1.類級別的註解:如@Component、@Repository、@Controller、@Service以及JavaEE6的@ManagedBean和@Named註解,都是添加在類上面的類級別註解。

Spring容器根據註解的過濾規則掃描讀取註解Bean定義類,並將其註冊到Spring IoC容器中。

2.類內部的註解:如@Autowire、@Value、@Resource以及EJB和WebService相關的註解等,都是添加在類內部的字段或者方法上的類內部註解。

SpringIoC容器通過Bean後置註解處理器解析Bean內部的註解。

 

舉例說明什麼是Spring基於Java的配置?

Spring3.0之前都是基於XML配置的,Spring3.0開始可以幾乎不使用XML而使用純粹的java代碼來配置Spring應用。

@Configuration
@EnableTransactionManagement
public class AppConfig implements TransactionManagementConfigurer {
	@Bean
	public DruidDataSource dataSource() {
		DruidDataSource dataSource = new DruidDataSource();
		dataSource.setUrl("jdbc:mysql://localhost:3306/sqoop");
		dataSource.setDriverClassName("com.mysql.jdbc.Driver");
		dataSource.setUsername("root");
		dataSource.setPassword("abcd_123");
		return dataSource;
	}

	@Bean
	public JdbcTemplate jdbcTemplate(DruidDataSource dataSource) {
		return new JdbcTemplate(dataSource);
	}

	@Bean
	public PlatformTransactionManager txManager() {
		return new DataSourceTransactionManager(dataSource());
	}

	@Override
	public PlatformTransactionManager annotationDrivenTransactionManager() {
		return txManager();
	}
}

 

什麼是基於註解的容器配置?

XML解耦了配置和原代碼,而註解則精簡了配置。spring框架基於註解的容器配置:

@Qualifier

@Autowired

@Resource

@PostContuct

@PreDestory

 

@Autowired @Resource @Inject 的區別

@Resource

1、@Resource是JSR250規範的實現,需要導入javax.annotation實現注入。

2、@Resource是根據名稱進行自動裝配的,一般會指定一個name屬性

3、@Resource可以作用在變量、setter方法上。

@Autowired

1、@Autowired是spring自帶的,@Inject是JSR330規範實現的,@Resource是JSR250規範實現的,需要導入不同的包

2、@Autowired、@Inject用法基本一樣,不同的是@Autowired有一個request屬性

3、@Autowired、@Inject是默認按照類型匹配的,@Resource是按照名稱匹配的

4、@Autowired如果需要按照名稱匹配需要和@Qualifier一起使用,@Inject和@Name一起使用

 

什麼是AOP,有什麼作用,能應用在什麼場景?

面向切面編程。

AOP主要作用

將日誌記錄,性能統計,安全控制,事務處理,異常處理等代碼從業務邏輯代碼中劃分出來,通過對這些行爲的分離,我們希望可以將它們獨立到非指導業務邏輯的方法中,進而改變這些行爲的時候不影響業務邏輯的代碼。

總之,面向切面的目標與面向對象的目標沒有不同。一是減少重複,二是專注業務。

AOP應用場景

日誌記錄,性能統計,安全控制,事務處理,異常處理等問題及擴展

 

什麼是織入,織入的時機是什麼

把切面(aspect)連接到其它的應用程序類型或者對象上,並創建一個被通知(advised)的對象,這樣的行爲叫做織入。

織入操作可以發生在如下幾個階段。

  1. 編譯時:在對源代碼進行編譯時,特殊的編譯器允許我們通過某種方式指定程序中的各個方面進行Weave的規則,並根據這些規則生成編譯完成的應用程序;
  2. 編譯後:根據Weave規則對已經完成編譯的程序模塊進行Weave操作;
  3. 載入時:在載入程序模塊的時候進行Weave操作;
  4. 運行時:在程序運行時,根據情況織入程序中的對象和方面。

編譯期織入是指在Java編譯期,將切面織入到Java類中;而類加載期織入則指通過特殊的類加載器,在類字節碼加載到JVM時,織入切面;運行期織入則是採用CGLib工具或JDK動態代理進行切面的織入

 

什麼是切入點,關注點,連接點

連接點(JoinPoint) spring允許你是通知(Advice)的地方,基本每個方法的前、後、環繞或拋出異常時都可以是連接點,spring只支持方法連接點。其他如AspectJ還可以讓你在構造器或屬性注入時都行。

切入點(Pointcut) 一個類裏,有N個方法就有N個連接點,但是你並不想在所有方法上都使用通知,只想讓其中幾個方法執行前、後或者拋出異常完成其他功能(如日誌,性能分析),那麼就用切入點來篩選到那幾個你想要的方法。

public class BusinessLogic {
    public void doSomething() {
        // 驗證安全性;Securtity關注點
        // 執行前記錄日誌;Logging關注點
        doit();
        // 保存邏輯運算後的數據;Persistence關注點
        // 執行結束記錄日誌;Logging關注點
    }
} 

Business Logic屬於核心關注點,它會調用到Security,Logging,Persistence等橫切關注點。

 

Spring提供了幾種AOP支持?

方式一:經典的基於代理的AOP

方式二:@AspectJ註解的切面

方式三:純POJO切面

AOP常用的實現方式有兩種,一種是採用聲明的方式來實現(基於XML),一種是採用註解的方式來實現(基於AspectJ)。

 

舉例說明什麼是事物以及其特點

事務是爲了保證對同一數據表操作的一致性。

  1. A是原子性(atomic):事務中包含的各項操作必須全部成功執行或者全部不執行。任何一項操作失敗,將導致整個事務失敗,其他已經執行的任務所作的數據操作都將被撤銷,只有所有的操作全部成功,整個事務纔算是成功完成。     
  2. C是一致性(consistent):保證了當事務結束後,系統狀態是一致的。那麼什麼是一致的系統狀態?例如,如果銀行始終遵循着"銀行賬號必須保持正態平衡"的原則,那麼銀行系統的狀態就是一致的。上面的轉賬例子中,在取錢的過程中,賬戶會出現負態平衡,在事務結束之後,系統又回到一致的狀態。這樣,系統的狀態對於客戶來說,始終是一致的。     
  3. I是隔離性(isolated):使得併發執行的事務,彼此無法看到對方的中間狀態。保證了併發執行的事務順序執行,而不會導致系統狀態不一致。     
  4. D是持久性(durable):保證了事務完成後所作的改動都會被持久化,即使是發生災難性的失敗。可恢復性資源保存了一份事務日誌,如果資源發生故障,可以通過日誌來將數據重建起來

 

Java EE事務類型有哪些?應用場景是什麼?Spring是如何實現的?

一般J2EE服務器支持三種類型的事務管理。即:JDBC事務,JTA事務,容器管理事務。

JDBC事物接口:PlatformTransactionManager、AbstractPlatformTransactionManager、DataSourceTransactionManager

JTA具有三個主要的接口:UserTransaction、JTATransactionManager、Transaction接口

容器級事務主要是由容器提供的事務管理,如:WebLogic/Websphere

 

Spring有幾個事物隔離級別,分別詳述

事務隔離級別(5種)

DEFAULT 這是一個PlatfromTransactionManager默認的隔離級別,使用數據庫默認的事務隔離級別。

未提交讀(read uncommited) :髒讀,不可重複讀,虛讀都有可能發生。

已提交讀 (read commited):避免髒讀。但是不可重複讀和虛讀有可能發生。

可重複讀 (repeatable read) :避免髒讀和不可重複讀.但是虛讀有可能發生。

串行化的 (serializable) :避免以上所有讀問題。

 

Mysql 默認:可重複讀

Oracle 默認:讀已提交

 

read uncommited:是最低的事務隔離級別,它允許另外一個事務可以看到這個事務未提交的數據。

read commited:保證一個事物提交後才能被另外一個事務讀取。另外一個事務不能讀取該事物未提交的數據。

repeatable read:這種事務隔離級別可以防止髒讀,不可重複讀。但是可能會出現幻象讀。它除了保證一個事務不能被另外一個事務讀取未提交的數據之外還避免了以下情況產生(不可重複讀)。

serializable:這是花費最高代價但最可靠的事務隔離級別。事務被處理爲順序執行。除了防止髒讀,不可重複讀之外,還避免了幻象讀(避免三種)。

 

描述下SpringJDBC的架構

Spring JDBC提供了一套JDBC抽象框架,用於簡化JDBC開發。

Spring主要提供JDBC模板方式、關係數據庫對象化方式、SimpleJdbc方式、事務管理來簡化JDBC編程。

support包:提供將JDBC異常轉換爲DAO非檢查異常轉換類、一些工具類如JdbcUtils等。

datasource包:提供簡化訪問JDBC 數據源(javax.sql.DataSource實現)工具類,並提供了一些DataSource簡單實現類從而能使從這些DataSource獲取的連接能自動得到Spring管理事務支持。

core包:提供JDBC模板類實現及可變部分的回調接口,還提供SimpleJdbcInsert等簡單輔助類。

object包:提供關係數據庫的對象表示形式,如MappingSqlQuery、SqlUpdate、SqlCall

 

描述下Spring事務處理類及其作用

Spring框架支持事務管理的核心是事務管理器抽象,對於不同的數據訪問框架(如Hibernate)通過實現策略接口PlatformTransactionManager。該接口由3個方法組成:

getTransaction():返回一個已經激活的事務或創建一個新的事務(根據給定的TransactionDefinition類型參數定義的事務屬性),返回的是TransactionStatus對象代表了當前事務的狀態,該方法拋出TransactionException(未檢查異常)表示事務由於某種原因失敗。

commit():用於提交TransactionStatus參數代表的事務

rollback():用於回滾TransactionStatus參數代表的事務

 

編程式事務

1、直接使用PlatformTransactionManager實現

2、使用TransactionTemplate模板類,用於支持邏輯事務管理。

 

聲明式事務

1、AOP代理方式實現

2、@Transactional實現事務管理

<tx:annotation-driven transaction-manager="transactionManager"

 

Spring提供幾種事物實現?分別是什麼?各有什麼優缺點?

一種編程式和三種聲明式

一種編程式(基於底層 API txManager.getTransaction方式或基於TransactionTemplate)

三種聲明式:AOP(TransactionProxyFactoryBean),基於AspectJ的聲明式事務<tx:advice>,基於註解方式的聲明式事務(@Transactional)編程式事務侵入性比較強,但處理粒度更細。

 

JdbcTemplate有哪些主要方法

CRUD操作全部包含在JdbcTemplate

ResultSetExtractor/RowMapper/RowCallbackHandler

 

JdbcTemplate支持哪些回調類

1、RowMapper是一個精簡版的ResultSetExtractor,RowMapper能夠直接處理一條結果集內容,而ResultSetExtractor需要我們自己去ResultSet中去取結果集的內容,但是ResultSetExtractor擁有更多的控制權,在使用上可以更靈活;

2、與RowCallbackHandler相比,ResultSetExtractor是無狀態的,他不能夠用來處理有狀態的資源。

 

MyBatis

什麼是MyBatis?簡述MyBatis的體系結構

Mybatis的功能架構分爲三層:

  1. API接口層:提供給外部使用的接口API,開發人員通過這些本地API來操縱數據庫。接口層一接收到調用請求就會調用數據處理層來完成具體的數據處理。
  2. 數據處理層:負責具體的SQL查找、SQL解析、SQL執行和執行結果映射處理等。它主要的目的是根據調用的請求完成一次數據庫操作。
  3. 基礎支撐層:負責最基礎的功能支撐,包括連接管理、事務管理、配置加載和緩存處理,這些都是共用的東西,將他們抽取出來作爲最基礎的組件。爲上層的數據處理層提供最基礎的支撐。

 

列舉MyBatis的常用API及方法

org.apache.ibatis.session.SqlSession

MyBatis工作的主要頂層API,表示和數據庫交互的會話。完畢必要數據庫增刪改查功能。

 

org.apache.ibatis.executor.Executor

MyBatis執行器,是MyBatis 調度的核心,負責SQL語句的生成和查詢緩存的維護。

 

org.apache.ibatis.executor.statement.StatementHandler

封裝了JDBC Statement操作。負責對JDBC statement 的操作。如設置參數、將Statement結果集轉換成List集合。

 

org.apache.ibatis.executor.parameter.ParameterHandler

負責對用戶傳遞的參數轉換成JDBC Statement 所須要的參數。

 

org.apache.ibatis.executor.resultset.ResultSetHandler

負責將JDBC返回的ResultSet結果集對象轉換成List類型的集合

 

org.apache.ibatis.type.TypeHandler

負責java數據類型和jdbc數據類型之間的映射和轉換

 

org.apache.ibatis.mapping.MappedStatement

MappedStatement維護了一條<select|update|delete|insert>節點的封裝

 

org.apache.ibatis.mapping.SqlSource

負責依據用戶傳遞的parameterObject,動態地生成SQL語句,將信息封裝到BoundSql對象中,並返回

 

org.apache.ibatis.mapping.BoundSql

表示動態生成的SQL語句以及對應的參數信息

 

org.apache.ibatis.session.Configuration

MyBatis全部的配置信息都維持在Configuration對象之中

 

對於Hibernate和MyBatis的區別與利弊,談談你的看法

1、hibernate真正掌握要比mybatis難,因爲hibernate的功能和特性非常多,還不適合多表關聯查詢。

2、hibernate查詢會將所有關聯表的字段全部查詢出來,會導致性能消耗,當然hibernate也可以自己寫sql指定字段,但這就破壞了hibernate的簡潔性。mybatis的sql是自己手動編寫的,所以可以指定查詢字段。

3、hibernate與數據庫管聯只需在xml文件中配置即可,所有的HQL語句都與具體使用的數據庫無關,移植性很好;mybatis所有的sql都是依賴所用數據庫的,所以移植性差。

4、hibernate是在jdbc上進行一次封裝,mybatis是基於原生的jdbc,運行速度較快。

5、如果有上千萬的表或者單次查詢或提交百萬數據以上不建議使用hibernate。如果統計功能、多表關聯查詢較多較複雜建議使用mybatis。

 

#{}和${}的區別是什麼?

select * from location where id = ${id}  =>  Select * from location where id = xxx;

Select * from location where id = #{}   =>  Select * from location where id="xxxx";

${}方式無法防止sql注入;

 

Order by動態參數時,使用${}而不用#{}

模糊查詢的時候使用${}

select * from location where name like '${}%';

 

Mybatis是如何進行分頁的?分頁插件的原理是什麼?

RowBounds針對ResultSet結果集執行分頁

<select id="selectById" parameterType="int" resultType="com.dongnao.demo.dao.Location">
	select * from location where id = #{id}
</select>

插件分頁

@Intercepts

分頁插件的基本原理是使用Mybatis提供的插件接口,實現自定義插件,在插件的攔截方法內攔截待執行的sql,然後重寫sql,根據dialect方言,添加對應的物理分頁語句和物理分頁參數。

 

簡述Mybatis的插件運行原理,以及如何編寫一個插件

Mybatis僅可以編寫針對ParameterHandler、ResultSetHandler、StatementHandler、Executor這4種接口的插件。

Mybatis使用JDK的動態代理,爲需要攔截的接口生成代理對象以實現接口方法攔截功能,每當執行這4種接口對象的方法時,就會進入攔截方法,具體就是InvocationHandler的invoke()方法。當然,只會攔截那些你指定需要攔截的方法。

 

實現Mybatis的Interceptor接口並複寫intercept()方法,然後在給插件編寫註解,指定要攔截哪一個接口的哪些方法即可。記住,別忘了在配置文件中配置你編寫的插件。

 

Mybatis動態sql是做什麼的?都有哪些動態sql?簡述一下動態sql的執行原理

Mybatis動態sql可以讓我們在Xml映射文件內,以標籤的形式編寫動態sql,完成邏輯判斷和動態拼接sql的功能。

Mybatis提供了9種動態sql標籤trim|where|set|foreach|if|choose|when|otherwise|bind

 

原理爲,使用OGNL從sql參數對象中計算表達式的值,根據表達式的值動態拼接sql,以此來完成動態sql的功能。

 

動態SQL,主要用於解決查詢條件不確定的情況:在程序運行期間,根據提交的查詢條件進行查詢。

動態SQL,即通過MyBatis提供的各種標籤對條件作出判斷以實現動態拼接SQL語句。

 

Mybatis是否支持延遲加載?如果支持,它的實現原理是什麼?

Mybatis僅支持association關聯對象和collection關聯集合對象的延遲加載,association指的就是一對一,collection指的就是一對多查詢。在Mybatis配置文件中,可以配置是否啓用延遲加載lazyLoadingEnabled=true|false。

 

它的原理是,使用CGLIB創建目標對象的代理對象。當調用目標方法時,進入攔截器方法,如:調用a.getB().getName(),攔截器invoke()方法發現a.getB()是null值,那麼就會單獨發送事先保存好的查詢關聯B對象的sql,把B查詢上來,然後調用a.setB(b),於是a的對象b屬性就有值了,接着完成a.getB().getName()方法的調用。這就是延遲加載的基本原理。

 

Mybatis的Xml映射文件中,不同的Xml映射文件,id是否可以重複?

可以。Mybatis namespace+id

 

Mybatis都有哪些Executor執行器?它們之間的區別是什麼?

SimpleExecutor執行一次sql,開始創建一個statement,用完關閉statement

ReuseExector 類似數據庫連接池,statement用完後返回,statement可以複用

BatchExecutor主要用於批處理執行

 

Mybatis是否可以映射Enum枚舉類?

可以。Mybatis可以映射枚舉類,不單可以映射枚舉類,Mybatis可以映射任何對象到表的一列上。

 

Mybatis能否執行一對一、一對多關聯查詢?都有哪些實現方式,它們之間有什麼區別

能,Mybatis不僅可以執行一對一、一對多的關聯查詢,還可以執行多對一,多對多的關聯查詢。

 

什麼是MyBatis的接口綁定,有什麼好處

接口映射就是在IBatis中任意定義接口,然後把接口裏邊的方法和SQL語句綁定,我們可以直接調用接口方法,比起SqlSession提供的方法我們可以有更加靈活的選擇和設置。

 

iBatis和MyBatis在細節上的不同有哪些

區別太多,篇幅太長,大家可以自行百度下。

 

講下MyBatis的緩存

MyBatis 提供了查詢緩存來緩存數據,以提高查詢的性能。MyBatis 的緩存分爲一級緩存和二級緩存。

 

一級緩存是 SqlSession 級別的緩存

二級緩存是 mapper 級別的緩存,多個 SqlSession 共享

一級緩存

一級緩存是SqlSession級別的緩存,是基於HashMap的本地緩存。不同的 SqlSession之間的緩存數據區域互不影響。

 

一級緩存的作用域是SqlSession範圍,當同一個SqlSession執行兩次相同的 sql語句時,第一次執行完後會將數據庫中查詢的數據寫到緩存,第二次查詢時直接從緩存獲取不用去數據庫查詢。當SqlSession執行insert、update、delete 操做並提交到數據庫時,會清空緩存,保證緩存中的信息是最新的。

 

MyBatis默認開啓一級緩存。

 

二級緩存

二級緩存是mapper級別的緩存,同樣是基於HashMap進行存儲,多個SqlSession可以共用二級緩存,其作用域是mapper的同一個namespace。不同的SqlSession兩次執行相同的namespace下的sql語句,會執行相同的sql,第二次查詢只會查詢第一次查詢時讀取數據庫後寫到緩存的數據,不會再去數據庫查詢。

 

MyBatis 默認沒有開啓二級緩存,開啓只需在配置文件中寫入如下代碼:

<settings>  
    <setting name="cacheEnabled" value="true"/>  
</settings>

 

 

 

 

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