前言
mybatis核心元件有哪些?它是工作原理是什麼?
mybatis配置檔案各個引數是什麼含義?
mybatis只新增了介面類,沒有實現類,為什麼可以直接查詢呢?
mybatis的mapper對映檔案各個引數又是什麼含義?
mybatis-spring提供哪些機制簡化了原生mybatis?
mybatis-springboot-starter又是如何簡化進一步讓mybatis使用如此方便?程式碼呼叫流程是怎麼樣的?
目錄
jdbc介紹
mybatis介紹
mybatis-spring
mybatis-spring-boot-starter
mybatis原始碼分析
mybatis程式碼生成工具mybatis-generator
mybatis分頁外掛pagehelper
一. jdbc介紹
1. 概述
- jdbc是sun公司提出的一系列對資料庫操作的規範
- java程式對資料庫的連線都通過jdbc規範進行,它統一了介面,使用者在使用時無需關心各個資料庫廠商底層的差異
- 不同資料庫底層具體實現由資料庫廠商實現,也就是資料庫驅動程式
2. 使用jdbc進行開發的流程
- 載入驅動,Driver介面
- 建立連線,Connection介面
- 建立執行SQL的Statement
- 通過Statement執行SQL,執行結果返回到ResultSet並處理
- 釋放資源
3. 總結與反思
- jdbc程式設計工作量大,需要處理連線,事務,資料型別,各種Connection,Statement,ResultSet,關閉連線等等
- 實際開發中不會直接使用jdbc程式設計,而是使用物件關係模型(ORM)框架。
二. mybatis介紹
1. 概述
mybatis是一款優秀的持久層框架,支援定製SQL語句,避免了幾乎所有JDBC程式碼和手動設定引數,結果集獲取
2. 如何使用
- pom檔案中新增mybatis的依賴
- 讀取配置檔案,將配置資訊傳給SqlSessionFactoryBuilder的build方法,構造出SqlSessionFactory
- 用SqlSessionFactory取得SqlSession
- 呼叫SqlSession的getMapper得到mapper介面
- 呼叫mapper介面中的增刪該查方法運算元據庫
3. 核心元件和API
- SqlSession:mybatis最核心的元件,可以傳送sql去執行並返回結果,也可以獲取Mapper介面。類似於jdbc的Connection物件
- SqlSessionFactory:建立SqlSession的工廠類,包含所有建立SqlSession例項的方法
- SqlSessionFactoryBuilder: 根據配置資訊Configuration或程式碼構建SqlSessionFactory物件
- SQL Mapper:由Java介面和xml檔案構成,並給出對應的sql和對映規則,負責傳送sql執行並返回
SqlSessionFactoryBuilder
- 一旦建立了SqlSessionFactory之後,就不再需要它了,最佳作用域是區域性變數
- 包含的函式如下圖所示,允許通過不同的方法建立SqlSessionFactory
- configuration 類包含你可能需要了解 SqlSessionFactory 例項的所有內容
SqlSessionFactory build(InputStream inputStream)SqlSessionFactory build(InputStream inputStream, String environment)SqlSessionFactory build(InputStream inputStream, Properties properties)SqlSessionFactory build(InputStream inputStream, String env, Properties props)SqlSessionFactory build(Configuration config)複製程式碼
SqlSessionFactory
- 每個Mybatis應用都是以SqlSessionFactory例項為中心的,它的任務是建立SqlSession
- 每個資料庫對應一個,在MyBatis應用的整個生命週期中,設計為單例或靜態單例模式最佳
- 構建方法:xml配置方式和程式碼方式
- 包含的函式如下圖所示
//預設獲取的方式,不自動提交(開啟事務)SqlSession openSession()//是否自動提交SqlSession openSession(boolean autoCommit)SqlSession openSession(Connection connection)//事務的隔離級別:None,RU,RC,RR,SerialSqlSession openSession(TransactionIsolationLevel level)//查詢型別:simple,batch,reuseSqlSession openSession(ExecutorType execType,TransactionIsolationLevel level)SqlSession openSession(ExecutorType execType)SqlSession openSession(ExecutorType execType, boolean autoCommit)SqlSession openSession(ExecutorType execType, Connection connection)//獲取mybatis配置資訊Configuration getConfiguration();
複製程式碼
SqlSession
- 每個執行緒都應該有他自己的SqlSession例項
- 是一個介面類,扮演門面的作用,真正幹活的是Executor介面
- 生命週期在請求資料庫處理事務的過程中,不是執行緒安全的物件,不能作為類的靜態變數。多執行緒要小心
- 每次使用時開啟一個SqlSession,操作完就關閉它
//帶引數的增刪改查方法<
T>
T selectOne(String statement, Object parameter)<
E>
List<
E>
selectList(String statement, Object parameter)<
K,V>
Map<
K,V>
selectMap(String statement, Object parameter, String mapKey)int insert(String statement, Object parameter)int update(String statement, Object parameter)int delete(String statement, Object parameter)//不帶引數的增刪改查方法<
T>
T selectOne(String statement)<
E>
List<
E>
selectList(String statement)<
K,V>
Map<
K,V>
selectMap(String statement, String mapKey)int insert(String statement)int update(String statement)int delete(String statement)//高階版本的增刪該查方法,支援自定義返回行數和結果控制<
E>
List<
E>
selectList (String statement, Object parameter, RowBounds rowBounds)<
K,V>
Map<
K,V>
selectMap(String statement, Object parameter, String mapKey, RowBounds rowbounds)void select (String statement, Object parameter, ResultHandler<
T>
handler)void select (String statement, Object parameter, RowBounds rowBounds, ResultHandler<
T>
handler)//事務控制相關方法void commit()void commit(boolean force)void rollback()void rollback(boolean force)//清除快取。mybatis提供了本地快取和二級快取void clearCache()//關閉sessionvoid close()//獲得configuration例項Configuration getConfiguration()//獲得對映器<
T>
T getMapper(Class<
T>
type)複製程式碼
mapper
- 用來繫結對映SQL語句的介面
- 由java介面和xml組成,提供的功能有
- 定義引數型別
- 描述快取
- 描述sql語句
- 定義查詢結果和POJO的對映關係
- 生命週期小於SqlSession,如同jdb中一條sql的執行
- 用過之後不需要顯示關閉mapper
4. mybatis配置說明
4.1 主配置檔案
所有支援的配置項介紹文件:mybatis配置檔案說明,最外層標籤為configuration,子標籤有:
-
propertiess, 可以外部配置且動態替換
-
typeAliases,定義別名。用於減少冗長的類限定名,只和xml配置有關
<
typeAlias>
<
typeAlia alias="role" type="XXX"/>
<
package name="xxx"/>
<
/typeAlias>
複製程式碼 -
mappers,定義對映器,告訴mybatis去哪裡找對映器
<
mappers>
<
mapper resource="xxx"/>
<
mapper url="file:://xxx"/>
<
mapper class="xxx"/>
<
!--包內的所有介面都註冊為對映器-->
<
package name="xxx" />
<
/mappers>
複製程式碼 -
typeHandlers,用於將獲取的值轉化為合適的java型別
<
typeHandlers>
<
typeHandler handler="xxx">
<
/typeHandlers>
複製程式碼mybatis提供了很多預設的型別處理器,簡單列舉幾個
- BooleanTypeHandler:boolean-bool
- StringTypeHandler:String-varchar,char
- IntegerTypeHandler:Integer-int
- DateTypeHandler:Date-timestamp
- EnumTypeHandler:儲存列舉類字串
- EnumOrdinalTypeHandler:儲存列舉類下標
如果標準處理器滿足不了需求,可自定義處理器選擇性對映到某個JDBC型別,具體步驟:
- 實現org.apache.ibatis.type.TypeHandler介面
- 指定該處理器要對映的jdbc型別:配置檔案typeHandler中指定jdbc=“xxx”,或者處理類上使用@MappedJdbcTypes
- 指定該處理器要對映的java型別:
-
environments,定義瞭如何配置資料庫環境資訊
<
environments>
<
environment>
<
transactionManager type="JDBC">
<
/transactionManager>
<
dataSource type="POOLED">
<
property name="url" value="xxx">
... <
/dataSource>
<
/environment>
<
/environments>
複製程式碼 -
settings,很重要的引數
<
settings>
<
!--全域性開啟對映器已經配置的任何快取-->
<
setting name="cacheEnabled" value="true"/>
<
!--延遲載入的全域性開關-->
<
setting name="lazyLoadingEnabled" value="true"/>
<
!--是否執行單一語句返回多條結果集-->
<
setting name="multipleResultSetsEnabled" value="true"/>
<
!--列標籤代替列名-->
<
setting name="useColumnLabel" value="true"/>
<
!--執行jdbc支援自增長主鍵-->
<
setting name="useGeneratedKeys" value="false"/>
<
!--如何自動對映列到欄位屬性-->
<
setting name="autoMappingBehavior" value="PARTIAL"/>
<
!---->
<
setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
<
!--預設的執行器-->
<
setting name="defaultExecutorType" value="SIMPLE"/>
<
!--超時時間-->
<
setting name="defaultStatementTimeout" value="25"/>
<
!--日誌框架,可選值有:SLF4J,LOG4J,JDK_LOGGING,COMMONS_LOGGING,STDOUT_LOGGING,NO_LOGGING-->
<
setting name="logImpl" value="LOG4J"/>
<
!---->
<
setting name="defaultFetchSize" value="100"/>
<
!---->
<
setting name="safeRowBoundsEnabled" value="false"/>
<
!--是否開啟自動駝峰命名規則:下劃線列名轉駝峰變數名-->
<
setting name="mapUnderscoreToCamelCase" value="false"/>
<
!---->
<
setting name="localCacheScope" value="SESSION"/>
<
!---->
<
setting name="jdbcTypeForNull" value="OTHER"/>
<
!---->
<
setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
<
/settings>
複製程式碼 -
objectFactory:建立結果物件的工廠類,可自定義覆蓋預設的
<
objectFactory type="XXX">
<
property name="xx", value="xx"/>
<
/objectFactory>
複製程式碼 -
plugins:外掛執行定義攔截器,攔截mybatis執行過程中的某些呼叫
4.2 Mapper對映檔案
對映檔案定義了介面要執行的sql語句,所有支援的對映檔案介紹文件:mybatis對映檔案說明
- select
<
select id="呼叫介面的函式名稱,唯一標識" parameterType="引數型別,可省略,會根據typehandler自動推斷" parameterMap="被廢棄的選項" resultType="返回結果的型別,不能與resultMap同時存在" resultMap="返回結果的外部集合對映,不能與resultType同時存在。resultType為bean時,底層使用了resultMap" flushCache="設定為true表示任何時候呼叫都會清除本地和二級快取,預設false" useCache="是否開啟本地和二級快取,預設為true" timeout="驅動等待資料庫響應時間,預設為unset,依賴驅動" fetchSize="驅動每次批量返回結果數" statementType="預設preparedStatement" resultSetType="結果集型別,逗號分開">
select id, name from table_name where id = #{id
}<
/select>
複製程式碼 - insert/update/delete:很多屬性同insert
<
insert ... useGeneratedKeys="是否取出資料庫自增長得到的id,預設false" keyProperty=“generatedKey的目標屬性欄位” keyColumn=“generatedKey的目標列名,主鍵列不是第一列需要設定” >
<
/insert>
複製程式碼 - sql:定義可重用的sql語句
<
sql id="xxx">
<
/sql>
<
!--呼叫的地方-->
<
include refid="xxx"/>
複製程式碼 - resultMap:mybatis只最重要最強大的元素
<
resultMap>
<
!--注入結果到構造方法中-->
<
constructor>
<
idArg column="" javatype="">
<
arg>
<
/constructor>
<
!--複雜型別的關聯-->
<
association>
<
/association>
<
!--複雜型別的集合-->
<
collection>
<
/collection>
<
/resultMap>
複製程式碼 - cache:開啟快取,預設情況下是不開啟快取的,除了區域性session
<
!--開啟可讀可寫快取,所有select都被快取,insert,delete和update重新整理快取,-->
<
cache <
!--回收策略:包括LRU(預設),FIFO,SOFT,WEAK-->
eviction="LRU" <
!--重新整理時間,單位毫秒-->
flushInternval="60000" readOnly="true" <
!--快取儲存的引用數量,預設1024-->
size="512"/>
<
cache type="自定義快取,必須實現org.mybatis.cache.Cache介面"/>
複製程式碼 - cache-ref:引用另外一個快取
5. 動態SQL
動態SQL:用於根據條件包含where字句的一部分。動態SQL包括if,choose,trim,foreach
<
select/insert id="xx">
select id, name, status from table_name where status = #{status
} <
!--普通的條件判斷語句-->
<
if test="name != null">
and name like #{name
} <
/if>
<
!--條件分支語句,類似與switch-->
<
choose>
<
when test="name != null">
<
/when>
<
otherwise>
<
/otherwise>
<
/choose>
<
!--會自動去除條件不滿足時多餘的where,and,or等關鍵字-->
<
where>
<
/where>
<
!--自定義去除某些符號的功能-->
<
trim prefix="WHERE" prefixOverrides="AND|OR">
<
/trim>
<
set>
<
if>
<
/set>
<
foreach item="" index="" collection="">
<
/foreach>
<
/select>
複製程式碼
三. Mybatis Spring
1. 概述
- 無縫的將mybatis整合到spring中,使用這個類庫,spring會載入必要到工廠類和session類
- 允許mybatis參與到spring的事務管理中,利用了spring的DataSourceTransactionManger
- 使用mybatis-spring,需要在上下文中定義sqlSessionFactory和至少一個資料對映器類
2. 如何使用
- pom中新增mybatis-spring依賴
- spring的xml檔案中傳入資料來源,並配置sqlSessionFactory
- spring的xml檔案中配置mapper對映介面
- 業務程式碼中獲取自動注入到容器的對映介面,並呼叫增刪改查方法運算元據庫
3. SqlSessionFactoryBean
- 前面介紹原生Mybatis中,通過SqlSessionFactoryBuilder建立SqlSessionFactory。而mybati-spring中由SqlSessionFactoryBean建立
<
bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<
!--必須的屬性,配置資料來源-->
<
property name="dataSource" ref="dataSource" />
<
!--可選屬性,配置對映檔案路徑-->
<
property name="mapperLocations" value="classpath*:sample/config/mappers/**/*.xml" />
<
/bean>
複製程式碼 - SqlSessionFactoryBean實現了spring的FactoryBean介面
- 它必須注入dataSource屬性
4. 配置事務
<
bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<
!--資料來源必須和SqlSessionFactoryBean配置的資料來源一致-->
<
property name="dataSource" ref="dataSource" />
<
/bean>
複製程式碼
5. 使用SqlSession
- 原生mybatis中,通過SqlSessionFactory獲取SqlSession,在mybatis-spring中,不再需要直接使用SqlSessionFactory,因為SqlSession已經以執行緒安全的Bean的方式自動注入了
- SqlSessionTemplate是mybatis-spring的核心,實現了SqlSession介面,負責管理SqlSession。它是執行緒安全的,可以被多個Dao呼叫。還負責SqlSession的的生命週期,包括關閉,提交和回滾操作
- SqlSessionTemplate被設計用於替換預設的DefaultSqlSession
6. 注入對映器
- 為了代替手工呼叫SqlSessionTemplate編寫DAO層業務程式碼,mybatis-spring提供了動態代理的實現類:MapperFactoryBean,該類是設計成泛型,將mapper介面類自動注入到service類中,無需自己寫實現類,內部會自動建立代理
<
bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<
property name="mapperInterface" value="org.mybatis.spring.sample.mapper.UserMapper" />
<
property name="sqlSessionFactory" ref="sqlSessionFactory" />
<
/bean>
複製程式碼
- MapperFactoryBean建立的代理類實現了UserMapper介面,並注入到應用程式中
- 為了代替手工註冊每個對映器,可以使用MapperScannerConfigurer,它會建立路徑下所有對映器,被自動建立MapperFactoryBean
<
bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<
property name="basePackage" value="org.mybatis.spring.sample.mapper" />
<
/bean>
複製程式碼
四. Mybatis Springboot Starter
1. 概述
- 基於springboot快速構建mybatis應用程式
- 使用mybatis-spring,我們需要在xml中配置SqlSessionFactory和mapper對映介面
- 使用mybatis-springboot-starter,會自動檢測dataSource,並根據資料來源,使用SqlSessionFactoryBean自動建立並註冊一個SqlSessionFactory,同時將建立SqlSessionTemplate,自動掃描mapper,關聯到SqlSessionTemplate並注入到容器中
- 預設掃描所有帶@Mapper的介面,自定義掃描某些包,需要使用@MapperSacn註解
2. 如何使用
- pom中新增mybatis-spring-boot-starter依賴
- application.xml中新增資料來源和mybatis相關配置資訊
- 對映介面上新增@Mapper註解,或使用@MapperScan掃描整個包的mapper
- 業務程式碼中獲取自動注入到容器的mapper介面,呼叫mapper的增刪改查方法運算元據庫
3. 配置檔案
- 配置資訊放在application.properties或application.yml檔案中,以mybatis作為配置的字首。引數配置同前面介紹的原生mybatis配置
# application.properties# 指定mybatis-config.xml檔案的位置mybatis.config-location=classpath:mybatis-config.xml# 指定mapper的xml檔案路徑mybatis.mapper-locations=classpath:com/xxmybatis.executor-type=SIMPLE# 指定別名的包,多個用逗號分開mybatis.type-aliases-package=com.example.domain.modelmybatis.type-handlers-package=com.example.typehandlermybatis.configuration.map-underscore-to-camel-case=truemybatis.configuration.default-fetch-size=100mybatis.configuration.default-statement-timeout=30複製程式碼
五. Mybatis原始碼分析
1. mybatis相關jar包說明
1.1 mybatis-spring-boot-starter.jar
- 只有一個pom檔案和spring.provides檔案,官方提供的一些starter格式大致都是這個套路。真正處理自動配置功能的是XXX-autoconfigure.jar完成
- pom中依賴項:jdbc, mybatis, mybatis-spring, mybatis-spring-boot-autoconfigure(真正完成自動配置的jar包)
- provides:說明這個starter配置以後,自動引入的包有哪些
1.2 mybatis-spring-boot-autoconfigure.jar
- xxx-autoconfigure是開發一個starter預設使用的自動配置包
- META-INF/spring.factories: 指定了自動配置的類名是MybatisAutoConfiguration
- MybatisProperties: 指明瞭application.properties檔案中配置資訊對應的屬性類
- MybatisAutoConfiguration:自動配置實現類,函式入口的地方。根據DataSource自動注入SqlSessionFactory,再根據SqlSessionFactory自動注入SqlSessionTemplate。SqlSessionTemplate內部的操作都是通過建立SqlSession的代理sqlSessionProxy來操作的
1.3 mybatis-spring.jar
- mybatis和spring的整合包
1.4 mybatis.jar
- 最原生的mybatis包
2. 配置檔案載入
2.1 UML圖
- 訪問資料庫層,最基本的介面是SqlSession,它的預設實現為DefaultSqlSession, 在mybatis-spring中使用SqlSessionTemplate
- SqlSession通過SqlSessionFactory工廠來建立,而sqlSessionFactory通過建造者SqlSessionFactoryBuilder建立
- SqlSessionFactoryBuilder是通用的構造類類,通過它構造出SqlSessionFactory。可以手工直接呼叫SqlSessionFactoryBuilder。
- mybatis為了和spring整合,提供了mybatis-spring這個jar包。提供的SqlSessionFactoryBean類,內部封裝了對SqlSessionFactoryBuilder的呼叫
- springboot進一步提供了MybatisAutoConfiguration做自動配置,內部的sqlSessionFactory方法,最終呼叫了SqlSessionFactoryBean
- Configuration提供兩類資料,一類是輸入類:Environment,通過給定的配置檔案,將配置資訊
2.2 原始碼跟蹤
-
MybatisAutoConfiguration類內部構造了SqlSessionFactoryBean物件
-
SqlSessionFactoryBean實現了FactoryBean介面,所以getBean獲取例項時實際呼叫他的getObject方法。內部呼叫了afterPropertiesSet方法。afterPropertiesSet方法被重寫,內部呼叫buildSqlSessionFactory
-
buildSqlSessionFactory內部建立了XMLConfigBuilder,用於解析mybatis的配置檔案
-
真正解析配置檔案的地方
-
解析的配置檔案的根為configuration,然後依次解析子標籤:包括最重要的mappers標籤。這部分的解析和前面介紹的配置檔案說明是一一對應的,所有標籤都有對應的解析標籤的程式碼
-
對mapper檔案的解析,內部又具體呼叫了XMLMapperBuilder類的parse方法。這部分的解析與前面介紹的mapper配置檔案說明也是一一對應的
-
解析mapper檔案時,從根元素mapper開始,包括子節點cache,parameterMap,resultMap,select等。然後將解析的資訊都儲存到Configuration物件中。
-
其中select,insert,delete,update語句的解析方法為
-
解析完之後,放入一個map中,每條sql語句對應一個MappedStatement物件。其他屬性的解析類似,大多是放到map中。
-
解析完所有的配置檔案,得到Configuration物件,將它作為引數傳給SqlSessionFactoryBuilder的build方法
-
SqlSessionFactoryBuilder內部根據Configuration引數,建立DefaultSqlSessionFactory類
-
DefaultSqlSessionFactory建構函式只是將Configuration儲存了下來,當需要獲取session時,根據內部的configuration去具體建立
-
得到SqlSessionFactory後,根據它去建立SqlSessionTemplate
-
SqlSessionTemplate內部建立SqlSession的代理類,將沒有加事務的SqlSession的操作做強制提交
3. 動態代理的實現
3.1 概述
Dao層都是是一些介面 它並沒有實現類,為什麼介面可以直接使用呢? 那是因為MyBbatis使用了JDK動態代理機制動態生成了代理類,那麼代理類又是如何對SqlSession進行封裝的呢?
3.2 UML圖
3.3 原始碼跟蹤
註冊mapper並建立代理類
- MapperScanConfiguration這個bean,掃描給定包下所有的mapper檔案,並註冊到MapperRegistry中
- MapperRegistry中的addMappers方法將包名下每個mapper類建立一個MapperProxyFactory,放入map中。
- 獲取mapper時,從map中找到對應的MapperProxyFactory,並將sqlSession引數傳給newInstance,建立出代理類
- 建立代理類呼叫了JDK的動態代理方法,被代理類為DAO介面,代理類為MapperProxy
- MapperProxy實現了InvocationHandler,重寫invoke方法。該方法主要呼叫MapperMethod的execute方法
- MapperMethod的建立需要三個引數:DAO介面本身,方法類,Configuration物件
- MapperMethod內部新建了兩個類:SqlCommand,MethodSignature
- SqlCommand主要儲存了要查詢的這個介面方法的方法名稱和SQL查詢型別,這兩個值都需要先查詢MappedStatemen
- MappedStatement查詢就是在前面章節說道瞭解析檔案完成後儲存到的Configuration的map中查詢
- MethodSignature主要儲存引數,返回值,返回型別等資訊,主要解析Method類
- MapperMethod執行execute時,就是根據前面建立的SqlCommand和MethodSignature的一些屬性執行不同的操作,這些操作都呼叫了SqlSession介面。比如:xml中的select語句,SqlCommand中type指定為SELECT,execute根據不同type執行不同方法。xml中返回型別是單條記錄,還是多條記錄。分別對應MethodSignature的不同屬性,然後執行不同的方法。
獲取mapper並執行
- mapper的註冊前面介紹了是通過MapperRegistry的addMappers方法,而獲取mapper的方法是getMapper,那麼誰來呼叫這個getMapper方法呢?
- 當我們再service中使用@Autowired註解獲取某個mapper介面時,實際上是呼叫了spring為我們自動注入的bean,這個操作是由MapperFactoryBean泛型類來完成。同SqlSessionFactoryBean一樣,MapperFactoryBean實現了FactoryBean介面,所以getBean獲取例項時實際呼叫他的getObject方法。getObejct內部通過sqlSession呼叫getMapper方法,避免了原生mybatis中每次手動通過sqlSession呼叫getMapper方法。
- session物件是MapperFactoryBean的父類SqlSessionDaoSupport的屬性,內部具體實現類是SqlSessionTemplate
- SqlSessionTemplate的getMapper方法,實際呼叫的是Configuration的getMapper方法
- Configuration中的getMapper方法呼叫的就是前面一小節介紹的MapperRegistry類中註冊進去所有進行了動態代理後,放入一個map的物件
六. Mybatis Generator
1. 概述
- mybatis generator是一個mybatis程式碼自動生成工具。官方文件,中文文件
- 生成的內容包括:
- 實體物件:指定資料庫中指定表對應的java實體類
- mapper xml檔案:每張表對應的增刪改查SQL語句
- DAO介面:和SQL語句對應的java查詢介面
- 多次生成時注意的事項:
- xml檔案會自動合併,不會覆蓋已有的內容
- java檔案不會合並,它預設會生成一個不同名字的檔案。可通過引數配置覆蓋原有的檔案
2. 如何使用
2.1 命令列執行使用
- 定義配置檔案
- 執行以下命令
java -jar mybatis-generator-core-x.x.x.jar -configfile \temp\generatorConfig.xml -overwrite複製程式碼
2.2 spring或springboot中使用
- pom中新增依賴
<
build>
<
plugins>
<
plugin>
<
groupId>
org.mybatis.generator<
/groupId>
<
artifactId>
mybatis-generator-maven-plugin<
/artifactId>
<
version>
${mybatis-generator.version
}<
/version>
<
configuration>
<
overwrite>
true<
/overwrite>
<
verbose>
true<
/verbose>
<
/configuration>
<
dependencies>
<
dependency>
<
groupId>
mysql<
/groupId>
<
artifactId>
mysql-connector-java<
/artifactId>
<
version>
${mysql.version
}<
/version>
<
/dependency>
<
/dependencies>
<
/plugin>
<
/plugins>
<
/build>
複製程式碼 - 執行外掛
3. 配置檔案說明
<
?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>
<
!--非必填選項,用於新增執行類路徑位置到類路徑中-->
<
classPathEntry location="/Program Files/IBM/SQLLIB/java/db2java.zip" />
<
!--元素用於指定生成一組物件的環境-->
<
context id="DB2Tables" targetRuntime="MyBatis3">
<
!--註釋生成器的屬性-->
<
commentGenerator>
<
property name="suppressDate" value="true" />
<
!-- 是否去除自動生成的註釋 true:是 : false:否 -->
<
property name="suppressAllComments" value="true"/>
<
/commentGenerator>
<
!--指定資料庫連線資訊-->
<
jdbcConnection driverClass="COM.ibm.db2.jdbc.app.DB2Driver" connectionURL="jdbc:db2:TEST" userId="db2admin" password="db2admin">
<
/jdbcConnection>
<
!--用於定義Java型別解析器的屬性-->
<
javaTypeResolver >
<
property name="forceBigDecimals" value="false" />
<
/javaTypeResolver>
<
!-- 生成實體類的包名和位置-->
<
javaModelGenerator targetPackage="test.model" targetProject="\MBGTestProject\src">
<
property name="enableSubPackages" value="true" />
<
property name="trimStrings" value="true" />
<
/javaModelGenerator>
<
!-- 生成mapper xml檔案的包名和位置-->
<
sqlMapGenerator targetPackage="test.xml" targetProject="\MBGTestProject\src">
<
property name="enableSubPackages" value="true" />
<
/sqlMapGenerator>
<
!-- 生成DAO的包名和位置-->
<
javaClientGenerator type="XMLMAPPER" targetPackage="test.dao" targetPackage="xx" targetProject="\MBGTestProject\src">
<
property name="enableSubPackages" value="true" />
<
/javaClientGenerator>
<
!--指定生成哪個表的資訊-->
<
table schema="DB2ADMIN" tableName="ALLTYPES" domainObjectName="Customer" >
<
property name="useActualColumnNames" value="true"/>
<
!--指定自動生成的主鍵-->
<
generatedKey column="ID" sqlStatement="DB2" identity="true" />
<
columnOverride column="DATE_FIELD" property="startDate" />
<
ignoreColumn column="FRED" />
<
!--自定義列資訊,覆蓋預設資訊,包括property,javaType,jdbcType,typeHandler,delimitedColumnName屬性-->
<
columnOverride column="LONG_VARCHAR_FIELD" jdbcType="VARCHAR" />
<
/table>
<
/context>
<
/generatorConfiguration>
複製程式碼
七. PageHelper
1. 概述
- mybatis的分頁外掛,說明文件,或者github地址github地址, 與springboot的整合springboot-pagehelper
2. 如何使用
- 新增springboot依賴
<
dependency>
<
groupId>
com.github.pagehelper<
/groupId>
<
artifactId>
pagehelper-spring-boot-starter<
/artifactId>
<
version>
${pageHelper.version
}<
/version>
<
/dependency>
複製程式碼 - 在application.properties中新增配置說明
# 分頁外掛會自動檢測當前的資料庫連結,自動選擇合適的分頁方式。 你可以配置helperDialect屬性來指定分頁外掛使用哪種方言pagehelper.helperDialect=mysql# 分頁合理化引數,預設值為false。當該引數設定為 true 時,pageNum<
=0 時會查詢第一頁,# pageNum>
pages(超過總數時),會查詢最後一頁。預設false 時,直接根據引數進行查詢。pagehelper.reasonable=true# 預設值為false,該引數對使用 RowBounds 作為分頁引數時有效。 當該引數設定為true時,使用 RowBounds 分頁會進行 count 查詢。pagehelper.row-bounds-with-count=false# 為了支援startPage(Object params)方法,增加了該引數來配置引數對映,用於從物件中根據屬性名取值# 可以配置 pageNum,pageSize,count,pageSizeZero,reasonable,不配置對映的用預設值# 預設值為pageNum=pageNum;
pageSize=pageSize;
count=countSql;
reasonable=reasonable;
pageSizeZero=pageSizeZeropagehelper.params=# 支援通過 Mapper 介面引數來傳遞分頁引數,預設值false,分頁外掛會從查詢方法的引數值中,# 自動根據上面 params 配置的欄位中取值,查詢到合適的值時就會自動分頁pagehelper.supportMethodsArguments=false# 預設值為 false,當該引數設定為 true 時,如果 pageSize=0 或者 RowBounds.limit = 0 # 就會查詢出全部的結果(相當於沒有執行分頁查詢,但是返回結果仍然是 Page 型別)pagehelper.pageSizeZero=false# autoRuntimeDialect:預設值為 false。設定為 true 時,允許在執行時根據多資料來源自動識別對應方言的分頁 # pring 中配置了動態資料來源,並且連線不同型別的資料庫,這時你可以配置為truepagehelper.autoRuntimeDialect: false# 預設值為 true。當使用執行時動態資料來源或沒有設定 helperDialect 屬性自動獲取資料庫型別時,會自動獲取一個資料庫連線,# 通過該屬性來設定是否關閉獲取的這個連線,預設true關閉,設定為 false 後,不會關閉獲取的連線# 這個引數的設定要根據自己選擇的資料來源來決定pagehelper.close-conn=false複製程式碼 - 在程式碼中呼叫
//方法一:Mapper介面方式的呼叫,startPage,推薦這種使用方式。PageHelper.startPage(1, 10);
List<
Country>
list = countryMapper.selectIf(1);
//方法二:Mapper介面方式的呼叫,offsetPage, 推薦這種使用方式。PageHelper.offsetPage(1, 10);
List<
Country>
list = countryMapper.selectIf(1);
//方法三:引數方法呼叫//存在以下 Mapper 介面方法,你不需要在 xml 處理後兩個引數public interface CountryMapper {List<
Country>
selectByPageNumSize( @Param("user") User user, @Param("pageNum") int pageNum, @Param("pageSize") int pageSize);
}//配置supportMethodsArguments=true//在程式碼中直接呼叫:List<
Country>
list = countryMapper.selectByPageNumSize(user, 1, 10);
//方法四:java8 lambda呼叫//jdk8 lambda用法Page<
Country>
page = PageHelper.startPage(1, 10).doSelectPage(()->
countryMapper.selectGroupBy());
pageInfo = PageHelper.startPage(1, 10).doSelectPageInfo(() ->
countryMapper.selectGroupBy());
//count查詢,返回一個查詢語句的count數total = PageHelper.count(()->
countryMapper.selectLike(country));
複製程式碼
3. 使用注意
- PageHelper.startPage使用靜態的ThreadLocal的,分頁和執行緒繫結,使用startPage時,後面必須緊跟著dao查詢,分頁才能生效