詳解如何使用MyBatis簡(jiǎn)化JDBC開發(fā)
1. 前言
JavaEE 企業(yè)級(jí) Java 項(xiàng)目中的經(jīng)典三層架構(gòu)為表現(xiàn)層,業(yè)務(wù)層和持久層,使用Java 代碼操作數(shù)據(jù)庫(kù)屬于持久層內(nèi)容,而 MyBatis 對(duì) JDBC 代碼進(jìn)行了封裝,作為一款優(yōu)秀的持久層框架,專門用于簡(jiǎn)化JDBC開發(fā)。

MyBatis 支持自定義 SQL,存儲(chǔ)過(guò)程以及高級(jí)映射。MyBatis 免除了幾乎所有的 JDBC 代碼以及設(shè)置參數(shù)和獲取結(jié)果集的工作。MyBatis 可以通過(guò)簡(jiǎn)單的 XML 或注解來(lái)配置和映射原始類型,接口和 Java POJO(Plain Old Java Objects,普通老式 Java 對(duì)象)為數(shù)據(jù)庫(kù)中的記錄。
MyBatis 本是 Apache 的一個(gè)開源項(xiàng)目 iBatis, 2010 年這個(gè)項(xiàng)目由 Apache software foundation 遷移到了google code,并且改名為 MyBatis 。2013 年 11 月遷移到 Github。
小tips:在學(xué)習(xí)一門全新的技術(shù)前,盡量做到從頭到尾通讀官網(wǎng)信息,MyBatis 的中文版官網(wǎng)相比于其他的網(wǎng)站還是非常友好的,建議首先閱讀官網(wǎng)信息。
什么是框架呢?
框架的概念其實(shí)不難理解,這里的框架是指一個(gè)半成品的軟件,是一套可重用,通用的,軟件基礎(chǔ)代碼模型,在框架基礎(chǔ)之上構(gòu)建項(xiàng)目使編碼更加高效,規(guī)范,通用并且擴(kuò)展性強(qiáng)。
2. JDBC 存在的缺點(diǎn)
之前使用 JDBC 代碼操作數(shù)據(jù)庫(kù)時(shí),我們一般分為注冊(cè)驅(qū)動(dòng),獲取連接,定義sql,設(shè)置參數(shù)值,獲取 sql 執(zhí)行對(duì)象,執(zhí)行 sql,處理返回?cái)?shù)據(jù),釋放資源等幾個(gè)步驟。下面使用一個(gè)簡(jiǎn)單的例子分析 JDBC 究竟存在哪些缺點(diǎn)。
需求:使用 Java 代碼操作數(shù)據(jù)庫(kù),查詢學(xué)生表中所有男生信息,并且將其封裝為對(duì)象,最終存放在集合中。
public class JDBCDemo {
public static void main(String[] args) throws Exception {
//1. 注冊(cè)驅(qū)動(dòng)
Class.forName("com.mysql.jdbc.Driver");
//2. 獲取連接
String url = "jdbc:mysql://localhost:3306/blog?useSSL=false";
String username = "root";
String ppassword = "abc123";//密碼
Connection conn = DriverManager.getConnection(url, username, password);
//接收輸入的查詢條件
String gender = "男";
//3. 定義sql
String sql = "select * from student where gender=?";
//4. 獲取sql執(zhí)行對(duì)象
Statement stmt = conn.createStatement();
//設(shè)置參數(shù)的值
pstmt.setString(1,gender);
//5. 執(zhí)行sql
ResultSet rs = stmt.executeQuery(sql);
//6. 處理結(jié)果
//遍歷結(jié)果集,獲取數(shù)據(jù),封裝為對(duì)象,裝入集合
Student s = null;
List<Student> students = new ArrayList<>();
while (rs.next()) {
s = new Student();
int id = rs.getInt(1);
String name = rs.getString(2);
String gender = rs.getString(3);
s.setId(id);
s.setName(name);
s.setGender(gender);
students.add(s);
}
System.out.println(students);
//7. 釋放資源
rs.close();
stmt.close();
conn.close();
}
}
上面是一段簡(jiǎn)單標(biāo)準(zhǔn)的使用 JDBC 操作數(shù)據(jù)庫(kù)的代碼,分析代碼我們不難看出,在注冊(cè)驅(qū)動(dòng),獲取連接和定義 sql 部分,代碼中出現(xiàn)了大量的字符串信息,這些字符串信息非常不利于后期的維護(hù),例如后期修改要連接的數(shù)據(jù)庫(kù)等。我們把這個(gè)問(wèn)題稱為 JDBC 的硬編碼問(wèn)題。示例,存在硬編碼問(wèn)題的代碼:
//1. 注冊(cè)驅(qū)動(dòng)
Class.forName("com.mysql.jdbc.Driver");
//2. 獲取連接
String url = "jdbc:mysql://localhost:3306/blog?useSSL=false";
String username = "root";
String ppassword = "abc123";//密碼
Connection conn = DriverManager.getConnection(url, username, password);
//接收輸入的查詢條件
String gender = "男";
//3. 定義sql
String sql = "select * from student where gender=?";
在手動(dòng)設(shè)置參數(shù),封住結(jié)果集對(duì)象部分,代碼中出現(xiàn)了大量的相似代碼,例如將來(lái)的參數(shù)較多時(shí),手動(dòng)設(shè)置參數(shù)也是一件麻煩的事情等,這個(gè)問(wèn)題被稱為 JDBC 的操作繁瑣問(wèn)題。示例,存在操作繁瑣問(wèn)題的代碼:
//設(shè)置參數(shù)的值
pstmt.setString(1,gender);
//5. 執(zhí)行sql
ResultSet rs = stmt.executeQuery(sql);
//6. 處理結(jié)果
//遍歷結(jié)果集,獲取數(shù)據(jù),封裝為對(duì)象,裝入集合
Student s = null;
List<Student> students = new ArrayList<>();
while (rs.next()) {
s = new Student();
int id = rs.getInt(1);
String name = rs.getString(2);
String gender = rs.getS
s.setId(id);
s.setName(name);
s.setGender
students.add(s);
}
JDBC的缺點(diǎn),如下圖:

