上一篇博文總結了一下mybatis的入門,接下來就要開發dao方法了,這篇博文主要總結一下mybatis中原始dao開發的方法,最后并總結一下原始dao開發方法的弊端。mybatis中dao開發應該使用mapper代理的方法,這將在下一篇博文中介紹。
原始dao開發思路比較簡單,寫個dao接口和dao實現類即可。需要向dao實現類中注入sqlSessionFactory,在方法體內通過sqlSessionFactory創建sqlSession。為什么在方法體內創建呢?因為mybatis中sqlSession是線程不安全的。如果在方法外面以成員變量的方式創建,可能會引發線程安全問題。下面總結一下原始dao開發的步驟(dao的方法跟上一節入門程序中的方法一致):
1. 寫UserDao接口
public interface UserDao { //根據id查詢用戶信息 public User findUserById(int id) throws Exception; //根據用戶名模糊查詢 public List<User> findUserByName(String name) throws Exception; //添加用戶信息 public void insertUser(User user) throws Exception; //刪除用戶信息 public void deleteUser(int id) throws Exception; //更新用戶信息 public void updateUser(User user) throws Exception; }
2. 寫UserDaoImpl實現類
public class UserDaoImpl implements UserDao { private SqlSessionFactory sqlSessionFactory; //需要向dao實現類中注入SqlSessionFactory,由于沒和Spring整合,這里通過構造函數注入 public UserDaoImpl(SqlSessionFactory sqlSessionFactory) { this.sqlSessionFactory = sqlSessionFactory; } @Override public User findUserById(int id) throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(); User user = sqlSession.selectOne("test.findUserById", id); //釋放資源 sqlSession.close(); return user; } @Override public List<User> findUserByName(String name) throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(); List<User> list = sqlSession.selectList("test.findUserByName", name); //釋放資源 sqlSession.close(); return list; } @Override public void insertUser(User user) throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(); sqlSession.insert("test.insertUser", user); sqlSession.commit();//執行插入要先commit sqlSession.close(); } @Override public void deleteUser(int id) throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(); sqlSession.delete("test.deleteUser", id); sqlSession.commit();//執行插入要先commit sqlSession.close(); } @Override public void updateUser(User user) throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(); sqlSession.update("test.updateUser", user); sqlSession.commit();//執行插入要先commit sqlSession.close(); } }
從UserDaoImpl實現類中可以看出,首先SqlSessionFactory需要注入進來,這里通過構造函數來注入,傳個SqlSessionFactory進來即可完成注入。另外,sqlSession都是在具體方法內部創建的,沒有將sqlSession放到外面,因為在方法內部,相對于每個線程是獨立的,不會引起線程安全問題。至于每個方法內部的實現,和上一節的入門程序邏輯一樣。
3. 寫單元測試UserDaoImplTest
public class UserDaoImplTest { private SqlSessionFactory sqlSessionFactory; @Before public void setUp() throws Exception { //創建sqlSessionFactory String resource = "SqlMapConfig.xml"; //mybatis配置文件 //得到配置文件的流 InputStream inputStream = Resources.getResourceAsStream(resource); //創建會話工廠SqlSessionFactory,要傳入mybaits的配置文件的流 sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); } @Test public void testFindUserById() throws Exception { //創建UserDao的對象 UserDao userDao = new UserDaoImpl(sqlSessionFactory); System.out.println(userDao.findUserById(1)); } }
從JUnit測試程序中可以看出,通過@Before注解,將SqlSessionFactory在測試方法執行之前初始化好,然后在測試方法中,直接通過構造函數傳進去即可,這就和上面的UserDaoImpl實現類接上了。然后測試一下添加用戶即可。
4. 原始dao開發存在的問題
從上面的代碼中,可以很明顯的看出原始dao開發方式有以下弊端:
1 dao接口實現類方法中存在大量重復代碼,從設計上來看,應該抽取。 2 調用sqlSession方法時,將satement的id硬編碼了,即類似于”test.findUserById”這種,都寫死了。 3 sqlSession的方法中,要求傳入的參數是Object類型的(泛型),也就是說如果我傳錯了參數,編譯不會報錯,執行的時候才會報錯,不利于開發。
這些都是原始dao開發方式中存在的問題,在了解了原始dao開發方式的問題后,再來使用mapper代理開發dao,就可以形成鮮明的對比了。這篇博文就總結到這。
本篇可能發生的錯誤是:
Caused by: org.apache.ibatis.executor.ExecutorException: No constructor found in mybatis.po.User matching [java.lang.Integer, java.lang.String, java.sql.Date, java.lang.String, java.lang.String]
原因是缺少 無參的構造方法。
文章列表