Mybatis 基本概念和入門案例

文中代碼託管在碼雲平臺,點擊進入

框架概述

  • 框架表現爲一組抽象構件以及構件實例間交互的方法,是可被應用開發者定製的應用骨架;
  • 通俗來說,框架是軟件開發中的一套解決方案,不同的框架解決的是不同的問題,框架封裝了很多的細節,使開發者可以使用簡便的方式實現功能,從而大大提高開發效率。
  • Mybatis 是在持久層應用的一種框架,內部封裝了JDBC,屏蔽了JDBC Api底層訪問細節,通過xml或註解的方式配置,採用ORM思想解決了實體和數據庫的映射
  • Mybatis 通過 xml 或註解的方式將要執行的各種 statement 配置起來,並通過 java 對象和 statement 中 sql 的動態參數進行映射生成最終執行的 sql 語句,最後由 Mybatis 框架執行 sql 並將結果映射爲 java 對象並返回;
  • 實體類中的屬性需要和數據庫的字段名稱保持一致

環境搭建

Mybatis 官網

  • IDEA創建
    (1)創建maven項目,輸入名稱
    (2)選擇創建位置,即可創建完成
    (3)創建數據庫
  • pom.xml配置
    (1)添加打包方式<packaging>jar</packagiing>
    (2)依賴導入
    (3)數據庫配置
    (4)日誌配置
    (5)單元測試導入
  • 創建實體類、主配置文件和各個Dao接口的映射配置文件
  • 注意事項:
    (1)Mybatis的映射配置文件必須和dao的接口在同一結構內即resourcesjava兩個目錄必須是一致的
    (2)映射配置文件的mapper標籤namespace屬性的取值必須是dao接口的全限定類名
    (3)映射配置文件的操作配置,id屬性的取值必須是dao接口的方法名
    (4)resources文件目錄下的文件夾要一個一個創建,不要在創建文件夾時直接寫com.***.***.***,會直接創建爲一個一級目錄而不是三級目錄

SqlMapConfig.xml 主配置文件

<?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">
<!--  mybatis的主配置文件  -->
<configuration>
  <!--  配置環境  -->
  <environments default="mysql">
  	<!--  配置mysql管徑  -->
    <environment id="mysql">
      <!--  配置事務的類型  -->
      <transactionManager type="JDBC"/>
      <!--  配置數據源(連接池)  -->
      <dataSource type="POOLED">
        <!--  配置連接數據庫的4個基本屬性  -->
        <!--  有了這些便能創建Connection對象  -->
        <property name="driver" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/databaseName"/>
        <property name="username" value="Root"/>
        <property name="password" value="password"/>
      </dataSource>
    </environment>
  </environments>
  <!--  制定映射配置文件的位置  -->
  <!--  有了這些便能知道映射配置文件的信息  -->
  <mappers>
    <mapper resource="com/demo/dao/IUserDao.xml"/>
    <!-- <mapper class="com.demo.dao.IUserDao"/> 使用註解則改成這個語句 -->
  </mappers>
</configuration>

IUserDao.xml 映射配置文件

<?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">
  <!--  有了這些就有了執行的SQL語句
  		可以獲取PreparedStatement
  		還有封裝的實體類全限定類名,指定返回的對象類型
  	  -->
  <mapper namespace="********">
    <!-- 配置查詢所有 -->
    <!-- resultType 表示指定返回的是哪一種對象 -->
    <select id="findAll" resultType="IUserDao接口的路徑">
       select * from user
    </select>
  </mapper>

pom.xml maven配置文件

<?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>com.learn.mybatisDemo</groupId>
    <artifactId>demo1_first_use</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <build>
        <finalName>webapp</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.6.2</version>
                <configuration>
                    <source>12</source>
                    <target>12</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.3</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.48</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>1.7.30</version>
        </dependency>
    </dependencies>

</project>

在這裏插入圖片描述

入門案例

使用步驟

(1)讀取配置文件
(2)創建SqlSessionFactory工廠
(3)使用工廠生產SqlSession對象
(4)使用SqlSession創建dao接口的代理對象
(5)使用代理對象的執行放阿飛
(6)釋放資源

  • 代碼
// 1 讀取配置文件
InputStream in = Resources.getResourceAsStream("配置文件路徑")
// 2 創建SqlSessionFactory工廠
// Mybatis把工廠的創建細節封裝在SqlSessionFactoryBuilder
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
// 3 使用工廠生產SqlSession對象
SqlSession session = factory.openSession();
// 4 使用SqlSession創建dao接口的代理對象
IUserDao userDao = session.getMapper(IUserDao.class);
// 5 使用代理對象的執行方法
List<User> users = userDao.findAll();
for(User user:users){
  SYstem.out.println(user);
}
// 6 釋放資源
session.close();
in.close();

開發過程中的一些問題

  • 讀文件的路徑
    使用絕對路徑會不靈活,使用相對路徑在工程部署後一些文件結構會發生變動,因此一般在開發時採用類加載器(只能讀取類路徑的配置文件)和使用ServletContex對象的getRealPath()(獲取當前應用部署的絕對路徑)
  • 創建工廠Mybatis使用了構建者模式(類似於找個包工隊幫你裝修),builder就是構建者
  • session的創建使用了工廠模式(要什麼給什麼),優勢在於解耦,降低類之間的依賴關係
  • getMapper中使用了代理模式,優勢在於不修改源碼的基礎上對已有的方法增強

註解的使用方式

  • 使用註解就不再需要映射配置文件了,移除即可
  • 在dao方法中添加註解
  • 在主配置文件的 mapper 標籤中配置,使用 class 屬性

核心配置文件

<!-- 使用註解配置,就要使用class屬性制定被註解的dao的全限定類名 -->
<mappers>
  <mapper class="類路徑"/>
</mappers>

Dao

@Select("select * from user")
List<User> findAll(){
  ...
}

自定義dao接口的實現類

  • Mybatis支持自定義實現類,但是沒有意義,一般不採用,瞭解即可
public class UserDaoImpl implements IUserDao{
	private SqlSessionFactory factory;
	public UserDaoImpl (SqlSessionFactory factory){
		this.factory = factory;
	}
	public List<User> findAll(){
		//使用工廠創建SqlSession對象
		SqlSession session = factory.openSession();
		//使用session執行查詢所有方法
		List<User> users = session.selectList("xml中namespace的路徑+id");
		session.closr();
		return users;
		...
	}
}
  • 那麼在使用的時候就不再需要使用代理對象
// 1 讀取配置文件
InputStream in = Resources.getResourceAsStream("配置文件路徑")
// 2 創建SqlSessionFactory工廠
// Mybatis把工廠的創建細節封裝在SqlSessionFactoryBuilder
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
// 3 使用工廠創建dao對象
IUserDao userDao = new UserDaoImpl(factory);
// 4 使用對象的執行方法
List<User> users = userDao.findAll();
for(User user:users){
  SYstem.out.println(user);
}
// 5 釋放資源
in.close();
  • 其實這個實際開發基本不會採用,但是也要了解一下,主要是爲了讓大家瞭解 Mybatis 的執行細節,分析Mybatis在使用代理dao的方式實現增刪改查時做的事情:
    (1)創建代理對象
    (2)在代理對象中調用selectList或其他方法

  • 讀取 xml 配置文件:用到解析XML的技術,此處用的是dom4j解析XML技術(解析技術有很多,瞭解即可);目的是給方法提供數據庫連接信息和映射信息(包含執行的SQL語句封裝結果的實體類全限定類名

  • 要讓方法能夠執行,需要將映射信息封裝,定義成一個Map對象,將接口類中要實現的方法和 xml 文件中的映射信息相對應,即 xml 文件中mapper標籤中的內容

  • CRUD 方法中 Mybatis 執行流程:
    (1)根據配置文件的信息創建Connection對象:註冊驅動,獲取連接
    (2)獲取預處理對象,此時需要SQL語句:conn.prepareStatement(sql)就是從映射配置文件中獲取
    (3)執行CRUD操作:ResultSet rs = preparedStatement.executeQuery();
    (4)遍歷結果集進行封裝:

    1. 創建集合;
    2. 開始循環;
    3. 根據映射配置文件的返回類型創建對象E element = (E) Class.forName(配置的全限定類名).newInstance();
    4. 封裝對象封裝的時候使用反射封裝的方式根據名稱獲取每個屬性並賦值,這也就是要求表的列名和實體類屬性一致的原因
    5. 將對象添加到集合;
    6. 繼續下一個;
    7. 遍歷結束退出返回集合;

    (5)返回 list

創建代理對象的分析

// 4 使用SqlSession創建dao接口的代理對象
IUserDao userDao = session.getMapper(IUserDao.class);
  • 方法實現過程
//根據Dao接口的字節碼創建Dao的代理對象
public <T> getMapper(Class<T> daoInterfaceClass){
	/*
	  類加載器:使用的和被代理對象是相同的類加載器
	  代理對象要實現的接口:和被代理對象實現相同的接口
	  如何代理:就是增強的方法,需要自己提供,此處是一個InvocationHandler的接口
			我們需要寫一個該接口的實現類,並在實現類中調用dao中的關於CRUD的方法
	*/
	Proxy.newProxyInstance(類加載器, 代理對象要實現的接口字節碼數組,如何代理);
}

自定義Mybatis中能通過入門案例看到的類


  • (1)Resouce 使用類加載器讀取配置文件的類
    (2)SqlSessionFactoryBuilder 用於創建SqlSessionFactory對象
  • 接口
    (1)SqlSessionFactory 提供一個工廠
    (2)SqlSession 和數據庫交互的核心類,裏面可以創建dao接口的代理對象
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章