天天看點

MyBatis小結

MyBatis的學習總結

    • MyBatis簡介
    • MyBatis的架構環境搭建及環境介紹
      • MyBatis項目環境搭建
    • MyBatis的具體操作
      • 三種查詢方式
        • List
        • 對象
        • Map
      • 參數傳遞操作
        • 直接傳值
        • 對象傳值
        • Map傳值
      • Mapper代理增删改查操作
        • 插入
        • 修改
        • 删除
    • MyBatis使用的注意事項

學習MyBatis過程的小結

MyBatis 是一款優秀的持久層架構,它支援自定義 SQL、存儲過程以及進階映射。MyBatis 免除了幾乎所有的 JDBC 代碼以及設定參數和擷取結果集的工作。MyBatis 可以通過簡單的 XML 或注解來配置和映射原始類型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 對象)為資料庫中的記錄。

這是Apache的官方文檔給的介紹,從中我們可以獲得一些資訊

  1. MyBatis是一款持久層的架構
  2. 幾乎免除了JDBC Code以及設定參數和擷取結果集的工作
  3. 通過XML或注解來配置和映射原始類型、接口和 Java POJO為資料庫中的記錄

其中前期我們能夠直覺的感受到的就是第二點和第三點給我們帶來的周遊,試想一下我們以前在學習過程中練習的JDBC,通常要寫資料庫的連接配接,再拿着連接配接去建立

Statement

再得到結果集最後從結果集中挨個周遊資料,期間要最麻煩的就屬設定參數和接收參數了,幾個字段名還好,一旦字段名多了、表多了就不想寫JDBC了,那麼在前期學習MyBatis的時候我們就可以體驗到這個架構給我們帶來的一些便利。

在學習之前我們需要下載下傳MyBatis:https://github.com/mybatis/mybatis-3/releases ,推薦下載下傳最新版本後退4個小版本的(懂得都懂哈),保證咱們學習都能百度到答案,下載下傳之後,打開檔案夾,我們可以看到第一個jar包:

MyBatis小結

核心包:mybatis-3-5-2.jar,單單核心包還不夠,還需要依賴包,在lib下的所有jar包,以及MySQL的jar包

MyBatis小結

将上面所述的jar包導入項目之後,那麼前期MyBatis的架構環境搭建的準備工作就完成了(如果要使用日志的話還需要自行下載下傳log4j的依賴包)接下來進入項目中的環境搭建

建立項目

MyBatis1

将項目src分層為

entity

mapper

test

,首先我們建立一個JavaBean檔案

Account

entity

目錄中:

這個寫過JDBC的童鞋都知道有啥用,接下來就是準備咱們MyBatis的環境了

在src根路徑下建立

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>
    <!--  一開始會報錯
  The content of element type "configuration" must match
  "(properties?,settings?,typeAliases?,typeHandlers?,objectFactory?,objectWrapperFactory?,reflectorFactory?,plugins?,environments?,databaseIdProvider?,mappers?)".
    意思是 "configuration"标簽内的标簽必須以以下标簽的先後順序進行書寫
    properties
    settings
    typeAliases
    typeHandlers
    objectFactory
    objectWrapperFactory
    reflectorFactory
    plugins
    environments
    databaseIdProvider
    mappers
    可以看到properties标簽必須放在第一個
  -->
    <!-- 可以在外部進行配置,并可以進行動态替換,這裡用來讀取jdbc.properties的JDBC連接配接參數 -->
    <properties resource="jdbc.properties"/>
    <!-- 資料庫環境 -->
    <!--  給實體類配置别名  -->
    <typeAliases>
        <!-- 給實體類配置别名,适用于實體類較少 -->
        <!--        <typeAlias type="com.lyl.mybatis.entity.Account" alias="a"/>-->
        <!-- 實體類多時可以直接設定包别名,傳回類型直接寫類名即可,一般小寫,推薦寫這種形式 -->
        <package name="com.lyl.mybatis.entity"/>
    </typeAliases>
    <!--............................................................-->
    <environments default="MySQL">
        <environment id="MySQL">
            <!-- MyBatis中的事務管理 下面制指定了和JDBC一樣 -->
            <transactionManager type="JDBC"/>
            <!-- 底層采用連接配接池原理 -->
            <dataSource type="POOLED">
                <!--       讀取jdbc.properties中的配置資訊         -->
                <property name="driver" value="${m_driver}"/>
                <property name="url" value="${m_url}"/>
                <property name="username" value="${m_user}"/>
                <property name="password" value="${m_pwd}"/>
            </dataSource>
        </environment>
    </environments>
    <!--............................................................-->
    <!-- 掃描映射檔案 -->
    <mappers>
        <mapper resource="com/lyl/mybatis/mapper/Account.xml"/>
    </mappers>
