看阿里P7講MyBatis:從MyBatis的理解以及配置和實現全幫你搞懂
前言
MyBatis 是一款優秀的持久層框架,一個半 ORM(物件關係對映)框架,它支援定製化 SQL、儲存過程以及高階映`射。MyBatis 避免了幾乎所有的 JDBC 程式碼和手動設定引數以及獲取結果集。MyBatis 可以使用簡單的 XML 或註解來配置和對映原生型別、介面和 Java 的 POJO(Plain Old Java Objects,普通老式 Java 物件)為資料庫中的記錄。
MyBatis的作用
MyBatis作用是在持久層也就是訪問資料庫的操作,以前我們訪問資料庫是用JDBC來訪問資料庫,JDBC訪問資料庫需要寫很多重複的程式碼,假如資料庫訪問很多還需要對資料庫連線進行不停的開啟連線和關閉連線,很消耗系統性能
MyBatis封裝了JDBC底層訪問資料庫的程式碼,讓我們程式猿只需要關心如何去寫好SQL就好,不在需要去寫JDBC底層的程式碼
MyBatis的優缺點
優點
- MyBatis封裝了JBDC底層訪問資料庫的細節,使我們程式猿不需要與JDBC API打交道,就可以訪問資料庫
- MyBatis簡單易學,程式猿直接編寫SQL語句,適合於對SQL語句效能要求比較高的專案
- SQL語句封裝在配置檔案中,便於統一管理與維護,降低了程式的耦合度
- SQL程式碼從程式程式碼中徹底分離出來,可重用
- 提供了動態SQL標籤,支援編寫動態SQL
- 提供對映標籤,支援物件與資料庫的ORM欄位關係對映
缺點
- 過於依賴資料庫SQL語句,導致資料庫移植性差,更換資料庫,如果SQL語句有差異,SQL語句工作量大
- 由於xml裡標籤id必須唯一,導致DAO中方法不支援方法過載
MyBatis的配置檔案
properties元素
properties元素描述的都是外部化,可替代的屬性
一般用來配置連線資料來源,我們可以使用property子節點來配置也可以使用資源路徑引用
使用property子節點來配置
<properties> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql:///mybatis"/> <property name="username" value="root"/> <property name="password" value="root"/> </properties>
使用資源路徑引用
<properties resource="jdbcConfig.properties"/>
jdbcConfig.properties裡面的屬性
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/test
username=root
password=123456
連線資料來源的配置
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
假如使用property子節點來配置和使用資源路徑引用都用了,這個時候MyBatis會呼叫哪個勒?MyBatis會呼叫資源路徑引用的屬性值,因為資源路徑引用的優先順序高於property子節點的優先順序
settings元素
settings是 MyBatis 中極為重要的調整設定,它們會改變 MyBatis 的執行時行為
<settings>
<!-- 全域性對映器啟用快取 -->
<setting name="cacheEnabled" value="true"/>
<!-- 查詢時,關閉關聯物件即時載入以提高效能 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 設定關聯物件載入的形態,此處為按需載入欄位 (載入欄位由 SQL指 定 ),不會載入關聯表的所有欄位,以提高效能 -->
<setting name="aggressiveLazyLoading" value="false"/>
<!-- 對於未知的 SQL查詢,允許返回不同的結果集以達到通用的效果 -->
<setting name="multipleResultSetsEnabled" value="true"/>
<!-- 允許使用列標籤代替列名 -->
<setting name="useColumnLabel" value="true"/>
<!-- 允許使用自定義的主鍵值 (比如由程式生成的 UUID 32位編碼作為鍵值 ),資料表的 PK生成策略將被覆蓋 -->
<setting name="useGeneratedKeys" value="true"/>
<!-- 給予被巢狀的 resultMap以欄位 -屬性的對映支援 -->
<setting name="autoMappingBehavior" value="FULL"/>
<!-- 對於批量更新操作快取 SQL以提高效能 -->
<setting name="defaultExecutorType" value="BATCH"/>
<!-- 資料庫超過 25000秒仍未響應則超時 -->
<setting name="defaultStatementTimeout" value="25000"/>
</settings>
typeAliases元素
typeAliases元素的作用是給JavaBean取別名,方便我們在mappeer配置檔案中使用
當我們沒有給JavaBean取別名,mapper配置檔案中獲取JavaBean的時候,我們就需要獲取JavaBean所在專案裡面的全路徑
<!--省略部分程式碼-->
<select id="login" resultType="cn.friday.pojo.DevUser">
SELECT * FROM dev_user WHERE devCode=#{devCode} AND devPassword=#{devPassword}
</select>
接下來我們就來給JavaBean取別名
<typeAliases>
<typeAlias type="cn.friday.pojo.DevUser" alias="devUser"/>
<typeAlias type="cn.friday.pojo.AppInfo" alias="appInfo"/>
</typeAliases>
給每個JavaBean去取一個指定的別名,這樣是有缺陷的,萬一專案中有很多個POJO那麼工作量就大了,不過還有一種方法給指定的包裡面所有的JavaBean都取一個別名,MyBatis會自動掃描所指定的包下的JavaBean並且給一個預設的別名,預設的別名為JavaBean的名稱,請看下面
<typeAliases>
<package name="cn.friday.pojo"/>
</typeAliases>
mapper裡面的配置檔案就可以正常使用JavaBean取的別名了,不需要再去獲取JavaBean的全路徑了
<!--省略部分程式碼-->
<select id="login" resultType="DevUser">
SELECT * FROM dev_user WHERE devCode=#{devCode} AND devPassword=#{devPassword}
</select>
environments元素
MyBatis可以配置多種環境,如開發環境、測試環境、生產環境等,我們可以靈活選擇不同的配置,從而將SQL對映應用到不同的資料庫環境上.這些不同的執行環境我們就可以用environments元素來配置實現
environments元素元素的配置
<!--開發環境-->
<!--default屬性表示在預設的情況下我們將啟用的資料來源-->
<environments default="development">
<!--id屬性用來標識一個數據源的,方便在MyBatis中使用 -->
<environment id="development">
<!-- 使用jdbc事務管理 -->
<transactionManager type="JDBC"/>
<!-- 配置資料庫連線池 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/test"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
<!--我們在來配置一個測試環境-->
<environment id="test">
<!-- 使用jdbc事務管理 -->
<transactionManager type="JDBC"/>
<!-- 配置資料庫連線池 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/test1"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
假如我們想從開發環境變成測試環境只需要修改environments元素裡面的default屬性即可
<environments default="test">
<!--省略部分程式碼-->
</environments>
mappers元素
mappers對映器,說簡單點就是告訴MyBatis去哪裡找到SQL語句對映檔案,我們可以使用類資源路徑或者是URL等
用類資源路徑獲取對映檔案
<mappers>
<mapper resource="cn/friday/dao/developer/DevUserMapper.xml"/>
<mapper resource="cn/friday/dao/developer/AppInfoMapper.xml"/>
</mappers>
用URL獲取對映檔案
<mappers>
<mapper url="file:///D:/mappers/DevUserMapper.xml"/>
<mapper url="file:///D:/mappers/AppInfoMapper.xml"/>
</mappers>
如何實現MyBatis
先給大家看一下我的專案結構
第一步 匯入依賴
我的是maven專案所以只需要在pox.xml配置檔案中新增關於MyBatis的依賴即可
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>MyBatis</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>6.0.6</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.4</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/java/</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</build>
</project>
第二步 建立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="jdbc-config.properties"/>
<typeAliases>
<package name="com.friday.pojo"/>
</typeAliases>
<environments default="test">
<environment id="test">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/friday/dao/UserMapper.xml"></mapper>
</mappers>
</configuration>
jdbc-config.properties裡面的屬性
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/test?serverTimezone=UTC
username=root
password=123456
第三步 建立介面以及對映檔案
介面,普通的java介面
package com.friday.dao;
import com.friday.pojo.User;
import org.apache.ibatis.annotations.Param;
public interface UserMapper {
//@Param相對應給String userCode取了一個別名叫做userPassword,我們到寫對映SQL語句的時候只有#{註解名稱}即可,如#{userPassword}
public User login(@Param("userCode") String userCode,@Param("userPassword") String pwd);
}
對映檔案
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC
"-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.friday.dao.UserMapper">
<select id="login" resultType="User" parameterType="string">
SELECT * FROM smbms_user WHERE userCode=#{userCode} AND userPassword=#{userPassword}
</select>
</mapper>
mapper 檔案裡面的屬性
- namespace屬性 指定相對應的介面
- id屬性 接口裡面具體的方法名
- resultType 返回值的型別
- resultType 傳進來的引數的型別
第四步 測試
package com.friday.test;
import com.friday.dao.UserMapper;
import com.friday.pojo.User;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
public class MyBatisTest {
public static void main(String[] args) throws IOException {
//讀取mybatis配置檔案
String resource = "mybatis-config.xml";
//獲取mybatis配置檔案的輸入流
InputStream is = Resources.getResourceAsStream(resource);
//建立SqlSessionFactory物件
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
//開啟sqlSession物件
SqlSession sqlSession = factory.openSession();
//獲取對應的Mapper,讓對映器通過名稱空間和方法名稱找到對應的SQL,傳送給資料庫執行後返回結果。
User user = sqlSession.getMapper(UserMapper.class).login("zhanghua","userPassword");
//看一下是否可以查到資料
if (user != null) {
System.out.println("登入成功");
} else {
System.out.println("登入失敗");
}
//關閉sqlSession物件
sqlSession.close();
}
}
最後
感謝你看到這裡,看完有什麼的不懂的可以在評論區問我,覺得文章對你有幫助的話記得給我點個贊,每天都會分享java相關技術文章或行業資訊,歡迎大家關注和轉發文章!