2021Java面試題合集-MyBatis面試題37道_第1頁
2021Java面試題合集-MyBatis面試題37道_第2頁
2021Java面試題合集-MyBatis面試題37道_第3頁
2021Java面試題合集-MyBatis面試題37道_第4頁
2021Java面試題合集-MyBatis面試題37道_第5頁
已閱讀5頁,還剩11頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

MyBatis簡介

1.MyBatis是什么?

?Mybatis是一個半ORM(對象關(guān)系映射)框架,它內(nèi)部封裝了JDBC,開發(fā)時只需要關(guān)注SQL語

句本身,不需要花費精力去處理加載驅(qū)動、創(chuàng)建連接、創(chuàng)建statement等繁雜的過程。程序員直

接編寫原生態(tài)sql,可以嚴格控制sql執(zhí)行性能,靈活度高。

?MyBatis可以使用XML或注解來配置和映射原生信息,將POJO映射成數(shù)據(jù)庫中的記錄,避免了

幾乎所有的JDBC代碼和手動設(shè)置參數(shù)以及獲取結(jié)果集。

2.Mybatis優(yōu)缺點

優(yōu)點

與傳統(tǒng)的數(shù)據(jù)庫訪問技術(shù)相比,ORM有以下優(yōu)點:

?基于SQL語句編程,相當(dāng)靈活,不會對應(yīng)用程序或者數(shù)據(jù)庫的現(xiàn)有設(shè)計造成任何影響,SQL寫在

XML里,解除sql與程序代碼的耦合,便于統(tǒng)一管理;提供XML標簽,支持編寫動態(tài)SQL語句,并

可重用

?與JDBC相比,減少了50%以上的代碼量,消除了JDBC大量冗余的代碼,不需要手動開關(guān)連接

?很好的與各種數(shù)據(jù)庫兼容(因為MyBatis使用JDBC來連接數(shù)據(jù)庫,所以只要JDBC支持的數(shù)據(jù)庫

MyBatis都支持)

?提供映射標簽,支持對象與數(shù)據(jù)庫的ORM字段關(guān)系映射;提供對象關(guān)系映射標簽,支持對象關(guān)系

組件維護

?能夠與Spring很好的集成

缺點

?SQL語句的編寫工作量較大,尤其當(dāng)字段多、關(guān)聯(lián)表多時,對開發(fā)人員編寫SQL語句的功底有一定

要求

?SQL語句依賴于數(shù)據(jù)庫,導(dǎo)致數(shù)據(jù)庫移植性差,不能隨意更換數(shù)據(jù)庫

3.Hibernate和MyBatis的區(qū)別

相同點

?都是對jdbc的封裝,都是持久層的框架,都用于da。層的開發(fā)。

不同點

?映射關(guān)系

。MyBatis是一個半自動映射的框架,配置Java對象與sql語句執(zhí)行結(jié)果的對應(yīng)關(guān)系,多表關(guān)聯(lián)

關(guān)系配置簡單

。Hibernate是一個全表映射的框架,配置lava對象與數(shù)據(jù)庫表的對應(yīng)關(guān)系,多表關(guān)聯(lián)關(guān)系配

置復(fù)雜

SQL優(yōu)化和移植性

?Hibernate對SQL語句封裝,提供了日志、緩存、級聯(lián)(級聯(lián)比MyBatis強大)等特性,此外還提

供HQL(HibernateQueryLanguage)操作數(shù)據(jù)庫,數(shù)據(jù)庫無關(guān)性支持好,但會多消耗性能。如

果項目需要支持多種數(shù)據(jù)庫,代碼開發(fā)量少,但SQL語句優(yōu)化困難。

?MyBatis需要手動編寫SQL,支持動態(tài)SQL、處理列表、動態(tài)生成表名、支持存儲過程。開發(fā)工

作量相對大些。直接使用SQL語句操作數(shù)據(jù)庫,不支持數(shù)據(jù)庫無關(guān)性,但sql語句優(yōu)化容易。

ORM是什么

?ORM(ObjectRelationalMapping),對象關(guān)系映射,是一種為了解決關(guān)系型數(shù)據(jù)庫數(shù)據(jù)與簡單

Java對象(POJO)的映射關(guān)系的技術(shù)。簡單的說,ORM是通過使用描述對象和數(shù)據(jù)庫之間映射的

元數(shù)據(jù),將程序中的對象自動持久化到關(guān)系型數(shù)據(jù)庫中。

