mybatis是一款優秀的持久層框架,支持定製SQL語句,避免了幾乎全部JDBC代碼和手動設置參數,結果集獲取php
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) 複製代碼
//默認獲取的方式,不自動提交(開啓事務)
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();
複製代碼
//帶參數的增刪改查方法
<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) 複製代碼
全部支持的配置項介紹文檔: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>
複製代碼
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
映射文件定義了接口要執行的sql語句,全部支持的映射文件介紹文檔:mybatis映射文件說明
<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 ... useGeneratedKeys="是否取出數據庫自增加獲得的id,默認false" keyProperty=「generatedKey的目標屬性字段」 keyColumn=「generatedKey的目標列名,主鍵列不是第一列須要設置」 >
</insert>
複製代碼
<sql id="xxx">
</sql>
<!--調用的地方-->
<include refid="xxx"/>
複製代碼
<resultMap>
<!--注入結果到構造方法中-->
<constructor>
<idArg column="" javatype="">
<arg>
</constructor>
<!--複雜類型的關聯-->
<association>
</association>
<!--複雜類型的集合-->
<collection>
</collection>
</resultMap>
複製代碼
<!--開啓可讀可寫緩存,全部select都被緩存,insert,delete和update刷新緩存,-->
<cache
<!--回收策略:包括LRU(默認),FIFO,SOFT,WEAK-->
eviction="LRU"
<!--刷新時間,單位毫秒-->
flushInternval="60000"
readOnly="true"
<!--緩存存儲的引用數量,默認1024-->
size="512"
/>
<cache type="自定義緩存,必須實現org.mybatis.cache.Cache接口"/>
複製代碼
動態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>
複製代碼
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--必須的屬性,配置數據源-->
<property name="dataSource" ref="dataSource" />
<!--可選屬性,配置映射文件路徑-->
<property name="mapperLocations" value="classpath*:sample/config/mappers/**/*.xml" />
</bean>
複製代碼
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--數據源必須和SqlSessionFactoryBean配置的數據源一致-->
<property name="dataSource" ref="dataSource" />
</bean>
複製代碼
<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>
複製代碼
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="org.mybatis.spring.sample.mapper" />
</bean>
複製代碼
# 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
複製代碼
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的操做作強制提交
Dao層都是是一些接口 它並無實現類,爲何接口能夠直接使用呢? 那是由於MyBbatis使用了JDK動態代理機制動態生成了代理類,那麼代理類又是如何對SqlSession進行封裝的呢?
java -jar mybatis-generator-core-x.x.x.jar -configfile \temp\generatorConfig.xml -overwrite
複製代碼
<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>
複製代碼
<?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>
複製代碼
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>${pageHelper.version}</version>
</dependency>
複製代碼
# 分頁插件會自動檢測當前的數據庫連接,自動選擇合適的分頁方式。 你能夠配置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));
複製代碼