詳解如何使用MyBatis簡化JDBC開發(fā)
1. 前言
JavaEE 企業(yè)級(jí) Java 項(xiàng)目中的經(jīng)典三層架構(gòu)為表現(xiàn)層,業(yè)務(wù)層和持久層,使用Java 代碼操作數(shù)據(jù)庫屬于持久層內(nèi)容,而 MyBatis 對(duì) JDBC 代碼進(jìn)行了封裝,作為一款優(yōu)秀的持久層框架,專門用于簡化JDBC開發(fā)。
MyBatis 支持自定義 SQL,存儲(chǔ)過程以及高級(jí)映射。MyBatis 免除了幾乎所有的 JDBC 代碼以及設(shè)置參數(shù)和獲取結(jié)果集的工作。MyBatis 可以通過簡單的 XML 或注解來配置和映射原始類型,接口和 Java POJO(Plain Old Java Objects,普通老式 Java 對(duì)象)為數(shù)據(jù)庫中的記錄。
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ù)庫時(shí),我們一般分為注冊(cè)驅(qū)動(dòng),獲取連接,定義sql,設(shè)置參數(shù)值,獲取 sql 執(zhí)行對(duì)象,執(zhí)行 sql,處理返回?cái)?shù)據(jù),釋放資源等幾個(gè)步驟。下面使用一個(gè)簡單的例子分析 JDBC 究竟存在哪些缺點(diǎn)。
需求:使用 Java 代碼操作數(shù)據(jù)庫,查詢學(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(); } }
上面是一段簡單標(biāo)準(zhǔn)的使用 JDBC 操作數(shù)據(jù)庫的代碼,分析代碼我們不難看出,在注冊(cè)驅(qū)動(dòng),獲取連接和定義 sql 部分,代碼中出現(xiàn)了大量的字符串信息,這些字符串信息非常不利于后期的維護(hù),例如后期修改要連接的數(shù)據(jù)庫等。我們把這個(gè)問題稱為 JDBC 的硬編碼問題。示例,存在硬編碼問題的代碼:
//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)了大量的相似代碼,例如將來的參數(shù)較多時(shí),手動(dòng)設(shè)置參數(shù)也是一件麻煩的事情等,這個(gè)問題被稱為 JDBC 的操作繁瑣問題。示例,存在操作繁瑣問題的代碼:
//設(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)很多操作繁瑣等的問題,那么這個(gè)問題怎么解決呢?前面說使用 MyBatis 簡化 JDBC 開發(fā),那么具體是怎么避免這些問題的呢?
首先,要解決操作繁瑣的問題,只需要讓JDBC中手動(dòng)設(shè)置參數(shù)和手動(dòng)封裝結(jié)果集對(duì)象的操作由程序自動(dòng)封裝完成。例如下面一行代碼就解決了 JDBC 封裝結(jié)果集對(duì)象操作繁瑣的問題:
List<Student> students = sqlSession.selectList("test.selectAll"); //參數(shù)是一個(gè)字符串,該字符串必須是映射配置文件的namespace.id
MyBatis 將注冊(cè)驅(qū)動(dòng),獲取連接,定義sql 的語句從 Java 代碼中抽離,并單獨(dú)寫到配置文件中,解決了硬編碼的問題。例如:在 mybatis-cinfig.xml
配置文件中定義數(shù)據(jù)庫連接信息。
4. MyBatis 快速入門
每一個(gè)初學(xué)者,在學(xué)習(xí)一門全新的技術(shù)時(shí),都要在實(shí)戰(zhàn)練習(xí)中掌握其使用方法。今天,我們使用一個(gè)小小的案例來入門 MyBatis,學(xué)會(huì) MyBatis 的基本使用。
需求:查詢數(shù)據(jù)庫中 student 表中所有的數(shù)據(jù)。
我們使用以下 5 個(gè)步驟來解決這個(gè)問題:
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 語句
- 釋放資源
接下來,我們按照上面的步驟講解需求中的問題,學(xué)習(xí) MyBatis 的基本使用。下面為詳細(xì)過程和代碼演示,整個(gè)過程的分析參考文末的過程剖析。
第一步:創(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:用來設(shè)置打印級(jí)別,大小寫無關(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 硬編碼的問題。在模塊下的 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ù)庫連接環(huán)境信息??梢耘渲枚鄠€(gè)environment,通過default屬性切換不同的environment --> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <!--數(shù)據(jù)庫連接信息--> <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ù)庫連接信息--> <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 語句,同樣也是為了解決 JDBC 硬編碼的問題。在模塊的 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 + '\'' + '}'; } }
接下來在 org.chengzi
包下創(chuàng)建 MyBatisDemo 測(cè)試類,用于加載核心配置文件,獲取SqlSessionFactory 對(duì)象,獲取 SQLSession 對(duì)象并執(zhí)行 sql 語句,最后釋放資源。
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ì)象,用它來執(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(); } }
過程剖析:
在使用 MyBatis 持久層框架開發(fā)時(shí),我們首先創(chuàng)建 Maven 模塊,使用 Maven 構(gòu)建和管理這個(gè) Java 項(xiàng)目,所以我們要導(dǎo)入項(xiàng)目依賴的坐標(biāo)信息,例如 MySQL 數(shù)據(jù)庫的驅(qū)動(dòng)坐標(biāo),用于單元測(cè)試的 Junit 和用于查看日志信息的依賴坐標(biāo)。
接下來是編寫 MyBatis 核心配置文件,一般命名為 mybatis-config.xml
,其中<environments>
標(biāo)簽用于配置數(shù)據(jù)庫連接環(huán)境信息,可以配置多個(gè)<environment>
標(biāo)簽,通過 default 屬性切換不同的環(huán)境。我們還要定義<mapper>
標(biāo)簽用于加載 sql 映射文件。
而 sql 映射文件在哪里呢?接下來一步就是編寫 sql 映射文件,在模塊的 resources 文件目錄下創(chuàng)建映射文件的核心配置文件,一般命名有其語法規(guī)則,使用 xxxMapper.xml
命名,而 xxx 表示要操作的數(shù)據(jù)庫表。其中使用 namespace 作為命名空間,而 id 作為標(biāo)簽中 sql 語句的唯一標(biāo)識(shí),使用命名空間的方式類似于 Java 中包的概念,允許在不同的命名空間中存在相同名稱的 id ,方便在不同的 sql 映射文件中使用相同的 id,resultType 參數(shù)表示對(duì)應(yīng)語句返回結(jié)果的類型,例如案例中將數(shù)據(jù)包裝為 Student 類型的對(duì)象,其 resultType 參數(shù)的值就為 Student。
接下來就是定義 POJO 實(shí)體類,用于封裝查詢結(jié)果數(shù)據(jù),例如案例中查詢學(xué)生表,將每條記錄封裝為一個(gè)對(duì)象,這里就在 POJO 包中定義 Student 類。
最后就是核心的一部分,編寫相關(guān)測(cè)試類來操作數(shù)據(jù)庫,在源代碼 Java 文件目錄對(duì)應(yīng)的包中創(chuàng)建測(cè)試類來操作數(shù)據(jù)庫并封裝結(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)建過程可以多參考官網(wǎng)給出的示例教程和代碼,直接 C V 到 IDE 練習(xí)即可。
本文是 MyBatis 持久層框架的入門篇,MyBatis 作為大多數(shù)Java 開發(fā)者第一個(gè)學(xué)習(xí)的大型框架,其思想十分重要,慢慢體會(huì)其中每個(gè)步驟的意義,多練習(xí)就能熟練掌握。
以上就是詳解如何使用MyBatis簡化JDBC開發(fā)的詳細(xì)內(nèi)容,更多關(guān)于MyBatis簡化JDBC開發(fā)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Spring?boot集成easy?excel實(shí)現(xiàn)導(dǎo)入導(dǎo)出功能
這篇文章主要介紹了Spring?boot集成easy?excel實(shí)現(xiàn)導(dǎo)入導(dǎo)出操作,使用easyexcel,首先要引入easyexcel的maven依賴,具體的版本根據(jù)你的需求去設(shè)置,本文結(jié)合實(shí)例代碼講解的非常詳細(xì),需要的朋友可以參考下2024-05-05SpringBoot?基于?MongoTemplate?的工具類過程詳解
MongoDB是一個(gè)高性能,開源,無模式的文檔型數(shù)據(jù)庫,是當(dāng)前NoSql數(shù)據(jù)庫中比較熱門的一種,這篇文章主要介紹了SpringBoot基于MongoTemplate的工具類,需要的朋友可以參考下2023-09-09解決Error:(5,55)java:程序包org.springframework.cloud.netflix.eure
這篇文章主要介紹了解決Error:(5,55)java:程序包org.springframework.cloud.netflix.eureka.server不存在問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11Springboot簡單熱部署實(shí)現(xiàn)步驟解析
這篇文章主要介紹了Springboot簡單熱部署實(shí)現(xiàn)步驟解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-12-12Spring Boot 集成 Mybatis Plus 自動(dòng)填充字段的實(shí)例詳解
這篇文章主要介紹了Spring Boot 集成 Mybatis Plus 自動(dòng)填充字段,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03