溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

深入淺出MyBatis:JDBC和MyBatis介紹

發(fā)布時(shí)間:2020-08-04 01:28:01 來(lái)源:網(wǎng)絡(luò) 閱讀:1147 作者:情情說(shuō) 欄目:開(kāi)發(fā)技術(shù)

最近在休陪產(chǎn)假,時(shí)間比較零碎,準(zhǔn)備看2本書(shū)充實(shí)下,一本是「深入淺出MyBatis:技術(shù)原理與實(shí)踐」,一本是「RabbitMQ實(shí)戰(zhàn):高效部署分布式消息隊(duì)列」,為了加深記憶和理解,會(huì)進(jìn)行整理、擴(kuò)展和記錄。

看書(shū)的目標(biāo)不是把所有的細(xì)節(jié)都記住,而是從整體上了解一個(gè)技術(shù)能做什么,包含的特性、基本模塊,實(shí)現(xiàn)原理和常見(jiàn)使用場(chǎng)景。

本篇分享MyBatis書(shū)籍的第一篇,首先回憶下JDBC的相關(guān)概念,了解Java提供的訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)最基本的方式,然后介紹下MyBatis的基本特性和核心組件,最后說(shuō)下書(shū)的整體結(jié)構(gòu),了解后續(xù)文章的大致內(nèi)容。

JDBC相關(guān)概念

Java程序都是通過(guò)JDBC連接數(shù)據(jù)庫(kù)的,通過(guò)SQL對(duì)數(shù)據(jù)庫(kù)編程,JDBC是由SUN公司提出的一些列規(guī)范,只定義了接口規(guī)范,具體實(shí)現(xiàn)由各個(gè)數(shù)據(jù)庫(kù)廠(chǎng)商去實(shí)現(xiàn),它是一種典型的橋接模式。

橋接模式是一種結(jié)構(gòu)型設(shè)計(jì)模式,它的主要特點(diǎn)是把抽象與行為實(shí)現(xiàn)分離開(kāi)來(lái),分別定義接口,可以保持各部分的獨(dú)立性以及應(yīng)對(duì)他們的功能擴(kuò)展。

JDBC規(guī)范

所謂規(guī)范,就是自己定義了標(biāo)準(zhǔn)接口,做了如下抽象:用Connection代表和數(shù)據(jù)庫(kù)的連接,用Statement執(zhí)行SQL,用ResultSet表示SQL返回的結(jié)果,提供了對(duì)數(shù)據(jù)的便利。從Connection可以創(chuàng)建Statement,Statement執(zhí)行查詢(xún)得到ResultSet。

上面說(shuō)的Connection、Statement、ResultSet都應(yīng)該是接口,具體實(shí)現(xiàn)由各個(gè)數(shù)據(jù)庫(kù)提供商提供。有了規(guī)范,可以通過(guò)統(tǒng)一的接口,訪(fǎng)問(wèn)多種類(lèi)型的數(shù)據(jù)庫(kù),可隨便切換數(shù)據(jù)庫(kù)。

數(shù)據(jù)庫(kù)驅(qū)動(dòng)

上面提到,接口的實(shí)現(xiàn)由各個(gè)廠(chǎng)商提供,那么實(shí)現(xiàn)類(lèi)的類(lèi)名就會(huì)不統(tǒng)一,去創(chuàng)建Connection對(duì)象時(shí),代碼就會(huì)寫(xiě)死某個(gè)實(shí)現(xiàn)類(lèi),切換數(shù)據(jù)庫(kù)時(shí),就需要修改代碼,這樣不太好。為了解決這個(gè)問(wèn)題,抽象了Driver驅(qū)動(dòng)的概念。

Connection con=MySqlConnectionImpl("127.0.0.1",3306,"mi_user",userName,pwd);

每個(gè)數(shù)據(jù)庫(kù)都需要實(shí)現(xiàn)Driver接口,通過(guò)Driver可獲得數(shù)據(jù)庫(kù)連接Connection,通過(guò)反射機(jī)制動(dòng)態(tài)創(chuàng)建。

Class.forName("com.mysql.jdbc.Drier");

同一個(gè)程序可能訪(fǎng)問(wèn)不同的數(shù)據(jù)庫(kù),通過(guò)DriverManager來(lái)管理驅(qū)動(dòng),Driver在初始化的時(shí)候,需要注冊(cè)到DriverManager中。

DriverManager提供了一個(gè)getConnection方法,用于建立數(shù)據(jù)庫(kù)Connection:

Connection con=DriverManager.getConnection("127.0.0.1",3306,"mi_user",userName,pwd);

如果有多個(gè)數(shù)據(jù)庫(kù)驅(qū)動(dòng),DriverManager如何區(qū)分呢,需要在數(shù)據(jù)庫(kù)連接url中指定,比如mysql需要添加jdbc:mysql前綴:

String url= "jdbc:mysql://127.0.0.1:3306/mi_user";
Connection con=DriverManager.getConnection(url,userName,pwd);
數(shù)據(jù)源