4.為什么說Mybatis是半自動。RM映射工具?它與全自動的區(qū)別在

哪里?

?Hibernate屬于全自動ORM映射工具,使用Hibernate查詢關(guān)聯(lián)對象或者關(guān)聯(lián)集合對象時,可以根

據(jù)對象關(guān)系模型直接獲取,所以它是全自動的.

?而Mybatis在查詢關(guān)聯(lián)對象或關(guān)聯(lián)集合對象時,需要手動編寫sql來完成,所以,稱之為半自動

ORM映射工具。

5.傳統(tǒng)JDBC開發(fā)存在什么問題?

?頻繁創(chuàng)建數(shù)據(jù)庫連接對象、釋放,容易造成系統(tǒng)資源浪費,影響系統(tǒng)性能??梢允褂眠B接池解決這

個問題。但是使用jdbc需要自己實現(xiàn)連接池。

?sql語句定義、參數(shù)設(shè)置、結(jié)果集處理存在硬編碼。實際項目中sql語句變化的可能性較大,一旦發(fā)

生變化,需要修改java代碼,系統(tǒng)需要重新編譯,重新發(fā)布。不好維護。

?使用preparedStatement向占有位符號傳參數(shù)存在硬編碼,因為sq語句的where條件不一定,可

能多也可能少,修改sql還要修改代碼,系統(tǒng)不易維護。

?結(jié)果集處理存在重復(fù)代碼,處理麻煩。如果可以映射成ava對象會比較方便。

6.JDBC編程有哪些不足之處,MyBatis是如何解決的?

?1、數(shù)據(jù)庫鏈接創(chuàng)建、釋放頻繁造成系統(tǒng)資源浪費從而影響系統(tǒng)性能,如果使用數(shù)據(jù)庫連接池可解

決此問題。

。解決:在mybatis-config.xml中配置數(shù)據(jù)鏈接池,使用連接池管理數(shù)據(jù)庫連接.

?2、Sql語句寫在代碼中造成代碼不易維護,實際應(yīng)用sql變化的可能較大,sql變動需要改變java代

IB.-

。解決:將Sql語句配置在XXXXm叩per.xml文件中與ava代碼分離。

?3、向sql語句傳參數(shù)麻煩,因為sql語句的where條件不一定,可能多也可能少,占位符需要和參

數(shù)-對應(yīng)。

。解決:Mybatis自動將java對象映射至sq語句。

?4、對結(jié)果集解析麻煩,sql變化導(dǎo)致解析代碼變化,且解析前需要遍歷,如果能將數(shù)據(jù)庫記錄封裝

成poj。對象解析比較方便.

。解決:Mybatis自動將sq執(zhí)行結(jié)果映射至java對象。

7.MyBatis和Hibernate的適用場景?

?MyBatis專注于SQL本身,是一個足夠靈活的DA。層解決方案。

?對性能的要求很高,或者需求變化較多的項目,如互聯(lián)網(wǎng)項目,MyBatis將是不錯的選擇。

開發(fā)難易程度和學(xué)習(xí)成本

?Hibernate是重量級框架,學(xué)習(xí)使用門檻高,適合于需求相對穩(wěn)定,中小型的項目,比如:辦公自

動化系統(tǒng)

?MyBatis是輕量級框架,學(xué)習(xí)使用門檻低,適合于需求變化頻繁,大型的項目,比如:互聯(lián)網(wǎng)電子

商務(wù)系統(tǒng)

總結(jié)

?MyBatis是一個小巧、方便、高效、簡單、直接、半自動化的持久層框架,

?Hibernate是一個強大、方便、高效、復(fù)雜、間接、全自動化的持久層框架。

MyBatis的架構(gòu)

8.MyBatis編程步驟是什么樣的?

?1、創(chuàng)建SqISessionFactory

?2、通過SqISessionFactory創(chuàng)建SqISession

?3、通過sqlsession執(zhí)行數(shù)據(jù)庫操作

?4、調(diào)用mit。提交事務(wù)

?5、調(diào)用session.close。關(guān)閉會話

9.請說說MyBatis的工作原理

?在學(xué)習(xí)MyBatis程序之前,需要了解一下MyBatis工作原理,以便于理解程序。MyBatis的工作

原理如下圖

1.讀取MyBatis配置文件:mybatis-config.xml為MyBatis的全局配置文件,配置了MyBatis的運

行環(huán)境等信息,例如數(shù)據(jù)庫連接信息。

