1. 程式人生 > >MyBatis知識三 DAO開發模式

MyBatis知識三 DAO開發模式

首先,我們應該先了解一下介面與類:

介面與類

SqlSessionFactoryBuilder類,用來建立SqlSessionFactory介面的類,其中在這個SqlSessionFactoryBuilder類中,過載 了許多的builder方法。他會根據我們傳入的流建立一個XMLConfigBuilder類,然後會呼叫parse()方法,返回一個Configuration物件,最後我們通過DefaultSqlSessionFactory(config),將我們的Configuration進行解析,返回我們最終需要的SqlSessionFactory。【點進去原始碼進行觀察】。
通過SqlSessionFactoryBuilder建立會話工廠SqlSessionFactory,將SqlSessionFactoryBuilder當成一個工具類使用即可,不需要使用單例管理SqlSessionFactoryBuilder。在需要建立SqlSessionFactory時候,只需要new一次SqlSessionFactoryBuilder即可。

SqlSessionFactory介面:SqlSessionFactory是一個介面,其具體實現類是DefaultSqlSessionFactory,通過類名我們可以看到SqlSessionFactory是一個SqlSession工廠,用來生產SqlSession物件,SqlSession中有我們進行資料庫操作的增刪改查介面。通過SqlSessionFactory建立SqlSession,使用單例模式管理sqlSessionFactory(工廠一旦建立,使用一個例項)。

SqlSession介面:SqlSession是一個介面其具體實現類為DefaultSqlSession,SqlSession介面主要定義了一些增刪改查方法,DefaultSQLSession是對SqlSession介面的具體實現,SqlSession是一個面向使用者(程式設計師)的介面。SqlSession是執行緒不安全的,在SqlSesion實現類中除了有介面中的方法(操作資料庫的方法)還有資料域屬性。
SqlSession最佳應用場合在方法體內,定義成區域性變數使用。

MyBatis 原始開發DAO步驟:

1、編寫DAO介面
2、編寫DAO實現

// 1、編寫DAO介面
public interface UserDao {
    public User seleteById(int id);
    public List<User> selectByName(String name);
    public void insertUser(User user);
    public void deleteUserById(int id);
    public void updateuserwithid(User user);
}

// 2、編寫DAO實現
public class UserDaoImpl implements UserDao { private SqlSessionFactory sqlsessionfactory; public UserDaoImpl(SqlSessionFactory sqlsessionfactory) { this.sqlsessionfactory = sqlsessionfactory; } @Override public User seleteById(int id) { SqlSession session = sqlsessionfactory.openSession(); User user = session.selectOne("user.selectById", id); session.close(); return user; } @Override public List<User> selectByName(String name) { SqlSession session = sqlsessionfactory.openSession(); List<User> users = session.selectList("user.selectByName", name); session.close(); return users; } } 3、單元測試 public class UserTest { private SqlSessionFactory sqlsessionfactory; private UserDao userdao; @Before public void testbefore(){ try { InputStream input = Resources.getResourceAsStream("mybatis.xml"); sqlsessionfactory = new SqlSessionFactoryBuilder().build(input); userdao = new UserDaoImpl(sqlsessionfactory); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Test public void testSeleteById() { User user = userdao.seleteById(1); System.out.println(user.getUsername()); } @Test public void testSelectByName() { List<User> users = userdao.selectByName("張三"); for(User user: users){ System.out.println(user.getUsername()); } }

說明:
1、此時我們的配置檔案的mapper中的namespace仍然沒有規則,是我們隨意命名的
2、對於介面中的方法名,此時也是和我們的配置檔案中的id名稱沒有一一對應,沒有規則的。
3、對於介面的實現類中,我們要設定屬性 SqlSessionFactory ,這是因為SqlSessionFactory 是可以共用的,而且,在於我們的Spring整合之後,其可以設計問單例模式。
4、對於SqlSession 則是宣告定義在我們的方法中
5、在利用單元測試時,我們理由註解@Before 進行我們的載入配置檔案,生成sqlsessionfactory ,然後在初始化我們的DAO介面實現時,將我們的sqlsessionfactory 引數傳遞到方法中。

MyBatis Mapper代理開發DAO步驟:

利用Mapper代理開發DAO,就是通過一些規範,將我們的DAO介面和我們的Mapper配置檔案通過一定的關聯建立起聯絡。

利用Mapper代理開發DAO,可以省去我們寫DAO實現的程式碼,但是在省力的同時,我們也必須遵循MyBatis給我們提供的Mapper代理開發規範,這樣的話,我們的MyBatis就可以自動生成mapper介面實現類代理物件:
1、 在mapper.xml中namespace等於mapper介面地址,這裡我們的namespace就有了嚴格的定義:必須為我們的介面的類的全路徑。
2、在我們的 mapper.java介面中的方法名和mapper.xml中statement的id必須嚴格保持一致。
3、mapper.java介面中的方法輸入引數型別和mapper.xml中statement的parameterType指定的型別一致。
4、mapper.java介面中的方法返回值型別和mapper.xml中statement的resultType指定的型別一致。

注意:
1、介面引數只能是一個,因為在配置檔案中只能存在一個parameterType。
2、對於select返回單個物件或者是List集合時,是根據介面的返回值進行呼叫selectOne和selectList方法的。

步驟:
1、編寫DAO介面
2、編寫mapper.xml配置檔案

// mapper介面 編寫
public interface UserDaoMapper {

    public User selectById(int id);
    public List<User> selectByName(String name);
    public void insertUser(User user);
    public void deleteUserWithID(int id);
    public void updateUserWithID(User user);

}

// 配置檔案 編寫
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.wf.dao.UserDaoMapper">

    <select id="selectById" parameterType="int"  resultType="com.wf.model.User">
        select * from User where id = #{id}
    </select>

    <select id="selectByName" parameterType="java.lang.String" resultType="com.wf.model.User">
        select * from User where username like '%${value}%' 
    </select>

    <delete id="deleteUserWithID" parameterType="java.lang.Integer">
        delete from user where id=#{id}
    </delete>

</mapper>


// 測試程式碼

public class UserDaoMapperTest {

    private SqlSessionFactory sqlsessionfactory;

    @Before
    public void testBefore() {
        InputStream inputStream;
        try {
            inputStream = Resources.getResourceAsStream("mybatis.xml");
            sqlsessionfactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    @Test
    public void test() {
        SqlSession session = sqlsessionfactory.openSession();

        UserDaoMapper userDaoMapper = session.getMapper(UserDaoMapper.class);

        User user = userDaoMapper.selectById(1);
        System.out.println(user.getUsername());
    }

}

說明:
1、 namespace按照規範進行設定為介面類的全路徑
2、id屬性一定要和方法名保持一致,
3、由於我們利用了代理模式,所以在獲取資料庫操作時是利用Session的getMapper方法,得到我們的代理物件,然後再利用代理物件去呼叫介面中的方法,而不是,Session的相關selectOne或者selectList方法。,注意上面的測試程式碼中的相關方式。
4、mapper介面方法引數只能有一個,所以對於多參傳遞較為複雜的語句,我們使用的是包裝物件進行開發的