寫給mybatis小白的入門指南

深夜程猿發表於2018-02-27

一、什麼是myabtis

官方連結:www.mybatis.org/mybatis-3/z…

MyBatis 是一款優秀的持久層框架,它支援定製化 SQL、儲存過程以及高階對映。MyBatis 避免了幾乎所有的 JDBC 程式碼和手動設定引數以及獲取結果集。MyBatis 可以使用簡單的 XML 或註解來配置和對映原生資訊,將介面和 Java 的 POJOs(Plain Old Java Objects,普通的 Java物件)對映成資料庫中的記錄。

總而言之,mybatis是一款資料持久層框架(記得不是ORM框架)。

二、使用mybatis運算元據庫

  • 引入mybatis
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.5</version>
        </dependency>
複製程式碼

全部pom檔案配置:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>source.code</groupId>
    <artifactId>mybatis</artifactId>
    <packaging>war</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>mybatis Maven Webapp</name>
    <url>http://maven.apache.org</url>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.5</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.38</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.7</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.7</version>
        </dependency>
    </dependencies>
    <build>
        <finalName>mybatis</finalName>
    </build>
</project>

複製程式碼
  • 新增mybatis配置檔案,對映檔案
    配置檔案命名為mybatis.xml,對映檔案命名為article.xml

mybatis.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="config.properties">
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </properties>
    
    <typeAliases>
        <typeAlias type="com.mybatis.demo.entity.Article" alias="Article"/>
    </typeAliases>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"></transactionManager>
            <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="article.xml"></mapper>
    </mappers>

</configuration>
複製程式碼

分析:mybatis.xml檔案配置了資料庫,對映檔案等資訊。
(1)properties標籤配置一些基本屬性值,可以在裡面配置一些常量方便其它標籤引用。properties標籤可以使用resource屬性來指定配置檔案的路徑。其中,會先讀取讀取配置檔案,如果配置檔案存在,則獲取配置檔案的鍵值對內容,如果在properties的子標籤property有配置了和讀取到鍵值對的配置檔案的同key內容,則覆蓋掉鍵值對配置檔案的內容。也就是優先順序是:property標籤 > proerties檔案;
(2)environments標籤配置資料庫的一些環境,比如資料來源、事務管理
(3)mappers標籤配置了對映檔案的路徑可以配置多個mappers檔案
(4)還有更多標籤和屬性在這篇文章先不分析,後續文章會詳細分析

config.properties檔案內容

url=jdbc:mysql://localhost:3306/my_test_db?characterEncoding=UTF-8&useSSL=false
driver=com.mysql.jdbc.Driver
複製程式碼