2.加載映射文件。映射文件即SQL映射文件,該文件中配置了操作數(shù)據(jù)庫的SQL語句,需要在

MyBatis配置文件mybatis-config.xml中加載。mybatis-config.xml文件可以加載多個映射文

件,每個文件對應(yīng)數(shù)據(jù)庫中的一張表。

3.構(gòu)造會話工廠:通過MyBatis的環(huán)境等配置信息構(gòu)建會話工廠SqlSessionFactory0

4.創(chuàng)建會話對象:由會話工廠創(chuàng)建SqISession對象,該對象中包含了執(zhí)行SQL語句的所有方法。

5.Executor執(zhí)行器:MyBatis底層定義了一個Executor接口來操作數(shù)據(jù)庫,它將根據(jù)SqISession

傳遞的參數(shù)動態(tài)地生成需要執(zhí)行的SQL語句,同時負責(zé)查詢緩存的維護.

6.MappedStatement對象:在Executor接口的執(zhí)行方法中有一個MappedStatement類型的參

數(shù),該參數(shù)是對映射信息的封裝,用于存儲要映射的SQL語句的id、參數(shù)等信息。

7.輸入?yún)?shù)映射:輸入?yún)?shù)類型可以是Map、List等集合類型,也可以是基本數(shù)據(jù)類型和POJO類

型。輸入?yún)?shù)映射過程類似于JDBC對preparedStatement對象設(shè)置參數(shù)的過程。

8.輸出結(jié)果映射:輸出結(jié)果類型可以是Map、List等集合類型,也可以是基本數(shù)據(jù)類型和POJO類

型。輸出結(jié)果映射過程類似于JDBC對結(jié)果集的解析過程.

10.MyBatis的功能架構(gòu)是怎樣的

數(shù)據(jù)喈加接口數(shù)據(jù)■除接口數(shù)據(jù)查詢接口國置信.巨維護接口

按口調(diào)用方式基于StatementID擅于Mapper接口

SQI>tfr結(jié)泉處理和映射

數(shù)

揖SQL電句配我

語句解析

理SQL

,

SQL麗艇訊■

(ParameterHondler)(SqISource)(Executor)(ResultSetHardier)

語句配取方式

架SQL基于XML配置基于注解

9

g

事務(wù)管理連接池管理緩存機制

基于XML配置方式基于JavaAPI方式

?我們把Mybatis的功能架構(gòu)分為三層:

。API接口層:提供給外部使用的接口API,開發(fā)人員通過這些本地API來操縱數(shù)據(jù)庫。接口層一

接收到調(diào)用請求就會調(diào)用數(shù)據(jù)處理層來完成具體的數(shù)據(jù)處理。

。數(shù)據(jù)處理層:負責(zé)具體的SQL查找、SQL解析、SQL執(zhí)行和執(zhí)行結(jié)果映射處理等。它主要的目

的是根據(jù)調(diào)用的請求完成一次數(shù)據(jù)庫操作。

。基礎(chǔ)支撐層:負責(zé)最基礎(chǔ)的功能支撐,包括連接管理、事務(wù)管理、配置加載和緩存處理,這

些都是共用的東西,將他們抽取出來作為最基礎(chǔ)的組件。為上層的數(shù)據(jù)處理層提供最基礎(chǔ)的

支撐。

11.MyBatis的框架架構(gòu)設(shè)計是怎么樣的

?這張圖從上往下看。MyBatis的初始化,會從mybatis-config.xml配置文件,解析構(gòu)造成

Configuration這個類,就是圖中的紅框。

1.加載配置:配置來源于兩個地方,一處是配置文件,一處是Java代碼的注解,將SQL的配置信息加

載成為一個個M叩pedStatement對象(包括了傳入?yún)?shù)映射配置、執(zhí)行的SQL語句、結(jié)果映射配

置),存儲在內(nèi)存中。

2.SQL解析:當(dāng)AP接口層接收到調(diào)用請求時,會接收到傳入SQL的ID和傳入對象(可以是Map、

JavaBean或者基本數(shù)據(jù)類型),Mybatis會根據(jù)SQL的ID找到對應(yīng)的MappedStatement,然后根

據(jù)傳入?yún)?shù)對象對M叩pedStatement進行解析,解析后可以得到最終要執(zhí)行的SQL語句和參數(shù)。

3.SQL執(zhí)行:將最終得到的SQL和參數(shù)拿到數(shù)據(jù)庫進行執(zhí)行,得到操作數(shù)據(jù)庫的結(jié)果。

