MyBatis學習筆記(1)—使用篇

卡巴拉的樹發表於2018-01-25

MyBatis學習筆記(1)—使用篇

MyBatis學習筆記(2)—對映關係篇

MyBatis學習筆記(3)—高階對映之一對一對映

Mybatis學習筆記(4)-高階對映之一對多對映

Mybatis學習筆記(5)-高階對映之多對多對映

...敬請期待

Mybatis是什麼?

MyBatis是一款優秀的持久層框架,支援定製化SQL、儲存過程以及高階對映。避免了幾乎所有的JDBC程式碼和手動設定引數及獲取結果集。Mybatis可以通過配置XML或者註解,將介面和Java的POJOS 對映成資料庫中的記錄。

MyBatis學習筆記(1)—使用篇

第一個MyBatis應用

通過實戰來上手一個知識點是一種比較快的方式,可以幫助建立全域性的印象,在過程中會講述一些必要的知識點。

最近爆火的旅行青蛙很有意思,周邊好友紛紛入坑,這裡我以它的商店系統作為資料庫操作的物件。

MyBatis學習筆記(1)—使用篇

首先準備好資料庫,這裡我根據旅行青蛙商店的內容建立了Commodity表:

create database TravelFrog;
CREATE TABLE commodity
(
  id    int      NOT NULL AUTO_INCREMENT,
  name  varchar(255)     NOT NULL ,
  price decimal(8,2)  NOT NULL ,
  description  varchar(255),
  PRIMARY KEY(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO commodity(id, name, price, description)
VALUES(1001, '野葡萄烤餅', 10, '吃完還有點餓');
INSERT INTO commodity(id, name, price, description)
VALUES(1002, '巨石三明治', 20, '蔬菜、快速輕食');
INSERT INTO commodity(id, name, price, description)
VALUES(1003, '南瓜百吉餅', 50, '份大量足,可以去很遠的地方');
INSERT INTO commodity(id, name, price, description)
VALUES(1004, '乳蛋餅', 80, '想快點吃到拍,身心都輕快了,快速回家');
複製程式碼

下面正式開啟IDEA新建工程,新增maven依賴:

<dependencies>
        <!-- mybatis包 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.1</version>
        </dependency>

        <!-- mysql資料庫連線 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>6.0.6</version>
        </dependency>

        <!-- 日誌 -->
         <dependency>
             <groupId>log4j</groupId>
             <artifactId>log4j</artifactId>
             <version>1.2.17</version>
         </dependency>

        <!-- junit測試 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
複製程式碼

接下來,按以下目錄結構新增檔案:

MyBatis學習筆記(1)—使用篇

Mybatis配置檔案

新建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>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <!-- 選擇連線資料庫用的驅動 -->
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <!-- 資料庫地址 -->
                <property name="url" value="jdbc:mysql://localhost:3306/TravelFrog?characterEncoding=UTF-8"/>
                <!-- 資料庫使用者名稱 -->
                <property name="username" value="root"/>
                <!-- 資料庫密碼 -->
                <property name="password" value="jenkins"/>
            </dataSource>
        </environment>
    </environments>
    <!-- 匯入Mybatis資料庫查詢對映檔案 -->
    <mappers>
        <mapper resource="mapper/CommodityMapper.xml"/>
    </mappers>
</configuration>
複製程式碼

Mybatis配置檔案裡包含資料來源,日誌,快取等關係到Mybatis自身行為的一些配置,上面的配置檔案裡包含了資料來源配置,事務管理。

建立POJO類

package com.shuqing28.pojo;

public class Commodity {
    private Integer id;
    private String name;
    private Double price;
    private String description;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Double getPrice() {
        return price;
    }

    public void setPrice(Double price) {
        this.price = price;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    @Override
    public String toString() {
        return "Commodity{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", price=" + price +
                ", description='" + description + '\'' +
                '}';
    }
}
複製程式碼

對應於資料庫剛才建立的商品表,這裡的POJO裡的欄位和商品表裡的欄位一一對應。

對映器

介面部分
package com.shuqing28.dao;

import com.shuqing28.pojo.Commodity;

import java.util.List;

public interface CommodityDao {
    List<Commodity> getAllCommodity();
}
複製程式碼

這裡定義一個介面,注意介面的方法和下面的XML檔案的id保持一致。

XML Mapper
<?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="com.shuqing28.dao.CommodityDao">
    <select id="getAllCommodity" resultType="com.shuqing28.pojo.Commodity">
        SELECT * FROM commodity
    </select>
</mapper>
複製程式碼

描述一下上面的XML檔案做了什麼:

  1. 首先,前面的配置檔案裡其實註冊了這個Mapper:
 <mappers>
        <mapper resource="mapper/CommodityMapper.xml"/>
    </mappers>
複製程式碼

所以Mybatis會讀取這個XML,生成對映器,這裡其實用到了動態代理。

  1. 定義了一個名稱空間為com.shuqing28.dao.CommodityDao的SQL Mapper,這個名稱空間和我們定義的介面的全限定名是一致的。

  2. 用一個select元素定義了一個查詢SQL,返回結果是我們定義過的Commodity。 這也是Mybatis最核心的部分,也是最複雜的部分,除了使用XML實現,也可以通過註解實現,比如如果沒有上面的XML檔案,那麼也可以直接在介面裡這麼定義:

@Select(value="SELECT * FROM commodity")
public interface CommodityDao {
    List<Commodity> getAllCommodity();
}
複製程式碼

這邊只是淺淺的描述了使用,因為是第一篇,所以不深入,會用就行。

新增日誌配置

# Global logging configuration
log4j.rootLogger=ERROR, stdout
# MyBatis logging configuration...
# 指定Mapper包範圍的日誌級別
log4j.logger.com.zju.dao=DEBUG
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m
複製程式碼

測試類

import com.shuqing28.dao.CommodityDao;
import com.shuqing28.pojo.Commodity;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class CommodityTest {
    private SqlSessionFactory sqlSessionFactory = null;
    @Before
    public void setUp() throws IOException{
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    }

    @Test
    public void getAllCommodity(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            CommodityDao commodityDao = sqlSession.getMapper(CommodityDao.class);
            List<Commodity> commodities = commodityDao.getAllCommodity();
            System.out.println(commodities);
        } finally {
            sqlSession.close();
        }
     }
}
複製程式碼

執行結果

[Commodity{id=1001, name='野葡萄烤餅', price=10.0, description='吃完還有點餓'}, Commodity{id=1002, name='巨石三明治', price=20.0, description='蔬菜、快速輕食'}, Commodity{id=1003, name='南瓜百吉餅', price=50.0, description='份大量足,可以去很遠的地方'}, Commodity{id=1004, name='乳蛋餅', price=80.0, description='想快點吃到拍,身心都輕快了,快速回家'}]
複製程式碼

其實測試類裡面的東西非常值得我們關注,我們可以依此知道Mybatis的基本構成

Mybatis的基本構成

MyBatis學習筆記(1)—使用篇

SqlSessionFactoryBuilder

SqlSessionFactoryBuilder通常利用XML或者Java編碼來構建SqlSessionFactory,一旦我們構建了SqlSessionFactory,它的作用也就完結了。上面的例子中也就是簡單的讀取配置檔案,轉化為流物件,再建立出SqlSessionFactory。因為它的主要目的是建立SqlSessionFactory,所以它一般也只存活在建立的那個方法裡,宣告週期很短。

SqlSessionFactory

SqlSessionFactory是一個工廠類,它的作用就是生產SqlSession,而SqlSession你可以想象成JDBC裡的一個Connection,每次訪問資料庫都需要一個SqlSession,所以SqlSessionFactory通常伴隨整個Mybatis的生命週期,我們通常為一個資料庫建立一個SqlSessionFactory,因為如果建立多個,那麼每次建立新的,它都會附帶著開啟一堆Connection資源,所以通常我們使用單例模式管理SqlSessionFactory。

SqlSession

SqlSession就是一個對話,類比Connection,所以每次使用完都要記得關閉它。同時,它也是一個執行緒不安全物件,所以在涉及多執行緒時要額外注意,我們在上面的程式碼中,在finally語句裡確保關閉它。它存活於一個應用的請求和操作,可以執行多條sql,保證事務一致性。

Mapper

Mapper也就是上面我們寫的CommodityDao commodityDao = sqlSession.getMapper(CommodityDao.class);,我們僅僅使用Java介面和一個XML檔案(或者註解)去實現Mapper而不用實現類,其實這裡運用到了動態代理,Mybatis會為介面生成代理類物件,代理物件會根據“介面路徑+方法名”去匹配,找到對應的XML檔案(或註解)去完成它所需要的任務,返回我們需要的結果。Mapper是一個方法級別的東西,它的最大生命週期應該和SqlSession是相同的。

照著上面的程式碼敲一遍便可以實現第一個Mybatis應用了,本系列第一篇,未完待續。。

相關文章