在【004】中,細心的同學可能會發現,在增刪改查幾個函數中,存在大量的重複的代碼,如下這段代碼。
// mybatis配置文件
String resource = "SqlMapConfig.xml";
// 得到配置文件流
InputStream inputStream = Resources.getResourceAsStream(resource);
// 創建會話工廠,傳入mybatis的配置文件信息
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 通過工廠得到SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 釋放資源
sqlSession.close();
上面的這段代碼,在四個函數中,均存在。介紹mybatis開發DAO之前,先介紹下SqlSession的使用。
1. SqlSessionFactoryBuilder
通過SqlSessionFactoryBuilder創建會話工廠SqlSessionFactory,將SqlSessionFactoryBuilder當成一個工具類使用即可,不需要使用單例管理SqlSessionFactoryBuilder。在需要創建SqlSessionFactory時候,只需要new一次SqlSessionFactoryBuilder即可。
2. SqlSessionFactory
通過SqlSessionFactory創建SqlSession,使用單例模式管理sqlSessionFactory(工廠一旦創建,使用一個實例)。將來mybatis和spring整合後,使用單例模式管理sqlSessionFactory。
3. SqlSession
SqlSession是一個面向用戶(程序員)的接口。SqlSession中提供了很多操作數據庫的方法:如:selectOne(返回單個對象)、selectList(返回單個或多個對象)。
SqlSession是線程不安全的,在SqlSesion實現類中除了有接口中的方法(操作數據庫的方法)還有數據域屬性。SqlSession最佳應用場合在方法體內,定義成局部變量使用。
————————————————————————————————————————————————————————————————————
現在,介紹mybatis開發DAO的原始開發方法,所謂原始開發方法是指程序員需要寫dao接口和dao實現類,簡單的思路就是:需要向dao實現類中注入SqlSessionFactory,在方法體內通過SqlSessionFactory創建SqlSession。
首先,來看下,前幾章下來後,我們的項目代碼結構,本章,將在過去的基礎上繼續開發。
【1】創建dao接口,路徑爲:src\main\java\dao\UserDao.java,代碼如 下:
//根據id查詢用戶信息
User findUserById(int id) throws Exception;
//根據id插入用戶
void insertUserById(User user) throws Exception;
//根據id修改用戶信息
void deleteUserById(int id) throws Exception;
【2】創建接口實現類UserDaoImpl.java。路徑爲:src\main\java\dao\UserDaoImpl.java,代碼如下:
public class UserDaoImpl implements UserDao {
private SqlSessionFactory sqlSessionFactory;
// 需要向dao實現類中注入SqlSessionFactory
// 這裏通過構造方法注入
public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
}
public User findUserById(int id) throws Exception{
// 通過工廠得到SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 通過SqlSession操作數據庫
// 第一個參數:映射文件中statement的id,等於=namespace+"."+statement的id
// 第二個參數:指定和映射文件中所匹配的parameterType類型的參數
// sqlSession.selectOne結果 是與映射文件中所匹配的resultType類型的對象
// selectOne查詢出一條記錄
User user = sqlSession.selectOne("test.findUserById",id);
// 釋放資源
sqlSession.close();
return user;
}
public List<User> findUserByUsername(String name)throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
List<User> list = sqlSession.selectList("test.findUserByUsername",name);
// 釋放資源
sqlSession.close();
return list;
}
public void insertUserById(User user) throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
//執行插入操作
sqlSession.insert("test.insertUser", user);
// 提交事務
sqlSession.commit();
// 釋放資源
sqlSession.close();
}
public void deleteUserById(int id) throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
//執行插入操作
sqlSession.insert("test.deleteUser", id);
// 提交事務
sqlSession.commit();
// 釋放資源
sqlSession.close();
}
}
【3】完成以上兩個部分後,開始創建測試代碼,進行測試,這裏,我們只對findUserById()進行測試。在測試文件中,寫入如下代碼:
public class UserDaoImplTest {
//創建sqlsessionfactory工廠
private SqlSessionFactory sqlSessionFactory;
@Before
public void setUp() throws Exception {
// mybatis配置文件
String resource = "SqlMapConfig.xml";
// 得到配置文件流
InputStream inputStream = Resources.getResourceAsStream(resource);
// 創建會話工廠,傳入mybatis的配置文件信息
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
public void findUserById() throws Exception {
//創建UserDao對象
UserDao userDao = new UserDaoImpl(sqlSessionFactory);
// 調用UserDao的方法
User user = userDao.findUserById(22);
System.out.println(user);
}
}
以上代碼將會查詢id=22的用戶信息。
大功告成了,剩下的測試方法跟之前章節的是一個道理。
下面簡單總結原始方法開發dao的問題。
【總結】
1、dao接口實現類方法中存在大量模板方法,設想能否將這些代碼提取出來,大大減輕程序員的工作量。
2、調用sqlsession方法時將statement的id硬編碼了
3、調用sqlsession方法時傳入的變量,由於sqlsession方法使用泛型,即使變量類型傳入錯誤,在編譯階段也不報錯,不利於程序員開發。
在下一章中,我們將會介紹mybatis開發DAO的另外一種方式,基於mapper代理的開發方式。