一、MyBatis篇1、什麼是MyBatis
(1)Mybatis是一個半ORM(物件關係對映)框架,它內部封裝了JDBC,開發時只需要關注SQL語句 本身,不需要花費精力去處理載入驅動、建立連線、建立statement等繁雜的過程。程式設計師直接編寫原 生態sql,可以嚴格控制sql執行效能,靈活度高。
(2)MyBatis 可以使用 XML 或註解來配置和對映原生資訊,將 POJO對映成資料庫中的記錄,避免了 幾乎所有的 JDBC 程式碼和手動設定引數以及獲取結果集。
(3)透過xml 檔案或註解的方式將要執行的各種 statement 配置起來,並透過java物件和 statement 中sql的動態引數進行對映生成最終執行的sql語句,最後由mybatis框架執行sql並將結果對映為java對 象並返回。(從執行sql到返回result的過程)。
2、MyBatis的優點和缺點優點:(1)基於SQL語句程式設計,相當靈活,不會對應用程式或者資料庫的現有設計造成任何影響,SQL寫在 XML裡,解除sql與程式程式碼的耦合,便於統一管理;提供XML標籤,支援編寫動態SQL語句,並可重用。
(2)與JDBC相比,減少了50%以上的程式碼量,消除了JDBC大量冗餘的程式碼,不需要手動開關連線;
(3)很好的與各種資料庫相容(因為MyBatis使用JDBC來連線資料庫,所以只要JDBC支援的資料庫 MyBatis都支援)。
(4)能夠與Spring很好的整合;
(5)提供對映標籤,支援物件與資料庫的ORM欄位關係對映;提供物件關係對映標籤,支援物件關係 元件維護。
缺點(1)SQL語句的編寫工作量較大,尤其當欄位多、關聯表多時,對開發人員編寫SQL語句的功底有一定 要求。
(2)SQL語句依賴於資料庫,導致資料庫移植性差,不能隨意更換資料庫。
3、#{}和${}的區別是什麼?#{}是預編譯處理,KaTeX parse error: Expected 'EOF', got '#' at position 21: …串替換。 Mybatis在處理#̲{}時,會將sql中的#{}替…{}時,就是把${}替換成變數的值。 使用#{}可以有效的防止SQL注入,提高系統安全性。
4、當實體類中的屬性名和表中的欄位名不一樣 ,怎麼辦 ?第1種: 透過在查詢的sql語句中定義欄位名的別名,讓欄位名的別名和實體類的屬性名一致。
<select id=”selectorder” parametertype=”int” resultetype=”me.gacl.domain.order”> select order_id id, order_no orderno ,order_price price form orders where order_id=#{id}; </select>
第2種: 透過來對映欄位名和實體類屬性名的一一對應的關係。
5、Mybatis是如何進行分頁的?分頁外掛的原理是什麼?Mybatis使用RowBounds物件進行分頁,它是針對ResultSet結果集執行的記憶體分頁,而非物理分頁。 可以在sql內直接書寫帶有物理分頁的引數來完成物理分頁功能,也可以使用分頁外掛來完成物理分頁。 分頁外掛的基本原理是使用Mybatis提供的外掛介面,實現自定義外掛,在外掛的攔截方法內攔截待執行的sql,然後重寫sql,根據dialect方言,新增對應的物理分頁語句和物理分頁引數。
6、Mybatis是如何將sql執行結果封裝為目標物件並返回的?都有哪些對映形式?第一種是使用標籤,逐一定義資料庫列名和物件屬性名之間的對映關係。 第二種是使用sql列的別名功能,將列的別名書寫為物件屬性名。 有了列名與屬性名的對映關係後,Mybatis透過反射建立物件,同時使用反射給物件的屬性逐一賦值並返回,那些找不到對映關係的屬性,是無法完成賦值的。
7、 如何執行批次插入?首先,建立一個簡單的insert語句:
<insert id=”insertname”> insert into names (name) values (#{value}) </insert>
然後在java程式碼中像下面這樣執行批處理插入:
list<string> names = new arraylist(); names.add(“fred”); names.add(“barney”); names.add(“betty”); names.add(“wilma”);// 注意這裡 executortype.batch sqlsession sqlsession = sqlsessionfactory.opensession(executortype.batch); try { namemapper mapper = sqlsession.getmapper(namemapper.class); for (string name : names) { mapper.insertname(name); }sqlsession.commit(); }catch(Exception e){ e.printStackTrace(); sqlSession.rollback(); throw e; } finally { sqlsession.close(); }
8、Xml對映檔案中,除了常見的select|insert|updae|delete標籤之外,還有哪些標籤?、、、、,加上動態sql的9個標籤,其中為sql片段標籤,透過標籤引入sql片段,為不支援自增的主鍵生成策略標籤。
9、MyBatis實現一對一有幾種方式?具體怎麼操作的?有聯合查詢和巢狀查詢,聯合查詢是幾個表聯合查詢,只查詢一次, 透過在resultMap裡面配置association節點配置一對一的類就可以完成; 巢狀查詢是先查一個表,根據這個表裡面的結果的 外來鍵id,去再另外一個表裡面查詢資料,也是透過association配置,但另外一個表的查詢透過select屬性配置。
10、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,幾乎所有的包括Hibernate,支援延遲載入的原理都是一樣的。
11、Mybatis的一級、二級快取:1、一級快取: 基於 PerpetualCache 的 HashMap 本地快取,其儲存作用域為 Session,當 Sessionflush 或 close 之後,該 Session 中的所有 Cache 就將清空,預設開啟一級快取。
2、二級快取與一級快取其機制相同,預設也是採用 PerpetualCache,HashMap 儲存,不同在於其儲存作用域為 Mapper(Namespace),並且可自定義儲存源,如 Ehcache。預設不開啟二級快取,要開啟二級快取,使用二級快取屬性類需要實現Serializable序列化介面(可用來儲存物件的狀態),可在它的對映檔案中配置 ;
3、對於快取資料更新機制,當某一個作用域(一級快取 Session/二級快取Namespaces)的進行了C/U/D操作後,預設該作用域下所有 select 中的快取將被 clear 掉並重新更新,如果開啟了二級快取,則只根據配置判斷是否重新整理。