昨天寫了一個 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
也是非線程安全。
- 線程安全:就是在多線程環境下也不會出現資料不一緻,
- 非線程安全: 就有可能出現資料不一緻的情況。
--不要用肉體的勤奮,去掩蓋思考的懶惰--