數(shù)據(jù)源DataSource包含連接池和連接池管理2個(gè)部分,習(xí)慣上稱(chēng)為連接池。在系統(tǒng)初始化的時(shí)候,將數(shù)據(jù)庫(kù)連接作為對(duì)象存儲(chǔ)在內(nèi)存中,當(dāng)需要訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)時(shí),從連接池中取出一個(gè)已建立的空閑連接對(duì)象。

使用數(shù)據(jù)源,獲取其DataSource對(duì)象,通過(guò)該對(duì)象動(dòng)態(tài)的獲取數(shù)據(jù)庫(kù)連接。另外,DataSource對(duì)象可以注冊(cè)到名字服務(wù)(JNDI)中,可以通過(guò)名字服務(wù)獲得DataSource對(duì)象,無(wú)需硬性編碼驅(qū)動(dòng)。

DriverManager是JDBC1提供的,DataSource是JDBC2新增的功能,提供了更好的連接數(shù)據(jù)源的方法。

對(duì)比Hibernate和MyBatis

通過(guò)上面的介紹,傳統(tǒng)的JDBC編程給我們帶來(lái)了連接數(shù)據(jù)庫(kù)的功能,但其工作量相對(duì)較大,首先連接,然后處理JDBC底層事務(wù),處理數(shù)據(jù)類(lèi)型,還要對(duì)可能產(chǎn)生的異常進(jìn)行捕捉處理并正確的關(guān)閉資源。

實(shí)際工作中,很少使用JDBC進(jìn)行編程,提出了ORM模型,主要解決數(shù)據(jù)庫(kù)數(shù)據(jù)和POJO對(duì)象的相互映射。

Hibernate和Mybatis都是ORM模型,Hibernate提供的是一種全表映射的模型,對(duì)JDBC的封裝程度比較高。但Hibernate也有不少缺點(diǎn),列舉如下:

  • 全表映射帶來(lái)的不便,比如更新時(shí)需要發(fā)送所有的字段;
  • 無(wú)法根據(jù)不同的條件組裝不同的SQL;
  • 對(duì)多表關(guān)聯(lián)和復(fù)雜SQL查詢(xún)支持較差,需要自己寫(xiě)SQL,返回后,需要自己將數(shù)據(jù)組裝為POJO;
  • 不能有效支持存儲(chǔ)過(guò)程;
  • 雖然有HQL,但性能較差,大型互聯(lián)網(wǎng)系統(tǒng)往往需要優(yōu)化SQL,而Hibernate做不到。

大型互聯(lián)網(wǎng)環(huán)境中,靈活、SQL優(yōu)化,減少數(shù)據(jù)的傳遞是最基本的優(yōu)化方法,Hibernate無(wú)法滿(mǎn)足要求,而MyBatis提哦給你了靈活、方便的方式,是一個(gè)半自動(dòng)映射的框架。

MyBatis需要手工匹配提供POJO、SQL和映射關(guān)系,而全表映射的Hibernate只需要提供POJO和映射關(guān)系。

MyBatis可以配置動(dòng)態(tài)SQL,可以解決Hibernate的表名根據(jù)時(shí)間變化,不同的條件下列明不一樣的問(wèn)題??梢?xún)?yōu)化SQL,通過(guò)配置決定SQL映射規(guī)則,也能支持存儲(chǔ)過(guò)程,對(duì)于一些復(fù)雜和需要優(yōu)化性能的SQL的查詢(xún)它更加方便。

核心組件

核心組件主要包括以下幾個(gè):

  • SqlSessionFactoryBuilder:會(huì)根據(jù)配置信息或代碼來(lái)生成SqlSessionFactory;
  • SqlSessionFactory:依靠工廠(chǎng)來(lái)生成SqlSession;
  • SqlSession:是一個(gè)既可以發(fā)送SQL去執(zhí)行并返回結(jié)果,也可以獲取Mapper的接口;
  • SQL Mapper:是MyBatis新設(shè)計(jì)的組件,由一個(gè)Java接口和XML文件構(gòu)成,需要給出對(duì)應(yīng)的SQL和映射規(guī)則。它負(fù)責(zé)發(fā)送SQL去執(zhí)行,并返回結(jié)果。
構(gòu)建SqlSessionFactory

每個(gè)MyBatis應(yīng)用都是以SqlSessionFactory的實(shí)例為中心的,它的任務(wù)是創(chuàng)建SqlSession。SqlSesion類(lèi)似于一個(gè)JDBC的Connection對(duì)象。

提供了2種方式創(chuàng)建SqlSessionFactory:一種是XML配置的方式,一種是代碼的方式,推薦使用XML配置的方式。