4.結(jié)果映射:將操作數(shù)據(jù)庫的結(jié)果按照映射的配置進行轉(zhuǎn)換,可以轉(zhuǎn)換成HashMap、JavaBean或者

基本數(shù)據(jù)類型,并將最終結(jié)果返回。

12.什么是DBMS

?DBMS:數(shù)據(jù)庫管理系統(tǒng)(databasemanagementsystem)是一種操縱和管理數(shù)據(jù)庫的大型軟件,

用于建立、使用和維護數(shù)zd據(jù)庫,簡稱dbms。它對數(shù)據(jù)庫進行統(tǒng)一的管理和控制,以保證數(shù)據(jù)庫

的安全性和完整性。用戶通過dbms訪問數(shù)據(jù)庫中的數(shù)據(jù),數(shù)據(jù)庫管理員也通過dbms進行數(shù)據(jù)庫

的維護工作。它可使多個應(yīng)用程序和用戶用不同的方法在同時版或不同時刻去建立,修改和詢問數(shù)

據(jù)庫。DBMS提供數(shù)據(jù)定義語言DDL(DataDefinitionLanguage)與數(shù)據(jù)操作語言DML(Data

ManipulationLanguage),供用戶定義數(shù)據(jù)庫的模式結(jié)構(gòu)與權(quán)限約束,實現(xiàn)對數(shù)據(jù)的追加權(quán)、刪

除等操作。

13.為什么需要預(yù)編譯

?定義:

。SQL預(yù)編譯指的是數(shù)據(jù)庫驅(qū)動在發(fā)送SQL語句和參數(shù)給DBMS之前對SQL語句進行編譯,

這樣DBMS執(zhí)行SQL時,就不需要重新編譯。

?為什么需要預(yù)編譯

。JDBC中使用對象PreparedStatement來抽象預(yù)編譯語句,使用預(yù)編譯。預(yù)編譯階段可以優(yōu)

化SQL的執(zhí)行。預(yù)編譯之后的SQL多數(shù)情況下可以直接執(zhí)行,DBMS不需要再次編譯,越

復(fù)雜的SQL,編譯的復(fù)雜度將越大,預(yù)編譯階段可以合并多次操作為一個操作。同時預(yù)編譯

語句對象可以重復(fù)利用。把一個SQL預(yù)編譯后產(chǎn)生的PreparedStatement對象緩存下來,

下次對于同一>SQL,可以直接使用這個緩存的PreparedState對象。Mybatis默認情況下,

將對所有的SQL進行預(yù)編譯。

。還有一個重要的原因,復(fù)制SQL注入

14.Mybatis都有哪些Executor執(zhí)行器?它們之間的區(qū)別是什么?

?Mybatis有三種基本的Executor執(zhí)行器,SimpleExecutor、ReuseExecutor,BatchExecutor.

?SimpleExecutor:每執(zhí)行一次update或select,就開啟一個Statement對象,用完立刻關(guān)閉

Statement對象。

?ReuseExecutor:執(zhí)行update或select,以sql作為key查找Statement對象,存在就使用,不存

在就創(chuàng)建,用完后,不關(guān)閉Statement對象,而是放置于Map<String,Statement>內(nèi),供下一次

使用。簡言之,就是重復(fù)使用Statement對象。

?BatchExecutor:執(zhí)行update(沒有select,JDBC批處理不支持select),將所有sql都添加到批

處理中(addBatch。),等待統(tǒng)一執(zhí)行(executeBatchQ),它緩存了多個Statement對象,每個

Statement對象都是addBatch()完畢后,等待逐一執(zhí)行executeBatch。批處理。與JDBC批處理相

同。

作用范圍:Executor的這些特點,都嚴格限制在Sqlsession生命周期范圍內(nèi)。

15.Mybatis中如何指定使用哪一種Executor執(zhí)行器?

?在Mybatis配置文件中,在設(shè)置(settings)可以指定默認的ExecutorType執(zhí)行器類型,也可以手

動給DefaultSqISessionFactory的創(chuàng)建SqISession的方法傳遞ExecutorType類型參數(shù),如

SqISessionopenSession(ExecutorTypeexecType),

?配置默認的執(zhí)行器。SIMPLE就是普通的執(zhí)行器;REUSE執(zhí)行器會重用預(yù)處理語句(prepared

statements);BATCH執(zhí)行器將重用語句并執(zhí)行批量更新。