article.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 namespace="com.mybatis.demo.mapper.ArticleMapper">

    <select id="selectOne" parameterType="int" resultType="Article">
        SELECT title, content FROM article WHERE id = #{id}
    </select>


    <insert id="insert" parameterType="Article">
        INSERT INTO article (title, content) VALUES (#{title}, #{content})
    </insert>

    <update id="update" parameterType="Article">
        UPDATE article SET title = #{title} WHERE id = #{id}
    </update>

    <delete id="delete" parameterType="int">
        DELETE FROM article WHERE id = #{id}
    </delete>

</mapper>
複製程式碼
  • 建立實體類

Article.java

public class Article {

    private Integer id;
    private String title;
    private String content;

    public String getTitle() {
        return title;
    }


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

    public Integer getId() {
        return id;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }
}

複製程式碼
  • 建立Mapper類

ArticleMapper.java

@Mapper
public interface ArticleMapper {

    /**
     * 新增文章
     *
     * @param article
     * @return
     */
    boolean insert(Article article);

    /**
     * 獲取一條文章
     *
     * @param id 文章id
     * @return
     */
    Article selectOne(int id);

    /**
     * 更新文章
     *
     * @param article
     * @return
     */
    int update(Article article);

    /**
     * 刪除文章
     *
     * @param id
     * @return
     */
    int delete(int id);

}

複製程式碼
  • 建立測試類

ArticleMapperTest.java

public class ArticleMapperTest {

    private SqlSessionFactory sqlSessionFactory;
    private ArticleMapper mapper;
    private SqlSession sqlSession;

    @Before
    public void setUp() throws IOException {
        String mybatisCfg = "mybatis.xml";
        InputStream in = Resources.getResourceAsStream(mybatisCfg);
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
        sqlSession = sqlSessionFactory.openSession();
        mapper = sqlSession.getMapper(ArticleMapper.class);
    }

    @After
    public void close() {
        if (sqlSession != null) {
            sqlSession.close();
        }
    }

    @Test
    public void testDelete() {
        int count = mapper.delete(3);
        sqlSession.commit();
        System.out.println(count);
    }


    @Test
    public void testUpdate() {
        Article article = new Article();
        article.setId(3);
        article.setTitle("source code");
        int count = mapper.update(article);
        sqlSession.commit();
        System.out.println(count);
    }


    @Test
    public void testSelectOne() {
        Article article = mapper.selectOne(1);
        System.out.println("title:" + article.getTitle() + " " + "content:" + article.getContent());
        sqlSession.close();
    }

    @Test
    public void testInsertV1() {
        Article article = new Article();
        article.setTitle("我是標題");
        article.setContent("我是文字內容");
        int count = sqlSession.insert("com.mybatis.demo.mapper.ArticleMapper.insert", article);
        sqlSession.commit();
        sqlSession.close();
        System.out.println(count);
    }

    @Test
    public void testInsertV2() {
        Article article = new Article();
        article.setTitle("v2-標題");
        article.setContent("v2-文字內容");
        boolean flag = mapper.insert(article);
        sqlSession.commit();
        sqlSession.close();
        System.out.println(flag);
    }
}

複製程式碼

我們依次分析上面測試程式碼:
首先看下在執行測試用例之前,我們幹了什麼:

    @Before
    public void setUp() throws IOException {
        String mybatisCfg = "mybatis.xml";
        InputStream in = Resources.getResourceAsStream(mybatisCfg);
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
        sqlSession = sqlSessionFactory.openSession();
        mapper = sqlSession.getMapper(ArticleMapper.class);
    }
複製程式碼

我們是通過InputStream in = Resources.getResourceAsStream(mybatisCfg);來載入配置檔案,建立SqlSessionFactory,由SqlSessionFactory獲取SqlSession。
在mybatis中,一個SqlSession例項代表著一次資料庫連線,SqlSession由SqlSessionFactory來獲取。在整個應用執行過程,我們只需要一個SqlSessionFactory例項,但是可以有多個SqlSession例項。SqlSession是執行緒不安全的,所以我們最好在方法級別使用SqlSession,並且在使用完畢及時關閉連線,避免資源的浪費。

接下來我們看新增一條資料的操作是怎麼樣的

    @Test
    public void testInsertV1() {
        Article article = new Article();
        article.setTitle("我是標題");
        article.setContent("我是文字內容");
        int count = sqlSession.insert("com.mybatis.demo.mapper.ArticleMapper.insert", article);
        sqlSession.commit();
        sqlSession.close();
        System.out.println(count);
    }
複製程式碼

(1)我們通過SqlSession來運算元據庫,呼叫insert方法,第一個引數指定對應的對映類的方法的全路徑,第二個引數是新增的資料。
(2)執行insert方法的時候,mybatis會根據方法第一個引數指定的的全路徑去查詢對應的sql對映配置。在這裡mybatis會根據“com.mybatis.demo.mapper.ArticleMapper.insert”來查詢對應的對映檔案對應的sql對映配置。mybatis的對映檔案的每一個sql對映配置都會有一個唯一的id與之對應,可以簡單理解為(對映檔案的名稱空間+sql對映配置的id屬性值)的雜湊值。於是mabtis找到名稱空間為“com.mybatis.demo.mapper.ArticleMapper”,sql對映配置id屬性值為“insert”的sql對映配置

我們在運算元據庫的時候,可以不直接操作SqlSession,而是通過SqlSession獲取Mapper,由Mapper來運算元據庫。

    @Test
    public void testInsertV2() {
        Article article = new Article();
        article.setTitle("v2-標題");
        article.setContent("v2-文字內容");
        boolean flag = mapper.insert(article);
        sqlSession.commit();
        sqlSession.close();
        System.out.println(flag);
    }
複製程式碼

原理和使用SqlSession直接運算元據庫一樣,只不過是Mapper和SqlSession關聯起來,執行Mapper的insert方法的時候,也是查詢對應的sql對映配置。但是,這時候是使用Mapper的全路徑名+執行的方法名(不用引數)來查詢sql對映配置的。所以,我們的對映檔案的名稱空間需要的Mapper的全路徑名,sql對映配置的id屬性值必須和Mapper的方法同名

我們再來看一下,獲取一條資料庫記錄的操作:

    @Test
    public void testSelectOne() {
        Article article = mapper.selectOne(1);
        System.out.println("title:" + article.getTitle() + " " + "content:" + article.getContent());
        sqlSession.close();
    }
複製程式碼

在執行Mapper的selectOne方法的時候,前面流程和插入一條資料一樣,查詢配置檔案,解析sql,執行sql。只是在執行完sql後,mybatis還會對結果進行對映,然後返回對映結果集

刪除和更新操作原理一樣,就不過多分析了。 配置檔案和對映檔案的目錄如圖:

寫給mybatis小白的入門指南

廣告時間,可以忽略:

更多文章會在公眾號第一時間釋出,歡迎掃碼關注公眾號:深夜程猿
由於微信最近不允許修改公眾號頭像,公眾號最近才是運營,所以還沒有設定頭像~~是不是很醜……

寫給mybatis小白的入門指南

相關文章