框架概述
- 框架表現爲一組抽象構件以及構件實例間交互的方法,是可被應用開發者定製的應用骨架;
- 通俗來說,框架是軟件開發中的一套解決方案,不同的框架解決的是不同的問題,框架封裝了很多的細節,使開發者可以使用簡便的方式實現功能,從而大大提高開發效率。
- Mybatis 是在持久層應用的一種框架,內部封裝了JDBC,屏蔽了JDBC Api底層訪問細節,通過
xml
或註解的方式配置,採用ORM思想解決了實體和數據庫的映射
; - Mybatis 通過 xml 或註解的方式將要執行的各種 statement 配置起來,並通過 java 對象和 statement 中 sql 的動態參數進行映射生成最終執行的 sql 語句,最後由 Mybatis 框架執行 sql 並將結果映射爲 java 對象並返回;
- 實體類中的屬性需要和數據庫的字段名稱保持一致
環境搭建
- IDEA創建
(1)創建maven項目,輸入名稱
(2)選擇創建位置,即可創建完成
(3)創建數據庫 - pom.xml配置
(1)添加打包方式<packaging>jar</packagiing>
(2)依賴導入
(3)數據庫配置
(4)日誌配置
(5)單元測試導入 - 創建實體類、主配置文件和各個Dao接口的映射配置文件
- 注意事項:
(1)Mybatis的映射配置文件必須和dao的接口在同一結構內即resources
和java
兩個目錄必須是一致的
(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)遍歷結果集進行封裝:- 創建集合;
- 開始循環;
- 根據映射配置文件的返回類型創建對象
E element = (E) Class.forName(配置的全限定類名).newInstance();
; - 封裝對象
封裝的時候使用反射封裝的方式根據名稱獲取每個屬性並賦值,這也就是要求表的列名和實體類屬性一致的原因
; - 將對象添加到集合;
- 繼續下一個;
- 遍歷結束退出返回集合;
(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接口的代理對象