文章出處

上一篇博文總結了一下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]

原因是缺少 無參的構造方法。

 


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()