16.Mybatis是否支持延遲加載?如果支持,它的實現(xiàn)原理是什么?

?Mybatis僅支持association關(guān)聯(lián)對象和collection關(guān)聯(lián)集合對象的延遲加載,association指的就是

一對一,collection指的就是一對多查詢。在Mybatis配置文件中,可以配置是否啟用延遲加載

lazyLoadingEnabled=true|false.

?它的原理是,使用CGLIB創(chuàng)建目標對象的代理對象,當(dāng)調(diào)用目標方法時,進入攔截器方法,比如調(diào)

用a.getB().getName(),攔截器invoke。方法發(fā)現(xiàn)a.getB()是null值,那么就會單獨發(fā)送事先保存好

的查詢關(guān)聯(lián)B對象的sql,把B查詢上來,然后調(diào)用a.setB(b),于是a的對象b屬性就有值了,接著完

成a.getB().getName()方法的調(diào)用。這就是延遲加載的基本原理。

?當(dāng)然了,不光是Mybatis,幾乎所有的包括Hibernate,支持延遲加載的原理都是一樣的。

映射器

17.#{}和${}的區(qū)別

?#{}是占位符,預(yù)編譯處理;${}是拼接符,字符串替換,沒有預(yù)編譯處理.

?Mybatis在處理#{}時,#{}傳入?yún)?shù)是以字符串傳入,會將SQL中的#{}替換為?號,調(diào)用

PreparedStatement的set方法來賦值。

?狙}可以有效的防止SQL注入,提高系統(tǒng)安全性;${}不能防止SQL注入

?#{}的變量替換是在DBMS中;${}的變量替換是在DBMS外

18.模糊直詢like語句該怎么寫

?1%${question}%'可能弓|起SQL注入,不推薦

?2"%"#{questiog"%"注意:因為#{...}解析成sql語句時候,會在變量外側(cè)自動加單引號'',所以

這里%需要使用雙引號”",不能使用單引號'',不然會查不到任何結(jié)果。

?3CONCAT(,%',^question);%,)使用CONCATO函數(shù),(推薦)

?4使用bind標簽(不推薦)

<select1d="listliserLikeusername"resultType="com.jourwon.pojo.User">

  <bindname=,,pattern"value="+username+/>

  seiectid,sex,age,username,passwordfrompersonwhereusernameLIKE

#{pattern}

</select>

19.在mapper中如何傳遞多個參數(shù)

方法1:順序傳參法

publicUserselectUser(Stringname,intdeptld);

<selectid="selectuser"resultMap="userResultMap">

seiect*fromuser

whereuser_name=#{0}anddept_id=#{1}

</select>

?#{}里面的數(shù)字代表傳入?yún)?shù)的M頁序。

?這種方法不建議使用,sql層表達不直觀,且一旦JI質(zhì)序調(diào)整容易出錯。

方法2:@Param注解傳參法

publicUserseiectUser(@Param("userName")Stringname,int?Param(,'deptld,')

deptld);

<selectid="selectuser"resultMap="userResultMap">

seiect*fromuser

whereuser_name=#{userName}anddept_id=#{deptld}

</select>

?#{}里面的名稱對應(yīng)的是注解@Param括號里面修飾的名稱。

?這種方法在參數(shù)不多的情況還是比較直觀的,(推薦使用)。

方法3:Map傳參法

publicUserselectuser(Map<String,Object>params);

<selectid="selectusernparameterType="java.util.Map"resultMap="UserResultMap">

seiect*fromuser

where=#{userName}anddept_id=#{deptld}

</select>

?#{}里面的名稱對應(yīng)的是Map里面的key名稱。

?這種方法適合傳遞多個參數(shù),且參數(shù)易變能靈活傳遞的情況。(推薦使用)。

方法4:JavaBean傳參法

publicUserselectuserfuseruser);

<selectid="selectliser"parameterType="com.jourwon.pojo.User'1

resultMap="userResultMapH>

select*fromuser

whereuser_name=#{userName}anddept_id=#{deptld)

</select>

?#{}里面的名稱對應(yīng)的是User類里面的成員屬性。

?這種方法直觀,需要建一個實體類,擴展不容易,需要加屬性,但代碼可讀性強,業(yè)務(wù)邏輯處理方

便,推薦使用.(推薦使用)。

20.Mybatis如何執(zhí)行批量操作

?使用foreach標簽

