楔子:
一、三層架構:
1、三層架構包含的三層:
界面層(User Interface layer)、業務邏輯層(Business Logic Layer)、資料訪問層(Data access layer),
2、三層的職責:
界面層:接受用戶的資料,呼叫業務邏輯層進行功能處理,回傳結果給客戶端,過去的 servlet 就是界面層的功能,
業務邏輯層:用來進行整個專案的業務邏輯處理,向上為界面層提供處理結果,向下問資料訪問層要資料,
資料訪問層:專門用來進行對資料的增、刪、改、查操作,向上為業務邏輯層提供資料,
3、三層之間處理請求的互動:
(客戶端)<--->界面層<--->業務邏輯層<--->資料訪問層<--->(資料庫)
各層之間的呼叫順序是固定的,不允許跨層訪問,
二、框架:
1、框架(Framework)是一個半成品軟體,將所有的公共的,重復的功能解決掉,幫助程式快速高效的進行開發,它是可復用的,可拓展的,
2、常見的框架 --- SSM:
Spring:它是整合其它框架的框架,它的核心是IOC和AOP,它由20多個模塊構成,在很多領域都提供了很好的解決方案,
SpringMVC:專門用來優化控制器(servlet),提供了極簡單的資料提交,資料攜帶,頁面跳轉等功能,
MyBatis:是持久化層的一個框架,用來進行資料庫訪問的優化,專注于sql陳述句,極大的簡化了JDBC的訪問,
正文:
一、MyBatis 概述:
1、MyBatis 是一個優秀的基于 java 的持久層框架,內部封裝了 jdbc,開發者只需要關注 sql 陳述句本身,而不需要處理加載驅動、創建連接、創建 statement、關閉連接,資源等繁雜的程序,
2、MyBatis 通過 xml 或注解兩種方式將要執行的各種 sql 陳述句配置起來,并通過 java 物件和 sql 的動態引數進行映射生成最終執行的 sql 陳述句,最后由 mybatis 框架執行 sql 并將結果映射為 java 物件并回傳,
3、MyBatis 解決的主要問題:
1)減輕使用 JDBC 的復雜性,不用撰寫,重復創建 Connetion , Statement ;
2)不用撰寫關閉資源代碼;
3)直接使用 java 物件,表示結果資料;
二、MyBatis框架結構:

1、 mybatis組態檔:
【SqlMapConfig.xml】:此檔案作為mybatis的全域組態檔,配置了mybatis的運行環境等資訊,
【mapper.xml】:檔案即sql映射檔案,檔案中配置了操作資料庫的sql陳述句,此檔案需要在SqlMapConfig.xml中加載,
【SqlMapConfig.xml】:是mybatis的核心檔案,mybatis將dao層與sql陳述句分離開來,雖然寫的時候分離開來了,但是執行的時候還是要依靠sql陳述句,所以我們的sql陳述句寫在Mapper.xml中,我們在加載核心的時候,會加載他下面的Mapper.xml,所以sql陳述句便會加載進去了,我們只需要在SqlMapConfig.xml中引入Mapper.xml就可以了,所以最后只需要加載SqlMapConfig.xml這一個核心組態檔,
2、 通過mybatis環境等配置資訊構造SqlSessionFactory即會話工廠,工廠能幫我們去加載核心組態檔,加載了核心組態檔后就創建session,通過session可以對資料庫進行操作,
3、 由會話工廠創建sqlSession即會話,操作資料庫需要通過sqlSession進行,
4、 mybatis底層自定義了Executor執行器介面操作資料庫,Executor介面有兩個實作,一個是基本執行器、一個是快取執行器,Executor是執行者,我們不需要管,因為mybatis已經為我們封裝好了,mybatis直接執行sql陳述句,
5、 Mapped Statement也是mybatis一個底層封裝物件,它包裝了mybatis配置資訊及sql映射資訊等,mapper.xml檔案中一個sql對應一個Mapped Statement物件,sql的id即是Mapped statement的id,
6、 Mapped Statement對sql執行輸入引數進行定義,包括HashMap、基本型別、pojo,Executor通過Mapped Statement在執行sql前將輸入的java物件映射至sql中,輸入引數映射就是jdbc編程中對preparedStatement設定引數,
7、 Mapped Statement對sql執行輸出結果進行定義,包括HashMap、基本型別、pojo,Executor通過Mapped Statement在執行sql后將輸出結果映射至java物件中,輸出結果映射程序相當于jdbc編程中對結果的決議處理程序,
8、Mapped Statement是輸入與輸出中間程序中產生的一些物件,通過這些物件去訪問資料庫,
總結:
工廠能幫我們去加載核心組態檔,同時創建會話,會話里面有執行者,執行sql陳述句,在執行sql陳述句的程序中產生物件,通過Mapped Statement封裝成物件,執行sql陳述句就要需要輸入引數和輸出引數,
三、MyBatis 的使用:
1、添加框架的步驟:
1)添加依賴
2)添加組態檔
2、具體步驟:
1)新建庫,新建表
2)新建Maven專案,勾選 Create from archetype,選擇quickstart模板
3)修改目錄:添加缺失的目錄,修改目錄屬性
4)修改pom.xml檔案:添加MyBatis的依賴,添加mysql的依賴
5)修改pom.xml檔案:添加資源檔案指定
6)在idea中添加資料庫的可視化
7)添加jdbc.properties 屬性檔案(資料庫的配置)
8)添加SqlMapConfig.xml檔案,MyBatis的核心組態檔
9)創建物體類Student,用來封裝資料
10)添加完成學生表的增刪改查的功能的StudentMapper.xml 檔案
11)創建測驗類,進行功能測驗
3、資料庫預準備:
創建ssm庫,建表student:
CREATE DATABASE ssm DEFAULT CHARSET utf8;
use ssm;
CREATE TABLE `student` (
`id` int(11) AUTO_INCREMENT primary key ,
`name` varchar(255) DEFAULT NULL,
`email` varchar(255) DEFAULT NULL,
`age` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into student(name,email,age) values('張三','[email protected]',22);
insert into student(name,email,age) values('李四','[email protected]',21);
insert into student(name,email,age) values('王五','[email protected]',22);
insert into student(name,email,age) values('趙六','[email protected]',24);
四、MyBatis 物件分析:
1、 Resources 類:
Resources 類,顧名思義就是資源,用于讀取資源檔案,其有很多方法通過加載并決議資源檔案,回傳不同型別的 IO 流物件,
2、SqlSessionFactoryBuilder 類
SqlSessionFactory 的創建 , 需要使用 SqlSessionFactoryBuilder 物件的 build() 方法 , 由于SqlSessionFactoryBuilder物件在創建完工廠物件后,就完成了其使命,即可被銷毀,所以,一般會將該物件創建為一個方法內的區域物件,方法結束,物件銷毀,
3、SqlSessionFactory 介面
SqlSessionFactory 介面物件是一個重量級物件(系統開銷大的物件),是執行緒安全的,所以一個應用只需要一個該物件即可,創建 SqlSession 需要使用 SqlSessionFactory 介面的的 openSession()方法,
1)openSession(true):創建一個有自動提交功能的SqlSession
2)openSession(false):創建一個非自動提交功能的 SqlSession,需手動提交
3)openSession():同 openSession(false)
4、SqlSession 介面
SqlSession 介面物件用于執行持久化操作,一個 SqlSession 對應著一次資料庫會話,一次會話以SqlSession 物件的創建開始,以 SqlSession 物件的關閉結束,
SqlSession 介面物件是執行緒不安全的,所以每次資料庫會話結束前,需要馬上呼叫其 close()方法,將其關閉,再次需要會話,再次創建, SqlSession 在方法內部創建,使用完畢后關閉,
五、一堆栗子:
1、module 目錄結構:

2、pom.xml:
<?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.burning</groupId>
<artifactId>mybatis_001_student</artifactId>
<version>1.0</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!--記得修改對應的JDK版本-->
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<!--添加依賴-->
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!--mybatis框架依賴-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.9</version>
</dependency>
<!--mysql依賴-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.27</version>
</dependency>
</dependencies>
<build>
<!--添加資源檔案的指定(為了保證在原始碼中用到的各種組態檔,在編譯之后,都順利地到我tomcat指定的目錄下)-->
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
</resource>
</resources>
</build>
</project>
3、jdbc.properties:
//這是博主的mysql配置資訊,記得要修改為你的資訊喲~
jdbc.driverClassName=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm?useUnicode=true&characterEncoding=utf8
jdbc.username=root
jdbc.password=888
4、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">
<!--configuration 下的子標簽的順序不能變-->
<configuration>
<!--讀取屬性檔案(jdbc.properties)
屬性(兩種方式):
resource:從resource錄下找指定名稱的檔案加載
url:使用絕對路徑加載屬性檔案
例如:(記得把"\"改為“/”或者“\\”)
C:\java\mybatis\mybatis-course\mybatis_001_student\src\main\resources\jdbc.properties
-->
<properties resource="jdbc.properties"></properties>
<!--設定日志輸出底層執行的代碼-->
<settings>
<setting name="logImpl" value="https://www.cnblogs.com/Burning-youth/archive/2022/05/06/STDOUT_LOGGING"/>
</settings>
<!--注冊物體類的別名-->
<typeAliases>
<!-- <!–單個物體類別名的注冊–>-->
<!-- <typeAlias type="org.burning.entity.Student" alias="student"></typeAlias>-->
<!--批量注冊別名
別名是類名的駝峰命名法
-->
<package name="org.burning.entity"/>
</typeAliases>
<!--配置資料庫的環境變數(資料庫連接配置)
default:根據下面不同environment的id決定使用哪種資料庫連接配置
-->
<environments default="development">
<!--開發時在公司時使用的配置-->
<environment id="development"><!--id:就是提供給environments的default屬性使用-->
<!--配置事務管理器
type:指定事務管理的模式
JDBC:事務的控制交給程式員控制
MANAGED:由容器(spring)來管理事務
-->
<transactionManager type="JDBC"></transactionManager>
<!--配置資料源
type:指定不同的配置方式
JNDI:java命名目錄介面,在服務器端進行資料庫連接池的管理
POOLED:使用資料庫連接池
UNPOOLED:不使用資料庫連接池
-->
<dataSource type="POOLED">
<!--配置資料庫連接的基本引數
private String driver;
private String url;
private String username;
private String password;
-->
<property name="driver" value="https://www.cnblogs.com/Burning-youth/archive/2022/05/06/${jdbc.driverClassName}"/>
<property name="url" value="https://www.cnblogs.com/Burning-youth/archive/2022/05/06/${jdbc.url}"/>
<property name="username" value="https://www.cnblogs.com/Burning-youth/archive/2022/05/06/${jdbc.username}"/>
<property name="password" value="https://www.cnblogs.com/Burning-youth/archive/2022/05/06/${jdbc.password}"/>
</dataSource>
</environment>
<!--因為這里面都沒有配內容,所以先將下面兩個配置注釋掉-->
<!--在家資料庫的配置-->
<!-- <environment id="home">-->
<!-- <transactionManager type=""></transactionManager>-->
<!-- <dataSource type=""></dataSource>-->
<!-- </environment>-->
<!--上線后的資料庫的配置-->
<!-- <environment id="online">-->
<!-- <transactionManager type=""></transactionManager>-->
<!-- <dataSource type=""></dataSource>-->
<!-- </environment>-->
</environments>
<!--注冊mapper.xml
resource:從resources目錄下找指定名稱的檔案加載
url:使用絕對路徑加載屬性檔案
class:動態代理方式下的注冊
-->
<mappers>
<mapper resource="StudentMapper.xml"></mapper>
</mappers>
</configuration>
5、Student.java:
package org.burning.entity;
public class Student {
private Integer id;
private String name;
private String email;
private Integer age;
public Student() {
}
public Student(String name, String email, Integer age) {
this.name = name;
this.email = email;
this.age = age;
}
public Student(Integer id, String name, String email, Integer age) {
this.id = id;
this.name = name;
this.email = email;
this.age = age;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", email='" + email + '\'' +
", age=" + age +
'}';
}
}
6、StudentMapper.xml:
<?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:是整個檔案的大標簽,用來開始和結束xml檔案
屬性:
namespace:指定命名空間(相當于包名),用來區分不同mapper.xml檔案中相同的id屬性
-->
<mapper namespace="wgd">
<!--完成查詢全部學生的功能
resultType:指定查詢回傳的結果集的型別,如果是集合,則必須是泛型的型別
parameterType:如果有引數,則通過它來指定引數的型別
-->
<select id="getAll" resultType="student">
select id,name,email,age
from student
</select>
<!--按主鍵id查詢學生資訊
-->
<select id="getById" parameterType="int" resultType="student">
select id,name,email,age
from student
where id=#{id}
</select>
<!--按學生名稱模糊查詢
判斷使用 ${} 還是 #{} ?
如果要在字串中使用,則用${},否則用 #{}
-->
<select id="getByName" parameterType="string" resultType="student">
select id,name,email,age
from student
where name like '%${name}%'
</select>
<!--增加學生-->
<insert id="insert" parameterType="student">
insert into student (name,email,age) value (#{name},#{email},#{age})
</insert>
<!--按主鍵洗掉學生-->
<delete id="deleteById" parameterType="int">
delete from student
where id=#{id}
</delete>
<!--按主鍵更新學生-->
<update id="updateById" parameterType="student">
update student set name=#{name},email=#{email},age=#{age}
where id=#{id}
</update>
</mapper>
7、Mytest.java:
package org.burning.test;
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 org.burning.entity.Student;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class Mytest {
SqlSession sqlSession;
//在所有的@Test方法執行前先執行的代碼
@Before
public void openSqlSession() throws IOException {
//使用檔案流讀取核心組態檔SqlMapConfig.xml
InputStream in = Resources.getResourceAsStream
("SqlMapConfig.xml");
//創建SqlSessionFactory工廠
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//取出SqlSession的物件
sqlSession = factory.openSession();
}
//在所有的@Test方法執行后執行的代碼
@After
public void closeSqlSession() {
sqlSession.close();
}
@Test
public void testGetAll() throws IOException {
//完成查詢操作
List<Student> list = sqlSession.selectList("wgd.getAll");
list.forEach(student -> System.out.println(student));
}
@Test
public void testGetById() throws IOException {
//按主鍵完成查詢操作
Student student = sqlSession.selectOne("wgd.getById",2);
System.out.println(student);
}
@Test
public void testGetByName() throws IOException {
//按學生名稱關鍵字完成查詢操作
List<Student> studentList = sqlSession.selectList("wgd.getByName","楊");
studentList.forEach(student -> System.out.println(student));
}
@Test
public void testInsert() throws IOException {
//添加學生資訊
int num = sqlSession.insert("wgd.insert",new Student("大爺","[email protected]",50));
System.out.println(num);
//切記:在所有的增刪改后,必須手動提交事務!
sqlSession.commit();
}
@Test
public void testDeleteById() throws IOException {
//按學生id完成洗掉操作
int num = sqlSession.delete("wgd.deleteById",21);
System.out.println(num);
//切記:在所有的增刪改后,必須手動提交事務!
sqlSession.commit();
}
@Test
public void testUpdateById() throws IOException {
//按學生id完成更新操作
int num = sqlSession.update("wgd.updateById",new Student(20,"大爺","[email protected]",500));
System.out.println(num);
//切記:在所有的增刪改后,必須手動提交事務!
sqlSession.commit();
}
}
ps:
參考資料鏈接:mybatis框架的架構(圖解) - wyhluckydog - 博客園 (cnblogs.com)
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/469814.html
標籤:其他