3. MyBatis 優(yōu)化
JDBC 作為基礎(chǔ)性的代碼,固然會(huì)出現(xiàn)很多操作繁瑣等的問(wèn)題,那么這個(gè)問(wèn)題怎么解決呢?前面說(shuō)使用 MyBatis 簡(jiǎn)化 JDBC 開發(fā),那么具體是怎么避免這些問(wèn)題的呢?
首先,要解決操作繁瑣的問(wèn)題,只需要讓JDBC中手動(dòng)設(shè)置參數(shù)和手動(dòng)封裝結(jié)果集對(duì)象的操作由程序自動(dòng)封裝完成。例如下面一行代碼就解決了 JDBC 封裝結(jié)果集對(duì)象操作繁瑣的問(wèn)題:
List<Student> students = sqlSession.selectList("test.selectAll"); //參數(shù)是一個(gè)字符串,該字符串必須是映射配置文件的namespace.id
MyBatis 將注冊(cè)驅(qū)動(dòng),獲取連接,定義sql 的語(yǔ)句從 Java 代碼中抽離,并單獨(dú)寫到配置文件中,解決了硬編碼的問(wèn)題。例如:在 mybatis-cinfig.xml 配置文件中定義數(shù)據(jù)庫(kù)連接信息。
4. MyBatis 快速入門
每一個(gè)初學(xué)者,在學(xué)習(xí)一門全新的技術(shù)時(shí),都要在實(shí)戰(zhàn)練習(xí)中掌握其使用方法。今天,我們使用一個(gè)小小的案例來(lái)入門 MyBatis,學(xué)會(huì) MyBatis 的基本使用。
需求:查詢數(shù)據(jù)庫(kù)中 student 表中所有的數(shù)據(jù)。
我們使用以下 5 個(gè)步驟來(lái)解決這個(gè)問(wèn)題:
1.創(chuàng)建 student 表,添加數(shù)據(jù)
2.創(chuàng)建新項(xiàng)目,創(chuàng)建Maven模塊,導(dǎo)入坐標(biāo)
3.編寫MyBatis核心配置文件
4.編寫sql映射文件
5.編寫代碼
- 定義 POJO實(shí)體類
- 加載核心配置文件,獲取 SqlSessionFactory 對(duì)象
- 獲取 SqlSession 對(duì)象,執(zhí)行 sql 語(yǔ)句
- 釋放資源
接下來(lái),我們按照上面的步驟講解需求中的問(wèn)題,學(xué)習(xí) MyBatis 的基本使用。下面為詳細(xì)過(guò)程和代碼演示,整個(gè)過(guò)程的分析參考文末的過(guò)程剖析。
第一步:創(chuàng)建 student 表,添加數(shù)據(jù)
drop table if exists student;
create table student(
id int primary key auto_increment,
name varchar(10),
gender char(1)
);
insert into student(name,gender) values
('張三','男'),
('李四','女'),
('王五','男');
第二步:
創(chuàng)建空項(xiàng)目,創(chuàng)建 Maven 模塊,項(xiàng)目結(jié)構(gòu)如下圖:

在創(chuàng)建好的模塊中的 pom.xml 配置文件中添加依賴坐標(biāo),點(diǎn)擊刷新使坐標(biāo)信息生效:
<dependencies>
<!--mybatis 依賴-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.5</version>
</dependency>
<!--mysql 驅(qū)動(dòng)-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.46</version>
</dependency>
<!--junit 單元測(cè)試-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
<!-- 添加slf4j日志api -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.20</version>
</dependency>
<!-- 添加logback-classic依賴 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<!-- 添加logback-core依賴 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.3</version>
</dependency>
</dependencies>
在 resources 目錄下創(chuàng)建 logback 的配置文件 logback.xml,用于查看日志信息:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!--
CONSOLE :表示當(dāng)前的日志信息是可以輸出到控制臺(tái)的。
-->
<appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>[%level] %blue(%d{HH:mm:ss.SSS}) %cyan([%thread]) %boldGreen(%logger{15}) - %msg %n</pattern>
</encoder>
</appender>
<logger name="org.chengzi" level="DEBUG" additivity="false">
<appender-ref ref="Console"/>
</logger>
<!--
level:用來(lái)設(shè)置打印級(jí)別,大小寫無(wú)關(guān):TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF, 默認(rèn)debug
<root>可以包含零個(gè)或多個(gè)<appender-ref>元素,標(biāo)識(shí)這個(gè)輸出位置將會(huì)被本日志級(jí)別控制。
-->
<root level="DEBUG">
<appender-ref ref="Console"/>
</root>
</configuration>
第三步:編寫 MyBatis 核心配置文件
編寫 MyBatis 核心配置文件,可以用于替換連接信息,解決了 JDBC 硬編碼的問(wèn)題。在模塊下的 resources 目錄下創(chuàng)建 MyBatis 的配置文件 mybatis-config.xml,內(nèi)容如下:
<?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>
<typeAliases>
<package name="org.chengzi.pojo"/>
</typeAliases>
<!--
environments:配置數(shù)據(jù)庫(kù)連接環(huán)境信息??梢耘渲枚鄠€(gè)environment,通過(guò)default屬性切換不同的environment
-->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<!--數(shù)據(jù)庫(kù)連接信息-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/blog?useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="abc123"/>
</dataSource>
</environment>
<environment id="test">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<!--數(shù)據(jù)庫(kù)連接信息-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/blog?useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="abc123"/>
</dataSource>
</environment>
</environments>
<mappers>
<!--加載sql映射文件-->
<mapper resource="StudentMapper.xml"/>
</mappers>
</configuration>
這里使用了<typeAliases>標(biāo)簽以后,在 sql 映射配置文件中的 resultType 的值可以直接設(shè)置為 Student ,而不是:

第四步:編寫 sql 映射文件
編寫 sql 映射配置文件,用于統(tǒng)一管理 sql 語(yǔ)句,同樣也是為了解決 JDBC 硬編碼的問(wèn)題。在模塊的 resources 目錄下創(chuàng)建映射配置文件 StudentMapper.xml ,內(nèi)容如下:
<?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="test">
<select id="selectAll" resultType="org.chengzi.pojo.User">
select * from student;
</select>
</mapper>
第五步:編寫代碼
在編寫代碼時(shí),大概可以分為四步。首先是定義 POJO 類,在指定的包下創(chuàng)建 Student 類,如下:
package org.chengzi.pojo;
public class Student {
private int id;
private String name;
private String gender;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", gender='" + gender + '\'' +
'}';
}
}
接下來(lái)在 org.chengzi 包下創(chuàng)建 MyBatisDemo 測(cè)試類,用于加載核心配置文件,獲取SqlSessionFactory 對(duì)象,獲取 SQLSession 對(duì)象并執(zhí)行 sql 語(yǔ)句,最后釋放資源。
public class MyBatisDemo {
public static void main(String[] args) throws IOException {
//1. 加載mybatis的核心配置文件,獲取 SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//2. 獲取SqlSession對(duì)象,用它來(lái)執(zhí)行sql
SqlSession sqlSession = sqlSessionFactory.openSession();
//3. 執(zhí)行sql
List<Student> students = sqlSession.selectList("test.selectAll"); //參數(shù)是一個(gè)字符串,該字符串必須是映射配置文件的namespace.id
System.out.println(students);
//4. 釋放資源
sqlSession.close();
}
}
過(guò)程剖析:
在使用 MyBatis 持久層框架開發(fā)時(shí),我們首先創(chuàng)建 Maven 模塊,使用 Maven 構(gòu)建和管理這個(gè) Java 項(xiàng)目,所以我們要導(dǎo)入項(xiàng)目依賴的坐標(biāo)信息,例如 MySQL 數(shù)據(jù)庫(kù)的驅(qū)動(dòng)坐標(biāo),用于單元測(cè)試的 Junit 和用于查看日志信息的依賴坐標(biāo)。
接下來(lái)是編寫 MyBatis 核心配置文件,一般命名為 mybatis-config.xml,其中<environments>標(biāo)簽用于配置數(shù)據(jù)庫(kù)連接環(huán)境信息,可以配置多個(gè)<environment>標(biāo)簽,通過(guò) default 屬性切換不同的環(huán)境。我們還要定義<mapper> 標(biāo)簽用于加載 sql 映射文件。
而 sql 映射文件在哪里呢?接下來(lái)一步就是編寫 sql 映射文件,在模塊的 resources 文件目錄下創(chuàng)建映射文件的核心配置文件,一般命名有其語(yǔ)法規(guī)則,使用 xxxMapper.xml 命名,而 xxx 表示要操作的數(shù)據(jù)庫(kù)表。其中使用 namespace 作為命名空間,而 id 作為標(biāo)簽中 sql 語(yǔ)句的唯一標(biāo)識(shí),使用命名空間的方式類似于 Java 中包的概念,允許在不同的命名空間中存在相同名稱的 id ,方便在不同的 sql 映射文件中使用相同的 id,resultType 參數(shù)表示對(duì)應(yīng)語(yǔ)句返回結(jié)果的類型,例如案例中將數(shù)據(jù)包裝為 Student 類型的對(duì)象,其 resultType 參數(shù)的值就為 Student。
接下來(lái)就是定義 POJO 實(shí)體類,用于封裝查詢結(jié)果數(shù)據(jù),例如案例中查詢學(xué)生表,將每條記錄封裝為一個(gè)對(duì)象,這里就在 POJO 包中定義 Student 類。
最后就是核心的一部分,編寫相關(guān)測(cè)試類來(lái)操作數(shù)據(jù)庫(kù),在源代碼 Java 文件目錄對(duì)應(yīng)的包中創(chuàng)建測(cè)試類來(lái)操作數(shù)據(jù)庫(kù)并封裝結(jié)果集對(duì)象。內(nèi)容大致為加載核心配置文件 mybatis-config.xml ,獲取 SqlSessionFactory 類對(duì)象,使用該對(duì)象的openSession() 方法獲取 SqlSession 對(duì)象,用于執(zhí)行 sql,然后封裝結(jié)果集對(duì)象 ,此時(shí)傳入的參數(shù)是一個(gè)字符串,該字符串是映射配置文件的 namespace.id ,最后釋放資源。
5. 總結(jié)
初學(xué)者入門時(shí),整個(gè)構(gòu)建過(guò)程可以多參考官網(wǎng)給出的示例教程和代碼,直接 C V 到 IDE 練習(xí)即可。
本文是 MyBatis 持久層框架的入門篇,MyBatis 作為大多數(shù)Java 開發(fā)者第一個(gè)學(xué)習(xí)的大型框架,其思想十分重要,慢慢體會(huì)其中每個(gè)步驟的意義,多練習(xí)就能熟練掌握。
以上就是詳解如何使用MyBatis簡(jiǎn)化JDBC開發(fā)的詳細(xì)內(nèi)容,更多關(guān)于MyBatis簡(jiǎn)化JDBC開發(fā)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
一文詳解Java如何使用commons-csv搞定CSV文件操作
在?Java?開發(fā)中,處理?CSV(逗號(hào)分隔值)文件是一項(xiàng)常見的任務(wù),本文將利用Apache?Commons?CSV?庫(kù)實(shí)現(xiàn)讀取,寫入和操作CSV文件,希望對(duì)大家有所幫助2025-02-02
springboot項(xiàng)目中idea的pom.xml文件的引用標(biāo)簽全部爆紅問(wèn)題解決
這篇文章主要介紹了springboot項(xiàng)目中idea的pom.xml文件的引用標(biāo)簽全部爆紅問(wèn)題解決,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),需要的朋友參考下吧2023-12-12
IDEA2021.2永久激活碼最新超詳細(xì)(激活到2099)
這篇文章主要介紹了IDEA2021.2永久激活碼,是idea2021版最新激活方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09
常用json與javabean互轉(zhuǎn)的方法實(shí)現(xiàn)
這篇文章主要介紹了常用json與javabean互轉(zhuǎn)的方法實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04
maven如何動(dòng)態(tài)統(tǒng)一修改版本號(hào)的方法步驟
這篇文章主要介紹了maven如何動(dòng)態(tài)統(tǒng)一修改版本號(hào)的方法步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12