?foreach的主要用在構(gòu)建in條件中,它可以在SQL語句中進行迭代一個集合。foreach標簽的屬性主

要有item,index,collection,open,separator,close.

。item表示集合中每一個元素進行迭代時的別名,隨便起的變量名;

。index指定一個名字,用于表示在迭代過程中,每次迭代到的位置,不常用;

。open表示該語句以什么開始,常用"(";

。separator表示在每次進行迭代之間以什么符號作為分隔符,常用

。close表示以什么結(jié)束,常用

?在使用foreach的時候最關(guān)鍵的也是最容易出錯的就是collection屬性,該屬性是必須指定的,但是

在不同情況下,該屬性的值是不一樣的,主要有一下3種情況:

1.如果傳入的是單參數(shù)且參數(shù)類型是一個List的時候,collection屬性值為list

2.如果傳入的是單參數(shù)且參數(shù)類型是一個array數(shù)組的時候,collection的屬性值為array

3.如果傳入的參數(shù)是多個的時候,我們就需要把它們封裝成一個M叩了,當(dāng)然單參數(shù)也可以封

裝成map,實際上如果你在傳入?yún)?shù)的時候,在MyBatis里面也是會把它封裝成一個M叩

的,

map的key就是參數(shù)名,所以這個時候collection屬性值就是傳入的List或array對象在自己封

裝的m叩里面的key

?具體用法如下:

<!-批量保存(foreach插入多條數(shù)據(jù)兩種方法)

intaddEmpsBatch(?ParamC'emps")List<Employee>emps);-->

<!--MySQL下批量保存,可以foreach遍歷mysql支持values。,(),()語法〃推薦使用

<insertid="addEmpsBatch">

INSERTINTOemp(ename,gender,emai1,did)

VALUES

<foreachcol1ection="emps"item=,'emp"separator=",">

(#{emp.eName},#{emp.gender},#{emp.emai1},#{emp.dept.id})

</foreach>

</insert>

<!—這種方式需要數(shù)據(jù)庫連接屬性al1owMutiQueries=true的支持

如jdbc.url=jdbc:mysql://localhost:3306/mybatis?al1owMultiQueries=true-->

<insertid="addEmpsBatch">

<foreachcollection=,,empsHitem=^'emp,^separator=n;">

INSERTINTOemp(ename,gender,emai1,did)

VALUES(#{emp.eName},#{emp.gender},#{emp.emai1},#{emp.dept.id})

</foreach>

</insert>

?使用ExecutorType.BATCH

°Mybatis內(nèi)置的ExecutorType有3種,默認為simple,該模式下它為每個語句的執(zhí)行創(chuàng)建一個

新的預(yù)處理語句,單條提交sql;而batch模式重復(fù)使用已經(jīng)預(yù)處理的語句,并且批量執(zhí)行所

有更新語句,顯然batch性能將更優(yōu);但batch模式也有自己的問題,比如在Insert操作時,

在事務(wù)沒有提交之前,是沒有辦法獲取到自增的id,這在某型情形下是不符合業(yè)務(wù)要求的

。具體用法如下:

//批量保存方法測試

?Test

publicvoidtestBatch()throwslOException{

SqlSessionFactorysqlSessionFactory=getSqlSessionFactoryO;

//可以執(zhí)行批量操作的sqlSession

SqlSessionopensession=

sqlSessionFactory.opensession(ExecutorType.BATCH);

//批量保存執(zhí)行前時間

longstart=System.currentTimeMillisO;

try{

EmployeeMappermapper=

openSession.getMapper(EmployeeMapper.class);

for(inti=0;i<1000;i++){

mapper.addEmp(new

Employee(UUID.randomUUlD().tostring().substring(0,5),"b","1"));

)

openSmit();

longend=System.currentTimeMi11is();

//批量保存執(zhí)行后的時間

System.out.printin("執(zhí)行時長”+(end-start));

//批量預(yù)編譯sql一次==》設(shè)置參數(shù)==》10000次==》執(zhí)行1次677

//非批量(預(yù)編譯=設(shè)置參數(shù)=執(zhí)行)==》10000次1121

}finally{

openSession.closeO;

)

)

omappe壞口mapper.xml如下

publicinterfaceEmployeeMapper{

//批量保存員工

LongaddEmp(Employeeemployee);

)

<mappernamespace="com.jourwon.mapper.EmployeeMapper"

<!--批量保存員工一>

<insertid=,,addEmpn>

insertintoemployee(lastName,email,gender)

values(#{1astName},#{emai1},#{gender})

</insert>

</mapper>

21.如何獲取生成的主健

?新增標簽中添加:keyProperty="ID"即可

<insertid="insert"useGeneratedKeys="true"keyProperty=',userld">

insertintouser(

user_name,user_password,create_time)

values(#{userName},#{userPassword},#{createTime,jdbcType=

TIMESTAMP})

</insert>

intid=mapper,insert(record)

22.當(dāng)實體類中的屬性名和表中的字段名不一樣,怎么辦

?第1種:通過在查詢的SQL語句中定義字段名的別名,讓字段名的別名和實體類的屬性名一致。

<selectid="getorder"parameterType="int"

resultType="com.jourwon.pojo.Order">

selectorder_idid,order_noorderno,order_pricepriceformorders

whereorder_id=#{id};

</select>

?第2種:通過vresultMap>來映射字段名和實體類屬性名的——對應(yīng)的關(guān)系。

<select1d="getOrder"parameterType="int"resultMap="orderResultMap',>

select*fromorderswhereorder_id=#{id}

</select>

<resultMaptype="com.jourwon.pojo.Order"id="orderResultMap">

v!-用id屬性來映射主鍵字段。

<idproperty="id"column=Horder_id">

<!-用result屬性來映射非主鍵字段,property為實體類屬性名,column為數(shù)據(jù)庫表中的屬

性-〉

<resultproperty="orderno“column="order_no"/>

<resultproperty="price"column="order_price"/>

</reslutMap>

23.Mapper編寫有哪幾種方式?

?第一種:接口實現(xiàn)類繼承SqISessionDaoSupport:使用此種方法需要編寫mapper接口,

mapper接口實現(xiàn)類、mapper.xml文件。

1.在sqlMapConfig.xml中酉己置m叩per.xml的位置

<mappers>

<mapperresource="mapper.xml文件的地址”/>

<mapperresource="mapper.xml文件的地址”/>

</mappers>

2.定義m叩per接口

3.實現(xiàn)類集成SqISessionDaoSupport

mapper方法中可以this.getSqlSession()進行數(shù)據(jù)增刪改查。

4.spring配置

<beanid=""class="mapper接口的實現(xiàn)“〉

<propertyname="sqlSessionFactory"

ref="sqlSessionFactory"x/property>

</bean>

?第二種:使用org.mybatis.spring.mapper.MapperFactoryBean:

1.在sqlMapConfig.xml中酉己置m叩per.xml的位置,如果m叩per.xml和mappre接口的名

稱相同且在同一個目錄,這里可以不用配置

2.定義m叩per接口:

<mappers>

<mapperresource="mapper.xml文件的地址”/>

<mapperresource="mapper.xml文件的地址”/>

</mappers>

3.mapper.xml中的namespace為mapper接口的地址

4.mapper接口中的方法名和mapper.xml中的定義的statement的id保持一致

5.Spring中定義

<beanid=""class='*org.mybatis.spring.mapper.MapperFactoryBean">

<propertyname="mapperlnterface"value="mapper接口地址”/>

<propertyname="sqlSessionFactory"ref="sqlSessionFactory"/>

</bean>

?第三種:使用m叩per掃描器:

1.m叩per.xml文件編寫:

mapper.xml中的namespace為mapper接口的地址;

mapper接口中的方法名和mapper.xml中的定義的statement的id保持一致;

如果將mapper.xml和mapper接口的名稱保持一致則不用在sqlMapConfig.xrrd中進行配置。

2.定義mapper接口:

注意m叩per.xml的文件名和mapper的接口名稱保持一致,且放在同一個目錄

3.配置mapper掃描器:

<beanclass="org.mybatis.spring.mapper.MapperScannerConfigurer">

<propertyname=,,basePackagenvalue="mapper接口包地址

nx/property>

<propertyname="sqlSessionFactoryBeanName"

value=nsqlSessionFactory"/>

</bean>

4.使用掃描器后從spring容器中獲取mapper的實現(xiàn)對象。

24.什么是MyBatis的接口綁定?有哪些實現(xiàn)方式?

?接口綁定,就是在MyBatis中任意定義接口,然后把接口里面的方法和SQL語句綁定,我們直接調(diào)

用接口方法就可以,這樣比起原來了SqISession提供的方法我們可以有更加靈活的選擇和設(shè)置。

?接口綁定有兩種實現(xiàn)方式

1.通過注解綁定,就是在接口的方法上面加上@Select、@Update等注解,里面包含Sql語句來

綁定;

2.通過xml里面寫SQL來綁定,在這種情況下,要指定xml映射文件里面的namespace必須為

接口的全路徑名。當(dāng)Sql語句比較簡單時候,用注解綁定,當(dāng)SQL語句比較復(fù)雜時候,用xml

綁定,一般用xml綁定的比較多。

25.使用MyBatis的mapper接口調(diào)用時有哪些要求?

1.M叩per接口方法名和mapper.xml中定義的每個sql的id相同。

2.Mapper接口方法的輸入?yún)?shù)類型和m叩per.xml中定義的每個sql的parameterType的類型相

同。

3.Mapper接口方法的輸出參數(shù)類型和m叩per.xml中定義的每個sql的resultType的類型相同。

4.M叩per.xml文件中的namespace即是mapper接口的類路徑。

26.這個Da。接口的工作原理是什么?Da。接口里的方法,參數(shù)不同

時,方法能重載嗎

?Da。接口的工作原理是JDK動態(tài)代理,Mybatis運行時會使用JDK動態(tài)代理為Da。接口生成代理

proxy對象,代理對象proxy會攔截接口方法,轉(zhuǎn)而執(zhí)行MappedStatement所代表的sql,然后將

sq件丸行結(jié)果返回。

?Da。接口里的方法,是不能重載的,因為是全限名+方法名的保存和尋找策略。

27.Mybatis的Xml映射文件中,不同的Xml映射文件,id是否可以

重復(fù)?

,不同的Xml映射文件,如果配置了namespace,那么id可以重復(fù);如果沒有配置namespace,那

么id不能重復(fù);畢竟namespace不是必須的,只是最佳實踐而已。

?原因就是namespace+id是作為Map<String,MappedStatement>的key使用的,如果沒有

namespace,就剩下id,那么,id重復(fù)會導(dǎo)致數(shù)據(jù)互相覆蓋。有了namespace,自然id就可以重

復(fù),namespace不同,namespace+id自然也就不同。

28.簡述Mybatis的Xml映射文件和Mybatis內(nèi)部數(shù)據(jù)結(jié)構(gòu)之間的映

射關(guān)系?

?答:Mybatis將所有Xml配置信息都封裝到All-In-One重量級對象Configuration內(nèi)部。在Xml映射

文件中,<parameterMap>標簽會被解析為ParameterMap對象,其每個子元素會被解析為

ParameterMapping對象。<resultMap>標簽會被解析為ResultM叩對象,其每個子元素會被解

析為ResultM叩ping對象。每一個(select〉、(insert〉、〈update〉、〈delete〉標簽均會被

解析為MappedStatement對象,標簽內(nèi)的sq噲被解析為BoundSql對象。

29.Mybatis是如何將sql執(zhí)行結(jié)果封裝為目標對象并返回的?都有哪

些映射形式?

?第一種是使用<resultMap>標簽,逐一定義列名和對象屬性名之間的映射關(guān)系。

?第二種是使用sql列的別名功能,將列別名書寫為對象屬性名,比如T_NAMEASNAME,對象屬性

名一般是name,小寫,但是列名不區(qū)分大小寫,Mybatis會忽略列名大小寫,智能找到與之對應(yīng)

對象屬性名,你甚至可以寫成T_NAMEASNaMe,Mybatis一樣可以正常工作。

有了列名與屬性名的映射關(guān)系后,Mybatis通過反射創(chuàng)建對象,同時使用反射給對象的屬性逐一賦值并返回,那

些找不到映射關(guān)系的屬性,是無法完成賦值的。

30.Xml映射文件中,除了常見的select|insert|updae|delete標

簽之外,還有哪些標簽?

?還有很多其他的標簽,<resultMap>x<parameterMap><sql>x〈include〉、

<selectKey>,加上動態(tài)sql的9個標簽,

trim|where|set|foreach|if|choose|when|otherwise|bind^,其中<sql>為sql片段標簽,通

過〈include〉標簽引入sql片段,<selectKey>為不支持自增的主鍵生成策略標簽。

31.Mybatis映射文件中,如果A標簽通過include引用了B標簽的內(nèi)

容,請問,B標簽?zāi)芊穸x在A標簽的后面,還是說必須定義在A標簽

的前面?

?雖然Mybatis解析Xml映射文件是按照順序解析的,但是,被引用的B標簽依然可以定義在任何地

方,Mybatis都可以正確

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論