Mybatis一发入魂
文章目錄
- Mybatis官方中文文檔
- 一、Mybatis簡介
- 二、簡單入門使用
- 2.1、在pom.xml中添加依賴
- 2.2、使用xml配置文件
- 2.3、創建接口
- 2.4、創建映射文件
- 2.6、獲取sqlsession實例并執行方法
- 三、Mybatis的Xml配置文件
- 3.1、properties屬性
- 3.2、settings設置
- 3.3、typeAliases類型別名
- 3.4、environments環境配置
- 3.4.1、environment環境變量
- 3.4.2、transactionManager事務管理器
- 3.4.3、dataSource數據源
- 3.4.4、mappers映射器
- 四、XML映射器
- 4.1、命名空間
- 4.2、select
- 4.3、insert,update和delete
- 4.4、sql
- 4.5、參數
- 4.6、resultMap結果映射
- 在resultMap中使用順序:
- 在resultMap中常用元素:
- ResultMap常用屬性
- id和result的常用屬性
- association一對一關聯常用屬性
- collection一對多集合關聯常用屬性
- 結果映射例子:
- 五、動態SQL
- 5.1、if
- 5.2、choose、when、otherwise
- 5.3、where、set
- 5.4、foreach
Mybatis官方中文文檔
此處是根據官方文檔與自己的一些實踐所寫,若想繼續詳細了解請查看(官方中文文檔)
一、Mybatis簡介
- Mybatis是一款優秀的持久層礦建,它支持自定義SQL、存儲過程以及高級映射。
- Mybatis免除了幾乎所有的JDBC代碼以及設置參數和獲取結果集的工作。
- Mybatis可以通過簡單的XML或注解來配置和映射原始類型、接口和Java POJO為數據庫中的記錄。
二、簡單入門使用
2.1、在pom.xml中添加依賴
<!-- mysql依賴--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.30</version></dependency> <!-- 測試依賴--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope></dependency> <!-- mybatis依賴--><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.11</version></dependency>2.2、使用xml配置文件
xml配置文件中包含了對Mybatis系統的核心設置,包括獲取數據庫連接實例的數據源,以及決定事務作用域和控制方式的事物管理器。
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration><!-- 數據源配置文件 --><properties resource="database.properties"></properties><typeAliases><!-- 實體類所在包 --><package name="org.example.demo.pojo"/></typeAliases><!-- mysql數據源 --><environments default="mysqlDev"><environment id="mysqlDev"><transactionManager type="JDBC"></transactionManager><dataSource type="POOLED"><property name="driver" value="${mysqlDriver}"/><property name="url" value="${mysqlUrl}"/><property name="username" value="${mysqlUser}"/><property name="password" value="${mysqlPwd}"/></dataSource></environment></environments><!-- 持久層所在的包 --><mappers><package name="org.example.demo.dao"/></mappers> </configuration>2.3、創建接口
package org.example.demo.dao;import org.example.demo.pojo.Dog; import java.util.List; /*** @program: mybatisXsqone* @interfaceName DogDao* @description:* @author: 太白* @create: 2023-01-11 15:24**/ public interface DogDao {List<Dog> selectList(); }2.4、創建映射文件
對應Dao包創建目錄。注意:創建目錄需使用 / 是層級目錄,使用.是一個目錄
創建xml文件
2.6、獲取sqlsession實例并執行方法
package org.example.demo.dao;import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.example.demo.pojo.Dog; import org.junit.Test;import java.io.InputStream; import java.util.List;/*** @program: mybatisXsqone* @interfaceName DogDaoTest* @description:* @author: 太白* @create: 2023-01-11 15:29**/ public class DogDaoTest {public SqlSession init(){System.out.println("Start"); // 加載配置文件InputStream inputStream = DogDaoTest.class.getClassLoader().getResourceAsStream("mybatis-config.xml"); // 獲取builder工廠SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder(); // 通過建造工廠來建造sqlsessionfactorySqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream); // 創建sqlsession實例SqlSession sqlSession = sqlSessionFactory.openSession();return sqlSession;}public void down(SqlSession sqlSession){sqlSession.commit();sqlSession.close();System.out.println("over");}@Testpublic void testSelectList() {SqlSession sqlSession = this.init();DogDao mapper = sqlSession.getMapper(DogDao.class);List<Dog> dogs = mapper.selectList();for (Dog dog : dogs) {System.out.println(dog);}this.down(sqlSession);} }三、Mybatis的Xml配置文件
配置文件的結構如下:
- configuration (配置)
- properties (屬性)
- settings (設置)
- typeAliases (類型別名)
- objectFactory (對象工廠)
- plugins (插件)
- environments (環境配置)
- environment (環境變量)
- transactionManager (事務管理器)
- dataSource (數據源)
- environment (環境變量)
- databaseIdProvider (數據庫廠商標識)
- mappers(映射器)
配置文件頭 :
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">3.1、properties屬性
<!-- 數據源屬性(配置到外部資源文件) --><properties resource="database.properties"></properties> <!-- 數據源屬性(配置到mybatis的配置文件中) --><properties><property name="mysqlDriver" value="com.mysql.cj.jdbc.Driver"/><property name="mysqlUrl" value="jdbc:mysql://192.168.136.204:3306/jdbcdb?allowMultiQueries=true"/><property name="mysqlUser" value="root"/><property name="mysqlPwd" value="root"/></properties>3.2、settings設置
駝峰命名較為常用,其他設置一般默認即可 (詳情設置請查看官方文檔)
<!-- 設置駝峰命名--><settings><setting name="mapUnderscoreToCamelCase" value="true"/></settings>3.3、typeAliases類型別名
類型別名可為 Java 類型設置一個縮寫名字。 它僅用于 XML 配置,意在降低冗余的全限定類名書寫
<typeAliases><!-- 指定包名(在此包下搜索需要的JavaBean) --><package name="org.example.demo.pojo"/><!-- 指定類名 --> <!-- <typeAlias type="org.example.pojo.Dog" alias="Dog"/>--></typeAliases>3.4、environments環境配置
3.4.1、environment環境變量
MyBatis 可以配置成適應多種環境,這種機制有助于將 SQL 映射應用于多種數據庫之中, 現實情況下有多種理由需要這么做。例如,開發、測試和生產環境需要有不同的配置;或者想在具有相同 Schema 的多個生產數據庫中使用相同的 SQL 映射。
注意:盡管可以配置多個環境,但每個 SqlSessionFactory 實例只能選擇一種環境。
若想連接兩個數據庫,就創建兩個SqlSessionFactory實例,每個數據庫對應一個。
例如:配置文件如下:
<!-- 創建sqlSessionFactory默認使用mysqlDev的數據源 --><environments default="mysqlDev"><environment id="mysqlDev"><transactionManager type="JDBC"></transactionManager><dataSource type="POOLED"><property name="driver" value="${mysqlDriver}"/><property name="url" value="${mysqlUrl}"/><property name="username" value="${mysqlUser}"/><property name="password" value="${mysqlPwd}"/></dataSource></environment><environment id="oracleDev"><transactionManager type="JDBC"></transactionManager><dataSource type="POOLED"><property name="driver" value="${oracleDriver}"/><property name="url" value="${oracleUrl}"/><property name="username" value="${oracleUser}"/><property name="password" value="${oraclePwd}"/></dataSource></environment></environments>創建SqlSessionFactory實例代碼:
// 加載配置文件InputStream inputStream = DogDaoTest.class.getClassLoader().getResourceAsStream("mybatis-config.xml"); // 獲取builder工廠SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder(); // 通過建造工廠來建造sqlsessionfactorySqlSessionFactory mysqlFactory = sqlSessionFactoryBuilder.build(inputStream,"mysqlDev");SqlSessionFactory oracleFactory = sqlSessionFactoryBuilder.build(inputStream,"oracleDev");3.4.2、transactionManager事務管理器
在mybatis中有兩個類型的事物管理器 (JDBC | MANAGED)
- JDBC
- 這個配置直接使用了JDBC的提交和回滾功能,它依賴從數據源獲得的連接來管理事務作用域。
- 默認情況下,為了與某些驅動程序兼容,它在關閉連接時啟動自動提交。
- 對于某些驅動程序來說啟動自動提交不僅是不必要的,而且是代價高昂的操作。在3.5.10版本開始可以通過將“skipSetAutoCommitOnClose”屬性設置為true來跳過這個步驟
- MANAGED
- 這個配置幾乎沒做什么。它從不提交或回滾一個連接,而是讓容器來管理事務的整個生命周期。
- 默認情況下會關閉連接。
- 在一些容器不希望連接被關閉,隱藏可以將“closeConnection”屬性設置為false來阻止默認關閉的行為
3.4.3、dataSource數據源
在mybatis中有三種內檢的數據源類型(UNPOOLED | POOLED | JNDI)
- UNPOOLED
- 每次請求都會打開和關閉鏈接
- POOLED (類似于c3p0有諸多連接池的配置,但都擁有默認值)
- 利用“池”的改建將JDBC連接對象組織起來,避免了創建新的鏈接實例是所必需的初始化和認證時間。
- JNDI(很少用)
常用屬性配置:
| driver | JDBC驅動 | UNPOOLED | POOLED |
| url | 數據庫的JDBC URL 地址 | UNPOOLED | POOLED |
| username | 數據庫用戶名 | UNPOOLED | POOLED |
| password | 數據庫密碼 | UNPOOLED | POOLED |
| poolMaximumActiveConnections | 在任意時間可存在的活動連接數量(默認為 10) | POOLED |
| poolMaximumIdleConnections | 在任意時間可勛在的空閑連接數量 | POOLED |
| poolMaximumCheckoutTime | 強制返回之前,池中連接被檢出時間(默認為20秒(20000ms)) | POOLED |
3.4.4、mappers映射器
用來定義SQL映射語句。告訴Mybatis去哪里找映射文件。
<mappers><!--使用相對于類路徑的資源引用--> <!-- <mapper resource="org/example/dao/DogDao.xml"/>--><!--使用完全限定資源定位符(URL)--> <!-- <mapper url="file:///E:/lovejava/student/mybatis/src/main/resources/org/example/dao/DogDao.xml"/>--><!-- 使用映射器接口實現類的完全限定類名 --> <!-- <mapper class="org.example.dao.DogDao"/>--><!-- 將包內的映射器接口全部注冊為映射器 --><package name="org.example.demo.dao"/></mappers>四、XML映射器
文件格式:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace=""></mapper>元素(在mapper中):
| cache | 該命名空間的緩存配置 |
| cache-ref | 引用其他命名空間的緩存配置 |
| resultMap | 描述如何從數據庫結果集中加載對象 |
| sql | 可被其他語句引用的可重復語句塊 |
| insert | 映射插入語句 |
| update | 映射更新語句 |
| delete | 映射刪除語句 |
| select | 映射查詢語句 |
4.1、命名空間
命名空間為:通用格式中的namespace
作用:
- 利用更長的全限定名將不同的語句隔離開來
- 實現了接口綁定
- 全限定名:(比如:com.example.dao.Dogdao.select),被直接用于查找及使用
- 短名稱:(比如:select),如果是全局唯一可以作為一個單獨引用,若不唯一或有兩個或兩個以上的相同名稱,那么使用時就會產生 短名不唯一 的錯誤,這種情況下就需要使用全限定名。
4.2、select
常用屬性:
| id | 在命名空間中唯一的標識符,可以被用來引用這條語句 |
| parameterType | 將會傳入這條語句的參數的類全限定名或別名。(可選) |
| resultType | 期望從這條語句中返回結果的類全限定名或別名。(resultType和resultMap只可用一個) |
| resultMap | 對外部resultMap的命名引用 |
4.3、insert,update和delete
常用屬性:
| id | 在命名空間中唯一的標識符,可以被用來引用這條語句 |
| parameterType | 將會傳入這條語句的參數的類全限定名或別名。(可選) |
4.4、sql
這個元素可以用來定義可重復使用的SQL代碼片段,以便在其他語句中使用。
使用 <include refid=" "/> 來調用
例如:
<sql id="dogField">id,name,health,love,strain,lytm</sql><select id="selectList" resultType="org.example.demo.pojo.Dog">select <include refid="dogField"></include> from dog</select>4.5、參數
-
只傳一個參數:
原始類型或簡單數據類型因為沒有其他屬性,會直接用它的值來作為參數。(這個參數可以隨意命名)
例如:
int delete(int id);
java接口xml文件:
<delete id="delete">delete from dog where id = #{id} </delete> -
傳一個對象:
如果傳一個對象到了語句中,會查找它的屬性,將它們的值傳入與處理語句的參數中。
例如:
int save(Dog dog);
java接口xml文件:
<insert id="save">insert into dog(name,health,love,strain,lytm)values (#{name},#{health},#{love},#{strain},now());</insert> -
傳多個參數
@Param用于dao層,是mybatis中的注解
List<Dog> selectLoveHealth(@Param("love") Integer love, @Param("health") Integer health);
使得mapper.xml中的參數與后臺的參數對應上,也增強了可讀性
例如:
java接口xml文件:
<select id="selectLoveHealth" resultType="org.example.pojo.Dog">select * from dog where love=#{love} and health=#{health};</select>
4.6、resultMap結果映射
- resultMap 元素是 MyBatis 中最重要最強大的元素。
- 它可以讓你從 90% 的 JDBC ResultSets 數據提取代碼中解放出來,并在一些情形下允許你進行一些 JDBC 不支持的操作。
- 實際上,在為一些比如連接的復雜語句編寫映射代碼的時候,一份 resultMap 能夠代替實現同等功能的數千行代碼。
- ResultMap 的設計思想是,對簡單的語句做到零配置,對于復雜一點的語句,只需要描述語句之間的關系就行了。
在resultMap中使用順序:
constructor? , id* , result* , association* , collection* , discriminator?在resultMap中常用元素:
- id – 一個 ID 結果;標記出作為 ID 的結果可以幫助提高整體性能
- result – 注入到字段或 JavaBean 屬性的普通結果
- association – 一個復雜類型的關聯;許多結果將包裝成這種類型
- 嵌套結果映射 – 關聯可以是 resultMap 元素,或是對其它結果映射的引用
- collection – 一個復雜類型的集合
- 嵌套結果映射 – 集合可以是 resultMap 元素,或是對其它結果映射的引用
ResultMap常用屬性
| id | 當前命名空間中的一個唯一標識,用于標識一個結果映射。 |
| type | 類的完全限定名,或者一個類別名稱 |
id和result的常用屬性
| property | 映射到列的字段或屬性 |
| column | 數據庫中的列名,或者是列的別名 |
| javaType | 一個Java類的全限定名,或一個類型別名 |
association一對一關聯常用屬性
| property | 映射到列的字段或屬性 |
| javaType | 一個Java類的全限定名,或一個類型別名 |
| column | 數據庫中的列名,或者是列的別名 |
| select | 用于加載復雜類型屬性的映射語句ID,會從column屬性指定的列中檢索數據,作為參數傳遞給目標select語句 |
collection一對多集合關聯常用屬性
在collection和accociation類似但會有一個新的“ofType”屬性:
| ofType | 將 JavaBean(或字段)屬性的類型和集合存儲的類型區分開來 |
可看出posts存儲Post的ArrayList集合
在一般情況下,Mybatis可以推斷javaType屬性為ArrayList,因此不需要填寫,可以簡寫為:
結果映射例子:
一對多,一對一是可以嵌套的。
<resultMap id="dogMap1" type="dog"><id column="id" property="id"></id><result column="name" property="name"></result><result column="health" property="health"></result><result column="love" property="love"></result><result column="strain" property="strain"></result><result column="lytm" property="lytm"></result><association property="strainInfo" javaType="StrainInfo"><id column="sid" property="id"/><result column="sname" property="name"/><result column="describe" property="describe"/></association><collection property="masters" ofType="Master"><id column="pid" property="pid"></id><result column="uname" property="name"></result><result column="age" property="age"></result><result column="gender" property="gender"></result><result column="yearnum" property="yearnum"></result><!-- <result column="did" property="dog.id"></result>--></collection></resultMap>五、動態SQL
5.1、if
<update id="update">update dog<set><if test="name!=null and name != '' ">name = #{name},</if><if test="health!=null ">health = #{health},</if><if test="love!=null">love = #{love},</if><if test="strain!=null and strain != '' ">strain = #{strain},</if></set>where id = #{id}</update>5.2、choose、when、otherwise
有時候,我們不想使用所有的條件,而只是想從多個條件中選擇一個使用。針對這種情況,MyBatis 提供了 choose 元素,它有點像 Java 中的 switch 語句。
<select id="getDog" resultType="org.example.pojo.Dog">select id,name,health,love,strain,lytm from dog<choose><when test="sort == 1">order by lytm asc</when><when test="sort == 2">order by lytm desc</when><otherwise>order by id desc</otherwise></choose></select>5.3、where、set
前幾個例子已經解決了一些動態SQL問題,若如下:
<select id="getDog" resultType="org.example.pojo.Dog">select id,name,health,love,strain,lytm from dogWHERE<if test="name!= null and name != null">AND name like #{name}</if><if test="strain!= null">AND strain like #{strain}</if> </select>若沒有匹配的條件,最終SQL會變成:
select id,name,health,love,strain,lytm from dog WHERE這會導致查詢失敗,若只匹配第二個條件,最終SQL會變成:
select id,name,health,love,strain,lytm from dog WHERE AND strain like #{strain}這個也會導致查詢失敗,這個問題不能簡單的用條件元素來解決。在mybatis中也考慮到了這種場景可以如下寫:
<select id="getDog" resultType="org.example.pojo.Dog">select id,name,health,love,strain,lytm from dog<where><if test="name!= null and name != null">AND name like #{name}</if><if test="strain!= null">AND strain like #{strain}</if></where> </select>where 元素只會在子元素返回任何情況下才插入“WHERE”語句,而且,若字句開頭為“and”或“or”開頭,where元素也會將它們去除
用于動態更新語句的類似解決方案為set元素,set元素可以用于動態包含需要更新的列,忽略其他不更新的列(會刪除掉額外的逗號)
例如:
<update id="update">update dog<set><if test="name!=null and name != '' ">name = #{name},</if><if test="health!=null ">health = #{health},</if><if test="love!=null">love = #{love},</if><if test="strain!=null and strain != '' ">strain = #{strain},</if></set>where id = #{id}</update>5.4、foreach
動態SQL的另一個常見使用場景是對集合進行遍歷,如:
批量添加
| collection | 表示如何來得到這個集合,如果傳入的直接為一個List,那么collection值就為list,如果直接傳入的為一個array不可變數組,那么collection值就為array |
| item | 集合中每一個元素進行迭代時的別名 |
| separator | 在每次進行迭代之間以什么符號作為分隔符 |
| open | 該語句以什么開始 |
| close | 以什么結束 |
總結
以上是生活随笔為你收集整理的Mybatis一发入魂的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 机器学习 - Python Matplo
- 下一篇: Giving an effective