定義mybatis-config.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>
 <properties resource="application.properties">
 </properties>

 <!-- 定義別名 -->
 <typeAliases>
 <typeAlias alias="role" type="com.learn.chapter2.po.Role"/>
 </typeAliases>

 <!-- 定義數(shù)據(jù)庫(kù)信息.默認(rèn)使用development數(shù)據(jù)庫(kù)構(gòu)建環(huán)境 -->
 <environments default="development">
    <environment id="development">
    <!-- 采用jdbc事務(wù)管理 -->
        <transactionManager type="JDBC"/>
        <dataSource type="POOLED">
            <property name="driver" value="${driver}"/>
            <property name="url" value="${url}"/>
            <property name="username" value="${username}"/>
            <property name="password" value="${password}"/>
        </dataSource>
    </environment>
 </environments>

 <!-- 定義映射器 -->
 <mappers>
 <mapper resource="com\learn\chapter2\mapper\roleMapper.xml"/>
 </mappers>
</configuration>

創(chuàng)建SqlSessionFactory

String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory  sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
創(chuàng)建SqlSession

SqlSession是一個(gè)接口類(lèi),扮演者門(mén)面的作用,真正干活的是Executor接口。需要保證每次用完正常關(guān)閉它。

SqlSession sqlSession=null;
try{
    sqlSession=sqlSessionFactory.openSession();
    //some code
    sqlSession.commit();
} catch(Exception ex){
    sqlSession.roolback();
} finally{
    if(sqlSession!=null){
        sqlSession.close();
    }
}
映射器

映射器是由Java接口和XML文件(或注解)共同組成的,作用如下:

  • 定義參數(shù)類(lèi)型
  • 描述緩存
  • 描述SQL語(yǔ)句
  • 定義查詢(xún)結(jié)果和POJO的映射關(guān)系

首先,定義Java接口:

public interface RoleMapper{
    public Role getRole(Long id);
}

然后,定義映射XML文件,RoleMapper.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">

 <mapper namespace ="com.learn.chapter2.mapper.RoleMapper">
    <select id="getRole" paramterType="long" resultType="role" >
        select id,role_name as roleName , note from t_role where id=#{id}
    </select>
 </mapper>

POJO對(duì)象Role的定義比較簡(jiǎn)單,就不列出了。#{id}為這條SQL的參數(shù),SQL列的別名和POJO的屬性名稱(chēng)保持一致,會(huì)把這條語(yǔ)句的查詢(xún)結(jié)果自動(dòng)映射到Role屬性上,這就是自動(dòng)映射。

執(zhí)行查詢(xún)

RoleMapper roleMapper=sqlSession.getMapper(RoleMapper.class);
Role role=roleMapper.getRole(1L);
String roleName=role.getRoleName();
組件生命周期

SqlSessionFactory在MyBatis應(yīng)用的整個(gè)生命周期中,每個(gè)數(shù)據(jù)庫(kù)只對(duì)應(yīng)一個(gè)SqlSessionFactory,可以實(shí)現(xiàn)一個(gè)工具類(lèi),以單例模式獲取該對(duì)象。

SqlSession的生命周期在請(qǐng)求數(shù)據(jù)庫(kù)處理事務(wù)的過(guò)程中,它是一個(gè)線(xiàn)程不安全的對(duì)象,在涉及多線(xiàn)程的時(shí)候要特別當(dāng)心。它存活于一個(gè)應(yīng)用的請(qǐng)求和操作,可以執(zhí)行多條SQL,保證事務(wù)的一致性。

Mapper的作用是發(fā)送SQL,然后返回需要的結(jié)果,或者執(zhí)行SQL修改數(shù)據(jù)庫(kù)的數(shù)據(jù),所以它應(yīng)該在一個(gè)SqlSession事務(wù)方法之內(nèi),如同JDBC中一條SQL語(yǔ)句的執(zhí)行,它最大的范圍和SqlSession是相同的。

書(shū)的整體結(jié)構(gòu)

本書(shū)分為3個(gè)部分,依次介紹了MyBatis的基礎(chǔ)應(yīng)用、原理及插件開(kāi)發(fā)、實(shí)戰(zhàn)應(yīng)用。

基礎(chǔ)應(yīng)用

主要介紹如何高效地使用MyBatis:

  • MyBatis特性
  • 核心組件及其生命周期
  • MyBatis配置
  • 映射器
  • 動(dòng)態(tài)SQL
MyBatis原理

深入源碼理解MyBatis的內(nèi)部運(yùn)行原理以及插件的開(kāi)發(fā)方法和技巧:

  • 介紹MyBatis的解析和運(yùn)行原理,將了解到SqlSession的構(gòu)建方法,以及四大對(duì)象是如何工作的
  • 介紹MyBatis的插件
實(shí)戰(zhàn)應(yīng)用

主要講解MyBatis的一些實(shí)用的場(chǎng)景:

  • 介紹MyBatis-Spring,講解如何在Spring項(xiàng)目中集成MyBatis應(yīng)用
  • 介紹MyBatis的實(shí)用場(chǎng)景,精選一些典型場(chǎng)景,解析每個(gè)場(chǎng)景下,開(kāi)發(fā)人員需要注意避免的一些錯(cuò)誤和性能上的損失

下篇會(huì)介紹MyBatis的相關(guān)配置,更好的配置MyBatis以適用于不同的業(yè)務(wù)場(chǎng)景,以及提供給我們的擴(kuò)展。

深入淺出MyBatis:JDBC和MyBatis介紹

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI