目錄html
Mybatis是一個持久層框架java
它對JDBC操做數據庫進行封裝,讓咱們更關注SQL自己,而不須要花費精力去處理例如註冊驅動、建立connection、建立statement、手動設置參數、結果集檢索等jdbc繁雜的過程代碼。下面是Mybatis的架構圖
mysql
Mybatis又是如何解決JDBC中存在的問題呢?git
一、 建立數據庫鏈接相關操做,存在硬編碼
a) 解決方案:經過Mybatis全局配置文件,對數據庫鏈接進行配置
二、 statement相關操做,存在硬編碼
a) 解決方案:經過Mapper映射文件,對statement相關處理進行配置。
三、 頻繁開啓數據庫鏈接,會下降數據庫處理性能。
a) 解決方案:經過Mybatis全局配置文件,配置鏈接池。
github
所謂的關聯查詢就是一對一和一對多以及多對多的應用,例以下面的例子
spring
一對一 : 例如在獲取訂單的時候須要獲取該訂單所屬的用戶信息
解決思路 : 使用ResultMap或者ResultType自定義一個POJO進行結果映射sql
一對多 : 例如在獲取用戶信息的時候須要獲取該用戶的全部訂單信息
解決思路 : 自定義一個POJO使用(只能使用)ResultMap進行結果映射數據庫
MyBatis根據對關聯對象查詢的select語句的執行時機,分爲三種類型:直接加載、侵入式加載與深度延遲加載緩存
延遲加載策略須要在Mybatis的全局配置文件中,經過
直接加載 經過對全局參數:lazyLoadingEnabled進行設置,默認就是false。
<settings> <!-- 延遲加載總開關 --> <setting name="lazyLoadingEnabled" value="false"/> </settings>
侵入式加載
<settings> <!-- 延遲加載總開關 --> <setting name="lazyLoadingEnabled" value="true"/> <!-- 侵入式延遲加載開關 --> <setting name="aggressiveLazyLoading" value="true"/> </settings>
深度延遲加載
<settings> <!-- 延遲加載總開關 --> <setting name="lazyLoadingEnabled" value="true"/> <!-- 侵入式延遲加載開關 --> <setting name="aggressiveLazyLoading" value="false"/> </settings>
動態SQL的思想:就是使用不一樣的動態SQL標籤去完成SQL字符串的拼接處理。
if標籤 where標籤 sql片斷 foreach標籤
• 一級緩存是SqlSession級別的緩存。在操做數據庫時須要構造 sqlSession對象,在對象中有一個數據結構(HashMap)用於存儲緩存數據。不一樣的sqlSession之間的緩存數據區域(HashMap)是互相不影響的。 • 二級緩存是Mapper(namespace)級別的緩存。多個SqlSession去操做同一個Mapper的sql語句,多個SqlSession能夠共用二級緩存,二級緩存是跨SqlSession的。
第一次發起查詢用戶id爲1的用戶信息,先去找緩存中是否有id爲1的用戶信息,若是沒有,從數據庫查詢用戶信息,將查詢到的用戶信息存儲到一級緩存中。
若是中間sqlSession去執行commit操做(執行插入、更新、刪除),清空SqlSession中的一級緩存,這樣作的目的爲了讓緩存中存儲的是最新的信息,避免髒讀。
第二次發起查詢用戶id爲1的用戶信息,先去找緩存中是否有id爲1的用戶信息,緩存中有,直接從緩存中獲取用戶信息。
1. 第一次調用mapper下的SQL去查詢用戶信息。查詢到的信息會存到該mapper對應的二級緩存區域內。 2. 第二次調用相同namespace下的mapper映射文件中相同的SQL去查詢用戶信息。會去對應的二級緩存內取結果。 3. 若是調用相同namespace下的mapper映射文件中的增刪改SQL,並執行了commit操做。此時會清空該namespace下的二級緩存。
<!-- 開啓二級緩存總開關 --> <settings> <setting name="cacheEnabled" value="true"/> </settings>
<!-- 開啓本mapper下的namespace的二級緩存,默認使用的是mybatis提供的PerpetualCache --> <cache></cache>
說明 : 因爲二級緩存的數據不必定都是存儲到內存中,它的存儲介質多種多樣,好比說存儲到文件系統中,因此須要給緩存的對象執行序列化。若是該類存在父類,那麼父類也要實現序列化。(既查詢結果對象要實現序列化接口)
因爲Mybatis是半自動化的ORM框架,因此仍然有不少事情須要咱們去作
例如 : 編寫與數據庫表對應的實體,編寫Mapper接口,編寫Mapper配置文件
所謂的Mybatis逆向工程僅僅是一個項目因此只須要在下面配置中填寫好本身數據庫的相關信息,運行main方法既能夠爲咱們生成POJO類,Mapper接口,Mapper配置文件
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"> <generatorConfiguration> <context id="testTables" targetRuntime="MyBatis3"> <commentGenerator> <!-- 是否去除自動生成的註釋 true:是 : false:否 --> <property name="suppressAllComments" value="true" /> </commentGenerator> <!--數據庫鏈接的信息:驅動類、鏈接地址、用戶名、密碼 --> <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3306/mybatis" userId="root" password="root"> </jdbcConnection> <!-- <jdbcConnection driverClass="oracle.jdbc.OracleDriver" connectionURL="jdbc:oracle:thin:@127.0.0.1:1521:yycg" userId="yycg" password="yycg"> </jdbcConnection> --> <!-- 默認false,把JDBC DECIMAL 和 NUMERIC 類型解析爲 Integer,爲 true時把JDBC DECIMAL 和 NUMERIC 類型解析爲java.math.BigDecimal --> <javaTypeResolver> <property name="forceBigDecimals" value="false" /> </javaTypeResolver> <!-- targetProject:生成PO類的位置 --> <javaModelGenerator targetPackage="com.kkb.ms.po" targetProject=".\src"> <!-- enableSubPackages:是否讓schema做爲包的後綴 --> <property name="enableSubPackages" value="false" /> <!-- 從數據庫返回的值被清理先後的空格 --> <property name="trimStrings" value="true" /> </javaModelGenerator> <!-- targetProject:mapper映射文件生成的位置 --> <sqlMapGenerator targetPackage="com.kkb.ms.mapper" targetProject=".\src"> <!-- enableSubPackages:是否讓schema做爲包的後綴 --> <property name="enableSubPackages" value="false" /> </sqlMapGenerator> <!-- targetPackage:mapper接口生成的位置 --> <javaClientGenerator type="XMLMAPPER" targetPackage="com.kkb.ms.mapper" targetProject=".\src"> <!-- enableSubPackages:是否讓schema做爲包的後綴 --> <property name="enableSubPackages" value="false" /> </javaClientGenerator> <!-- 指定數據庫表 --> <table schema="" tableName="user"></table> <table schema="" tableName="order"></table> </context> </generatorConfiguration>
注意 :每次執行逆向工程代碼以前,先刪除原來已經生成的mapper xml文件再進行生成。mapper.xml文件的內容不是被覆蓋而是進行內容追加,會致使mybatis解析失敗。po類及mapper.java文件的內容是直接覆蓋沒有此問題。
若是你也在用Mybatis,建議嘗試該分頁插件,這個必定是最方便使用的分頁插件。
使用方法以下
首先增長依賴
<dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>5.1.6</version> </dependency>
配置PageHelper
• Mybatis全局配置文件 <plugins> <plugin interceptor="com.github.pagehelper.PageInterceptor"> <!-- config params as the following --> <property name="helperDialect" value="mysql"/> </plugin> </plugins>
• Spring配置文件 <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- other configuration --> <property name="plugins"> <array> <bean class="com.github.pagehelper.PageInterceptor"> <property name="properties"> <!-- config params as the following --> <value> helperDialect=mysql </value> </property> </bean> </array> </property> </bean>
在項目中使用PageHelper
//獲取第1頁,10條內容,默認查詢總數count PageHelper.startPage(1, 10); List<Country> list = countryMapper.selectAll(); //用PageInfo對結果進行包裝 PageInfo page = new PageInfo(list); //測試PageInfo所有屬性 //PageInfo包含了很是全面的分頁屬性 assertEquals(1, page.getPageNum()); assertEquals(10, page.getPageSize());
注意事項
1. 須要分頁的查詢語句,必須是處於PageHelper.startPage(1, 10);後面的第一條語句。 2. 若是查詢語句是使用resultMap進行的嵌套結果映射,則沒法使用PageHelper進行分頁。
Mybatis插件介紹
參考地址:https://www.cnblogs.com/fangjian0423/p/mybatis-interceptor.html
StatementHandler
ParameterHandler
ResultSetHandler
使用註解開發,咱們再也不須要XML配置文件
經常使用註解說明
• @Results: 至關於<resultMap>標籤,須要和@Result註解一塊兒使用。 • @Result: 至關於<result>和<id>標籤,實現結果集中某一列的數據映射 * column 數據庫的列名 * property 須要裝配的屬性名 * one 須要使用的@One 註解(@Result(one=@One())) * many 須要使用的@Many 註解(@Result(many=@many())) • @One: 至關於<association>標籤,實現一對一關係映射 • @Many:至關於<collection>標籤,實現一對多關係映射 • @One和@Many註解的屬性: * select 屬性:表明將要執行的 sql 語句 * fetchType 屬性:表明加載方式,通常若是要延遲加載都設置爲 LAZY 的值 • 使用格式: 1. @Results({@Result(),@Result()})或@Results(@Result()) 2. @Result(column=" ",property="",one=@One(select=""))