【測試開發】知識點-mybatis,主要使用方式:接口式編程

昨天寫了一個 mybatis 的helloWord,雖然能跑起來,但是那種方式還是會存在一些問題。

  • 每次進行增刪改查,方法裏傳入的 sql 唯一標識id 就好長一串。
  • 再者就是傳入的查詢入參類型是一個object,也就是什麼都可以往裏面傳,如果傳"a",肯定查不出來數據。

那麼,mybatis 還提供了另一種更高級的使用方式:接口式編程,這也是後續開發中主要使用的方式。

我們可以使用一個接口來描述一個給定的sql語句,它的參數和返回值。

一、接口與配置文件動態綁定

在測試平臺項目下的 dao 層新建一個接口com.pingguo.bloomtest.dao.UserMapper:

package com.pingguo.bloomtest.dao;

import com.pingguo.bloomtest.pojo.User;

public interface UserMapper {

    User getUserById(Integer id);
}

定義好了接口,裏面有一個方法getUserById,顧名思義就是通過id查詢數據,返回 User 對象。

按照以往,定義好了接口,接下來還需要定義出接口的實現類。

但是現在這個接口就是用來查詢出 user 表記錄數據並封裝成 User 對象返回,而在之前定義好的 sql 映射文件UserMapper.xml裏,<select>標籤裏的 sql 也是做這個事情。

<mapper namespace="org.mybatis.example.UserMapper">
    <select id="selectUser" resultType="com.pingguo.bloomtest.pojo.User">
      select * from user where id = #{id}
    </select>
</mapper>

那麼,現在就可以把接口與配置文件進行動態綁定:

  • namespace:不要隨便寫了,對應接口的全類名
  • id: 對應接口裏的方法名

改完之後應該是這樣了:

<mapper namespace="com.pingguo.bloomtest.dao.UserMapper">
    <select id="getUserById" resultType="com.pingguo.bloomtest.pojo.User">
      select * from user where id = #{id}
    </select>
</mapper>

再寫一個測試方法查詢一下:

    @Test
    void test2() throws IOException {
        // 根據配置文件,創建一個 SqlSessionFactory 對象
        SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
        // 獲取 SqlSession 實例,可以執行已經映射的 sql 語句
        SqlSession session = sqlSessionFactory.openSession();
        // 獲取接口的實現類對象
        UserMapper userMapper = session.getMapper(UserMapper.class);

        User user = userMapper.getUserById(4);
        System.out.println(user);
    }

getMapper方法可以獲取到這個接口的實現對象。

第一步因爲要經常使用,所以抽出去了:

    public SqlSessionFactory getSqlSessionFactory() throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        return new SqlSessionFactoryBuilder().build(inputStream);
    }

執行測試,查詢成功。

那麼問題來了,這個接口還沒寫實現類,那麼

`UserMapper userMapper = session.getMapper(UserMapper.class);`

獲取到的是什麼?

加個打印System.out.println(userMapper.getClass());看下輸出。

原來是個代理對象

所以說,只要把接口和 xml文件進行動態綁定,mybatis 會爲接口自動創建一個代理對象,然後由代理對象去執行增刪改查方法。

二、關於 SqlSession

SqlSession代表和數據庫的一次會話。用完必須關閉,我上面的事例應該加上session.close();

另外,SqlSession也是非線程安全

  • 線程安全:就是在多線程環境下也不會出現數據不一致,
  • 非線程安全: 就有可能出現數據不一致的情況。

所以不能像這樣寫:

如果這樣寫,可能會出現A線程 用了 SqlSession,然後關掉了,但是線程B 還在用。所以每次使用都應該去獲取新的對象,不要放在成員變量中。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章