初識MyBatis

建立mybatis工程

先不管什么原理不原理,上來就是干呀。

前期準備

建立一個空白的maven工程,添加依賴:

<dependencies>

    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.1</version>
    </dependency>

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.16</version>
    </dependency>

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>LATEST</version>
    </dependency>

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.8</version>
    </dependency>


</dependencies>

最重要的就是mybatis與mysql依賴,其他的都可以不加入,但具體代碼需你自己調整。

再建一張表,簡單點就好

CREATE TABLE `fruits` (
`id` INT ( 11 ) NOT NULL AUTO_INCREMENT,
`fruits_name` VARCHAR ( 40 ) DEFAULT NULL,
`color` VARCHAR ( 20 ) DEFAULT NULL,
`weight` DOUBLE DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
PRIMARY KEY ( `id` ) 
) ENGINE = INNODB AUTO_INCREMENT = 2 DEFAULT CHARSET = utf8mb4;

建表的時候想吃水果了,所以就建了這么個東西。再隨便插入條數據:如

INSERT INTO `test`.`fruits`(`fruits_name`, `color`, `weight`, `created_at`) VALUES ('banana', 'green', 1234.2, '2019-06-18 16:16:35')

前期準備就算完成了。

寫配置

本例中只關注mybatis,所以不會有與其他框架整合的配置。

配置與mysql的連接

先建個mysql.properties文件(這不是必須的,你可以直接寫到mybatis的配置里去)
寫(根據自己的情況修改):

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/test?characterEncoding=utf-8&serverTimezone=UTC
username=root
password=root

下面就是真正的配置,建個mybatis-config.xml文件,寫入:

<configuration>
    <!-- 引入外部配置文件 -->
    <properties resource="mysql.properties"></properties>
    <environments default="development">
        <environment id="development">
            <!-- type="JDBC" 代表使用JDBC的提交和回滾來管理事務 -->
            <transactionManager type="JDBC"/>
            <!-- mybatis提供了3種數據源類型,分別是:POOLED,UNPOOLED,JNDI -->
            <!-- POOLED 表示支持JDBC數據源連接池 -->
            <!-- UNPOOLED 表示不支持數據源連接池 -->
            <!-- JNDI 表示支持外部數據源連接池 -->
            <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>
</configuration>

建立表與實體的關系

建實體類

@Data
public class Fruits implements Serializable {
    private static final long serialVersionUID = 1L;
    private Integer id;

    private String fruitsName;

    private String color;

    private Double weight;

    private Date createdAt;

    private Date updatedAt;
}

lombok大法好呀~

建mapper接口

public interface FruitsMapper {
    
    Fruits selectById(Integer id);
}

建實體類的xml文件

resource文件夾下建mapperxml/FruitsMapper.xml文件:

<mapper namespace="com.llh.mybatis.mapper.FruitsMapper">
    <select id="selectById" resultType="com.llh.mybatis.pojo.Fruits">
        select * from fruits where id=#{id} ;
    </select>
</mapper>

至此所有的配置文件已經寫完了。但是,因為這里只是用了mybatis單一框架,又把映射文件(FruitsMapper.xml)放在了自定義文件夾里,所以我們需要給mybatis指定這個文件位置。
打開mybatis-config.xml文件,在configuration標簽內添加:

    <mappers>
         <mapper resource="mapperxml/FruitsMapper.xml"/>
    </mappers>

那么,無聊的配置工作就可以告一段落了。

構建查詢

使用mybatis查詢總的來說,就兩步:

  1. 告訴mybatis我們寫的配置
  2. 使用SqlSession對象進行查詢
    如下代碼:
 private SqlSessionFactory sqlSessionFactory;

    @Before
    public void config() throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    }
    @Test
    public void selectOne() {
        try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
            FruitsMapper mapper = sqlSession.getMapper(FruitsMapper.class);
            Fruits fruits = mapper.selectById(1);
            System.out.println(fruits);
        }
    }

如果一切順利的話,你就可以看到打印出查詢的結果了。
那么,我們費了這么大勁寫的這個特簡單東西到底有什么意思呢?
這個例子雖然簡單,但它把mybatis核心組件都用上了。

MyBatis核心組件

從我們的代碼來看:
首先是SqlSessionFactoryBuilder讀取了配置文件,給我們返回了SqlSessionFactory對象,我們用SqlSessionFactory對象獲取SqlSession對象,再由SqlSession對象去獲取我們寫的mapper接口,此時就可以使用mapper接口查詢方法了。
所以整理出MyBatis核心組件:

  • SqlSessionFactoryBuilder:讀配置文件生成SqlSessionFactory對象
  • SqlSessionFactory: 生成SqlSession對象
  • SqlSession:執行所寫的mapper接口查詢方法
    不少書認為sqlSession.getMapper這樣的方法是使用了SQL Mapper組件,目前尚未看出這個組件在源碼里有體現,暫議。不過這個方法確實是以前方法的改進。更老一點的查詢方法:
 @Test
    public void selectOneOld() {
        try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
            Fruits fruits = sqlSession.selectOne("com.llh.mybatis.mapper.FruitsMapper.selectById", 1);
            System.out.println(fruits);
        }
    }

流程解讀

流程.png

簡書不支持時序圖語法。
基本上一個查詢的完整流程就是這樣子。

后記

看到打印的結果你可能會奇怪為啥有些字段沒值呢(如果你的代碼與我保持一致的話)?
首先確認數據庫里的值是否存在,如果存在,還是打印不出來的話,那就要來看看這個了。

自動映射

mybatis-config.xml文件里,properties標簽之后(順序很重要)添加:

    <settings>
        <setting name="autoMappingBehavior" value="NONE"/>
    </settings>

然后再次執行查詢,你就會驚喜地發現嘛都查不出來了。
這就是mybatis自動映射的功能(關閉方法)。
之前的配置中并沒有配置結果字段與Java字段的映射,mybatis會自動把查詢結果映射到指定Java類中具有相同名稱和setter方法字段上。

字段映射

關閉了自動映射功能,自然就想到使用手動映射。
FruitsMapper.xml文件內mapper標簽內添加:

   <resultMap id="BaseMapper" type="com.llh.mybatis.pojo.Fruits">
        <id column="id" jdbcType="INTEGER" property="id"/>
        <result column="color" jdbcType="VARCHAR" property="color" />
        <result column="fruits_name" jdbcType="VARCHAR" property="fruitsName" />
        <result column="weight" jdbcType="VARCHAR" property="weight" />
        <result column="created_at" jdbcType="TIMESTAMP" property="createdAt" />
        <result column="updated_at" jdbcType="TIMESTAMP" property="updatedAt" />
    </resultMap>

再給select標簽添加屬性resultMap="BaseMapper"就可以引用這套映射配置(也就是說你可以整多套配置來滿足需要)。
如此,之前沒有值的字段也就有了值。

備注

MyBatis 自動映射有三種模式:NONE、PARTIAL、FULL。

第一個已經知道了。
第二個是默認項。
第三個會對嵌套對象進行映射。
總結下:第三個基本不會用,如無特殊需求就用默認。事實上配合代碼生成工具,用第一個還是第二個配置并沒有什么區別。

源碼

此文使用項目源碼在這里,查看標簽v0.1里的代碼即可。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容