mybatis原理,配置介紹及源碼分析

前言

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代碼和手動設置參數,結果集獲取php

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,Serial SqlSession openSession(TransactionIsolationLevel level) //查詢類型:simple,batch,reuse SqlSession 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() //關閉session void 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,子標籤有:html

  • propertiess, 能夠外部配置且動態替換java

  • typeAliases,定義別名。用於減小冗長的類限定名,只和xml配置有關mysql

    <typeAlias>
        <typeAlia alias="role" type="XXX"/>
        <package name="xxx"/>
    </typeAlias>
    複製代碼
  • mappers,定義映射器,告訴mybatis去哪裏找映射器git

    <mappers>
        <mapper resource="xxx"/>
        <mapper url="file:://xxx"/>
        <mapper class="xxx"/>
        <!--包內的全部接口都註冊爲映射器-->
        <package name="xxx" />
    </mappers>
    複製代碼
  • typeHandlers,用於將獲取的值轉化爲合適的java類型github

    <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,定義瞭如何配置數據庫環境信息spring

    <environments>
        <environment>
            <transactionManager type="JDBC">
            </transactionManager>
            <dataSource type="POOLED">
                <property name="url" value="xxx">
                ...
            </dataSource>
        </environment>
    </environments>
    複製代碼
  • settings,很重要的參數sql

    <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執行過程當中的某些調用apache

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/xx
mybatis.executor-type=SIMPLE
# 指定別名的包,多個用逗號分開
mybatis.type-aliases-package=com.example.domain.model
mybatis.type-handlers-package=com.example.typehandler
mybatis.configuration.map-underscore-to-camel-case=true
mybatis.configuration.default-fetch-size=100
mybatis.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. 概述

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=pageSizeZero
    pagehelper.params=
    # 支持經過 Mapper 接口參數來傳遞分頁參數,默認值false,分頁插件會從查詢方法的參數值中,
    # 自動根據上面 params 配置的字段中取值,查找到合適的值時就會自動分頁
    pagehelper.supportMethodsArguments=false
    # 默認值爲 false,當該參數設置爲 true 時,若是 pageSize=0 或者 RowBounds.limit = 0 
    # 就會查詢出所有的結果(至關於沒有執行分頁查詢,可是返回結果仍然是 Page 類型)
    pagehelper.pageSizeZero=false
    # autoRuntimeDialect:默認值爲 false。設置爲 true 時,容許在運行時根據多數據源自動識別對應方言的分頁 
    # pring 中配置了動態數據源,而且鏈接不一樣類型的數據庫,這時你能夠配置爲true
    pagehelper.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查詢,分頁才能生效
相關文章
相關標籤/搜索