詳解如何使用MyBatis簡(jiǎn)化JDBC開(kāi)發(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)秀的持久層框架,專(zhuān)門(mén)用于簡(jiǎn)化JDBC開(kāi)發(fā)。
MyBatis 支持自定義 SQL,存儲(chǔ)過(guò)程以及高級(jí)映射。MyBatis 免除了幾乎所有的 JDBC 代碼以及設(shè)置參數(shù)和獲取結(jié)果集的工作。MyBatis 可以通過(guò)簡(jiǎn)單的 XML 或注解來(lái)配置和映射原始類(lèi)型,接口和 Java POJO(Plain Old Java Objects,普通老式 Java 對(duì)象)為數(shù)據(jù)庫(kù)中的記錄。
MyBatis 本是 Apache 的一個(gè)開(kāi)源項(xiàng)目 iBatis, 2010 年這個(gè)項(xiàng)目由 Apache software foundation 遷移到了google code,并且改名為 MyBatis 。2013 年 11 月遷移到 Github。
小tips:在學(xué)習(xí)一門(mén)全新的技術(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ù),查詢(xún)學(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); //接收輸入的查詢(xún)條件 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)題稱(chēng)為 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); //接收輸入的查詢(xún)條件 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)題被稱(chēng)為 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 開(kāi)發(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ú)寫(xiě)到配置文件中,解決了硬編碼的問(wèn)題。例如:在 mybatis-cinfig.xml
配置文件中定義數(shù)據(jù)庫(kù)連接信息。
4. MyBatis 快速入門(mén)
每一個(gè)初學(xué)者,在學(xué)習(xí)一門(mén)全新的技術(shù)時(shí),都要在實(shí)戰(zhàn)練習(xí)中掌握其使用方法。今天,我們使用一個(gè)小小的案例來(lái)入門(mén) MyBatis,學(xué)會(huì) MyBatis 的基本使用。
需求:查詢(xún)數(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.編寫(xiě)MyBatis核心配置文件
4.編寫(xiě)sql映射文件
5.編寫(xiě)代碼
- 定義 POJO實(shí)體類(lèi)
- 加載核心配置文件,獲取 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
配置文件中添加依賴(lài)坐標(biāo),點(diǎn)擊刷新使坐標(biāo)信息生效:
<dependencies> <!--mybatis 依賴(lài)--> <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依賴(lài) --> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.3</version> </dependency> <!-- 添加logback-core依賴(lài) --> <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í)別,大小寫(xiě)無(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>
第三步:編寫(xiě) MyBatis 核心配置文件
編寫(xiě) 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 ,而不是:
第四步:編寫(xiě) sql 映射文件
編寫(xiě) 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>
第五步:編寫(xiě)代碼
在編寫(xiě)代碼時(shí),大概可以分為四步。首先是定義 POJO 類(lèi),在指定的包下創(chuàng)建 Student 類(lèi),如下:
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è)試類(lèi),用于加載核心配置文件,獲取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 持久層框架開(kāi)發(fā)時(shí),我們首先創(chuàng)建 Maven 模塊,使用 Maven 構(gòu)建和管理這個(gè) Java 項(xiàng)目,所以我們要導(dǎo)入項(xiàng)目依賴(lài)的坐標(biāo)信息,例如 MySQL 數(shù)據(jù)庫(kù)的驅(qū)動(dòng)坐標(biāo),用于單元測(cè)試的 Junit 和用于查看日志信息的依賴(lài)坐標(biāo)。
接下來(lái)是編寫(xiě) 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)一步就是編寫(xiě) sql 映射文件,在模塊的 resources 文件目錄下創(chuàng)建映射文件的核心配置文件,一般命名有其語(yǔ)法規(guī)則,使用 xxxMapper.xml
命名,而 xxx 表示要操作的數(shù)據(jù)庫(kù)表。其中使用 namespace 作為命名空間,而 id 作為標(biāo)簽中 sql 語(yǔ)句的唯一標(biāo)識(shí),使用命名空間的方式類(lèi)似于 Java 中包的概念,允許在不同的命名空間中存在相同名稱(chēng)的 id ,方便在不同的 sql 映射文件中使用相同的 id,resultType 參數(shù)表示對(duì)應(yīng)語(yǔ)句返回結(jié)果的類(lèi)型,例如案例中將數(shù)據(jù)包裝為 Student 類(lèi)型的對(duì)象,其 resultType 參數(shù)的值就為 Student。
接下來(lái)就是定義 POJO 實(shí)體類(lèi),用于封裝查詢(xún)結(jié)果數(shù)據(jù),例如案例中查詢(xún)學(xué)生表,將每條記錄封裝為一個(gè)對(duì)象,這里就在 POJO 包中定義 Student 類(lèi)。
最后就是核心的一部分,編寫(xiě)相關(guān)測(cè)試類(lèi)來(lái)操作數(shù)據(jù)庫(kù),在源代碼 Java 文件目錄對(duì)應(yīng)的包中創(chuàng)建測(cè)試類(lèi)來(lái)操作數(shù)據(jù)庫(kù)并封裝結(jié)果集對(duì)象。內(nèi)容大致為加載核心配置文件 mybatis-config.xml
,獲取 SqlSessionFactory 類(lèi)對(duì)象,使用該對(duì)象的openSession() 方法獲取 SqlSession 對(duì)象,用于執(zhí)行 sql,然后封裝結(jié)果集對(duì)象 ,此時(shí)傳入的參數(shù)是一個(gè)字符串,該字符串是映射配置文件的 namespace.id ,最后釋放資源。
5. 總結(jié)
初學(xué)者入門(mén)時(shí),整個(gè)構(gòu)建過(guò)程可以多參考官網(wǎng)給出的示例教程和代碼,直接 C V 到 IDE 練習(xí)即可。
本文是 MyBatis 持久層框架的入門(mén)篇,MyBatis 作為大多數(shù)Java 開(kāi)發(fā)者第一個(gè)學(xué)習(xí)的大型框架,其思想十分重要,慢慢體會(huì)其中每個(gè)步驟的意義,多練習(xí)就能熟練掌握。
以上就是詳解如何使用MyBatis簡(jiǎn)化JDBC開(kāi)發(fā)的詳細(xì)內(nèi)容,更多關(guān)于MyBatis簡(jiǎn)化JDBC開(kāi)發(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依賴(lài),具體的版本根據(jù)你的需求去設(shè)置,本文結(jié)合實(shí)例代碼講解的非常詳細(xì),需要的朋友可以參考下2024-05-05SpringBoot?基于?MongoTemplate?的工具類(lèi)過(guò)程詳解
MongoDB是一個(gè)高性能,開(kāi)源,無(wú)模式的文檔型數(shù)據(jù)庫(kù),是當(dāng)前NoSql數(shù)據(jù)庫(kù)中比較熱門(mén)的一種,這篇文章主要介紹了SpringBoot基于MongoTemplate的工具類(lèi),需要的朋友可以參考下2023-09-09解決Error:(5,55)java:程序包org.springframework.cloud.netflix.eure
這篇文章主要介紹了解決Error:(5,55)java:程序包org.springframework.cloud.netflix.eureka.server不存在問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11Springboot簡(jiǎn)單熱部署實(shí)現(xiàn)步驟解析
這篇文章主要介紹了Springboot簡(jiǎn)單熱部署實(shí)現(xiàn)步驟解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-12-12java使用jdbc操作數(shù)據(jù)庫(kù)示例分享
這篇文章主要介紹了java使用jdbc操作數(shù)據(jù)庫(kù)示例,需要的朋友可以參考下2014-03-03Spring Boot 集成 Mybatis Plus 自動(dòng)填充字段的實(shí)例詳解
這篇文章主要介紹了Spring Boot 集成 Mybatis Plus 自動(dòng)填充字段,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03簡(jiǎn)單了解SpringBoot HATEOAS使用方法
這篇文章主要介紹了簡(jiǎn)單了解SpringBoot HATEOAS使用方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-10-10