</configuration>
           

上面代碼的注釋可以選擇性看,其實我們手動寫的

mybatis-config.xml

檔案是MyBatis的核心配置檔案,檢視API我們可以知曉在Java Code中使用Mybatis需要建構

SqlSessionFactory

顧名思義是專門建立SQL會話的工廠,可以看作是生産程式與資料庫直接連接配接執行個體的工廠,那麼我們具體操作核心肯定是圍繞着

SqlSessionFactory

裡面的東西來實作的,後面會提到。

那麼寫了MyBatis的核心配置還不行,資料庫連接配接之後那增删改查操作的sql語句在哪呢?是不是直接解除安裝

mybatis-config.xml

裡面呢?上面代碼的最後可以看到有

<mappers>

标簽,這個标簽用來掃描映射檔案,直接檢視API的XML映射檔案的介紹:

MyBatis 的真正強大在于它的語句映射,這是它的魔力所在。由于它的異常強大,映射器的 XML 檔案就顯得相對簡單。如果拿它跟具有相同功能的 JDBC 代碼進行對比,你會立即發現省掉了将近 95% 的代碼。MyBatis 緻力于減少使用成本,讓使用者能更專注于 SQL 代碼。

ok,這下我們知道映射檔案其實就是編寫咱們sql代碼的檔案,而

mybatis-config.xml

中的

<mappers>

标簽就是用來掃描映射檔案映射器,讓MaBatis知道去哪尋找SQL映射語句,那麼我們接下來是在mapper目錄下編寫映射檔案

AccountMapper.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 namespance="com.lyl.mybatis.mapper.Account">
<!-- namespance:命名空間,用于在java代碼中找到正确的SQL映射語句 -->

<!-- public Account listAccount(){} -->
    <select id="listAccount" resultType="account">
      select * from account
    </select>
</mapper>
           

Account.xml

寫一個簡單的查詢,具體标簽作用可以看官方API,将上面

<select>

标簽翻譯成Java Code就是

public Account listAccount(){}

,這下就清楚明了了id和resultType的作用了,那麼到此MyBatis項目的基本環境搭建就完成了,那麼做一個小結:

  1. 導入核心包、依賴包、資料庫核心包,将項目分層,并建立好JavaBean
  2. 編寫MyBatis的核心配置

    mybatis-config.xml

  3. 編寫SQL映射檔案

    AccountMapper.xml

在編寫配置檔案的時候,我們會編寫很多配置資訊,這裡可能顯得MyBatis的優勢不足,這與我們平常寫的JDBC沒什麼差別,代碼量看似也沒有減少,那麼接下來我們就從測試中感受一下MyBatis的便利,同時一定不要被配置檔案搞得頭昏眼花,記住根本的三步驟就好了

在Test包下建立Test.java用來測試咱們的MyBatis,在此之前介紹一下使用MyBatis來操作資料庫的核心類:

  1. SqlSessionFactoryBuilder
  2. SqlSessionFactory
  3. SqlSession

使用MyBatis的核心基礎就是圍繞着這三個類來實作的,

SqlSessionFactoryBuilder

建立

SqlSessionFactory

SqlSession

SqlSessionFactory

中擷取,具體的操作借助

SqlSession

實作,這樣三者的關系就清楚一些了,讓我們來測試前的準備:

public static void main(String[] args){
        String resource = "mybatis.xml";
        InputStream inputStream = null;
        SqlSession sqlSession = null;
        try {
            // 1.解析mybatis.xml檔案,MyBatis提供了Resources類來擷取MyBatis的核心配置檔案輸入流
            inputStream = Resources.getResourceAsStream(resource);
            // 2.根據解析的資訊得到sqlSessionFactory
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            // 3.得到Session
             sqlSession = sqlSessionFactory.openSession();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (sqlSession!=null){
                sqlSession.close();
            }
        }
    }
           

上面是得到

SqlSession

的步驟,接下來執行查詢方法

SqlSession

提供了三種查詢方式便利我們進行簡單的查詢操作,同時也對應着三種查詢結果集不一樣

AccountMapper.xml

中編寫SQL語句

<select id="listAccount" resultType="account">
  select * from account
</select>
           

編寫好後我們開始執行java代碼

List<Account> list = sqlSession.selectList("com.lyl.mybatis.mapper.Account.listAccount");
  System.out.println(list);
           

列印結果

[Account{id=1, username='張三', balance=1000.0}, Account{id=3, username='王五', balance=2000.0}, Account{id=4, username='趙六', balance=4000.0}, Account{id=5, username='丈八', balance=3000.0}]
           

看到java代碼我們得知傳回的結果是List,那麼下面兩種方式大同小異隻是傳回類型不一樣,這裡提一點,上述的

AccountMapper.xml

<mapper namespace="com.lyl.mybatis.mapper.Account">

其中的namespace的作用就在此展現出來了,保證我們SqlSession根據namespace和每個SQL操作标簽的id來映射出SQL語句并對其操作

<select id="selectOne" resultType="account">
        select * from account where id=3
</select>
           

執行java代碼

Account account = sqlSession.selectList("com.lyl.mybatis.mapper.Account.selectOne");
  System.out.println(account);
           
Account{id=3, username='王五', balance=2000.0}
           

<select id="selectMap" resultType="map">
        select * from account
</select>
           
Map<Object, Object> account = sqlSession.selectMap("com.lyl.mapper.AccountMapper1.selectMap", "id");
System.out.println(account);
           
{1={balance=1000.0, id=1, username=張三}, 3={balance=2000.0, id=3, username=王五}, 4={balance=4000.0, id=4, username=趙六}, 5={balance=3000.0, id=5, username=丈八}}
           

在Map中的泛型不要改!不要改!不要改!貌似改了也無所謂,最好不要更改,萬一報錯了我可不負責,其中Map中有兩個參數傳遞,看結果集應該不難推斷出兩者關系和id參數的含義。

這三種方式之中推薦使用List,因為使用Map能做的List基本上也能做到,簡單的查詢也不需要使用到Map的特性,後期開發中也可能用到Map,這就需要自行了解使用了。

我們的SQL語句不可能寫死,需要根據我們的需求來進行指定的SQL操作,這個時候就需要傳遞參數,MyBatis是SQL和Java代碼實作了解耦,同時也給我們對應的接口來提供參數的傳遞,大緻分為三種傳值方式。

這個應該不太好取名,MyBatis中内置了一些Java的類型别名在API可以查到,可以通過别名簡化在配置檔案中的全限定類名,是一些基本資料類型和包裝類。

顧名思義就是将一個對象作為參數傳入sqlSession的方法中,MyBatis在處理的時候會将對象裡的值按照SQL映射檔案的對應語句格式傳值,這種方式在處理單表查詢的确友善,但是在處理多表的時候會顯得非常有局限性,一個對象不可能包含多表的所有字段,那麼解決方法是什麼呢? 是以我們接下來學習用Map傳值。

Map<String,Object> map = new HashMap<>(); // 建立Map泛型規定為Key--String,Value--Object
        // 将資料壓入map
        map.put("id",1);
        map.put("username","張三");
        // 傳值,SQL映射檔案的sql語句取值按照key來進行取值
        Account account = sqlSession.selectOne("com.lyl.mapper.AccountMapper2.selectOne3", map);
           

upDate操作與查詢操作同理,隻是方法不同,但是同樣是由SqlSession對象來操作,傳入參數最多也一個,這樣造成了局限性,并且,我們并沒有向往常一樣寫資料庫操作的接口,造成了後期代碼可維護性低,是以開始學習Mapper代理來解決問題。