更新時間:2022-12-14 16:44:20 來源:動力節(jié)點 瀏覽1424次
mybatis是一個優(yōu)秀的基于Java持久層框架,內(nèi)部它是封裝了JDBC,讓開發(fā)者不用過多的關(guān)心什么創(chuàng)建連接、加載驅(qū)動啊等等。如今大企業(yè)越來越多用mybatis,為什么它越來越被廣泛應(yīng)用,以前流行的SSH框架開發(fā),而現(xiàn)在完全勢向于SSM框架開發(fā),今天講解mybatis框架常見面試題。
● 談一談你對ORM的理解?
對象關(guān)系映射(Object Relational Mapping,簡稱ORM)是一種為了解決面向?qū)ο笈c關(guān)系數(shù)據(jù)庫存在的互不匹配的現(xiàn)象的技術(shù)。 簡單的說,ORM是通過使用描述對象和數(shù)據(jù)庫之間映射的元數(shù)據(jù),將java程序中的對象自動持久化到關(guān)系數(shù)據(jù)庫中。當(dāng)然反過來也是可以的,例如將數(shù)據(jù)庫表當(dāng)中的記錄查詢出來,然后映射為Java程序中的Java對象。
● 在MyBatis中$和#的區(qū)別?
$進(jìn)行sql語句的拼接,#是專門給sql語句傳值的。$就是JDBC當(dāng)中的Statement,#就是JDBC當(dāng)中的PreparedStatement。$的這種方式使用時需要特別注意sql注入問題。
● 你對MyBatis的一級緩存和二級緩存有了解嗎,說一下?
Mybatis對緩存提供支持,但是在沒有配置的默認(rèn)情況下,它只開啟一級緩存,一級緩存只是相對于同一個SqlSession而言。所以在參數(shù)SQL完全一樣的情況下,我們使用同一個SqlSession對象調(diào)用一個Mapper方法,往往只執(zhí)行一次SQL,因為使用SqlSession第一次查詢后,MyBatis會將其放在緩存中,以后再查詢的時候,如果沒有聲明需要刷新,并且緩存沒有超時的情況下,SqlSession都會取出當(dāng)前緩存的數(shù)據(jù),而不會再次發(fā)送SQL到數(shù)據(jù)庫。
MyBatis的二級緩存是Application級別的緩存,它可以提高對數(shù)據(jù)庫查詢的效率,以提高應(yīng)用的性能。SqlSessionFactory層面上的二級緩存默認(rèn)是不開啟的,二級緩存的開啟需要進(jìn)行配置,實現(xiàn)二級緩存的時候,MyBatis要求返回的POJO必須是可序列化的。 也就是要求實現(xiàn)Serializable接口,配置方法很簡單,只需要在映射XML文件配置就可以開啟緩存了。
由于我們在實際的開發(fā)中目前都會使用第三方的緩存技術(shù),例如Redis,所以MyBatis這塊的二級緩存沒有太多的了解。
● MyBatis的parameterType怎么理解的?
parameterType屬性用來指定參數(shù)類型,parameterType屬性是專門用來給sql語句占位符#{}傳值的,底層原理使用了反射機(jī)制,#{}的大括號當(dāng)中需要提供實體類的屬性名,底層使用屬性名拼接get方法來獲取屬性值,將屬性值傳遞給sql語句。
● MyBatis的resultType是怎么理解的?
resultType用來指定結(jié)果集封裝的數(shù)據(jù)類型,當(dāng)一個select語句查詢之后得到結(jié)果集,結(jié)果集的列名需要和java實體類的屬性名一致,不一致的可以使用as關(guān)鍵字給列起別名,拿著列名拼接set方法,通過反射機(jī)制調(diào)用set方法給結(jié)果集對象的屬性賦值。
● MyBatis中resultMap用過嗎,它是干什么的?
在MyBatis當(dāng)中,查詢結(jié)果集被封裝為Java對象,可以通過resultType,也可以通過resultMap,在resultMap當(dāng)中描述了數(shù)據(jù)庫表的列與Java對象的屬性之間的對應(yīng)關(guān)系。在映射關(guān)系中,還可以通過resultMap的typeHandler設(shè)置實現(xiàn)查詢結(jié)果值的類型轉(zhuǎn)換。另外,最重要的是通過resultMap的子標(biāo)簽比如、等,可以實現(xiàn)一對一、一對多等的映射。
● MyBatis底層實現(xiàn)原理?
MyBatis是一個持久層框架,實現(xiàn)了ORM思想,可以將查詢的結(jié)果集自動轉(zhuǎn)換成Java對象,也可以將Java對象轉(zhuǎn)換成一條數(shù)據(jù)插入到數(shù)據(jù)庫表當(dāng)中。
那么,查詢結(jié)果集是如何自動轉(zhuǎn)換成Java對象的呢?實際上這里使用了反射機(jī)制,在配置文件中假設(shè)編寫了一條select語句,查詢之后,列名與屬性名要一一對應(yīng)(不對應(yīng)的可以采用給列起別名),然后每個列名前添加“set”,通過反射機(jī)制獲取set方法,然后再通過反射機(jī)制的method.invoke()來調(diào)用這個set方法,給Java對象的屬性賦值。這樣就完成了對象的封裝。
另外,Java對象是如何轉(zhuǎn)換成一條記錄插入到數(shù)據(jù)庫的呢?假設(shè)在配置文件中編寫了一條insert語句,那么這條語句需要的值從哪里來呢,在mybatis的mapper配置中有parameterType屬性,該屬性是專門給sql語句占位符傳值的,其實這里也是使用了反射機(jī)制,其中sql語句的占位符采用#{},其中大括號當(dāng)中需要提供java對象的屬性名,該屬性名和get進(jìn)行拼接得到get方法名,然后通過反射機(jī)制獲取該get方法,再通過method.invoke()來調(diào)用這個get方法,這樣就可以獲取到對應(yīng)的屬性值,然后傳入了。
其實MyBatis設(shè)計最牛的地方當(dāng)然是采用JDK動態(tài)代理的方式生成DAO接口的實現(xiàn)類了。其中DAO接口中的每一個方法名對應(yīng)sql語句的id。DAO接口中的方法不允許重載,因為id是不允許重復(fù)的。以上大概就是我了解的MyBatis實現(xiàn)原理。
以上就是“被問到很多次的mybatis面試題及答案”,你能回答上來嗎?如果想要了解更多的Java面試題相關(guān)內(nèi)容,可以關(guān)注動力節(jié)點Java官網(wǎng)。
相關(guān)閱讀
初級 202925
初級 203221
初級 202629
初級 203743