天天看點

MyBatis(五)——Mybatis動态代理

文章目錄

      • 一、原始Dao層開發
        • 1、原理
        • 2、代碼
      • 二、Mapper動态代理
        • 1、Dao(Mapper)接口的工作原理:
        • 2、mybatis代理實作方式

一、原始Dao層開發

1、原理

前面的例子我們是将SQL的執行寫在了測試方法中,在實際的開發中我們肯定是調用Dao接口的方法去執行sql的,也就是我們所說的原始Dao層開發,通過Dao接口的實作類去關聯執行對應的sql,步驟如下:

  1. 需要我們手動編寫dao接口和dao接口的實作類。
  2. 在實作類中使用一些對象,由SqlSessionFactoryBuilder對象獲得SqlSessionFactory對象,由SqlSessionFactory對象獲得SqlSession對象,再由SqlSession對象裡面封裝的一系列方法實作對資料庫的操作。

2、代碼

建立dao接口的實作類(其實就是将Test測試裡面的邏輯移到了這裡):

public class StudentDaoImpl implements StudentDao {
    @Override
    public Student selectStudentById(Integer id) {
      // 一些代碼已封裝
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        String sqlId = "com.macay.dao.StudentDao"+"."+"selectStudentById";
        Student students = sqlSession.selectOne(sqlId);
        sqlSession.close();
        return students;
    }

    @Override
    public List<Student> selectStudents() {
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        String sqlId = "com.macay.dao.StudentDao"+"."+"selectStudents";
        List<Student> students = sqlSession.selectList(sqlId);
        sqlSession.close();
        return students;
    }

    @Override
    public void insertStudent(Student student) {
    }
}
           

測試類中直接調用dao對象中的方法完成對sql語句的執行:

@Test
    public void testSelectStudentsByUtils() {
        StudentDao studentDao = new StudentDaoImpl();
        Student student = studentDao.selectStudentById(2);
        System.out.println(student);
    }

    @Test
    public void testInsert() {
        StudentDao studentDao = new StudentDaoImpl();
        List<Student> students = studentDao.selectStudents();
        students.forEach(student -> System.out.println(student));
    }
           

雖然這種方式是可行的,但是如果有多個dao接口我們就要建立多個實作類,不但有大量重複的代碼,而且存在寫死不利于維護。

二、Mapper動态代理

Mybatis使用了動态代理機制,我們可以隻編寫資料互動的接口及方法定義,和對應的Mapper映射檔案,具體的互動方法實作由MyBatis來完成。這樣大大節省了開發DAO層的時間。

實作Mapper動态代理的方法并不難,但是使用要遵守一定的開發規範,如下:

  1. 建立一個interface接口,接口名稱保持與某個mapper.xml配置檔案相同。
  2. mapper的namespace指定interface全路徑名。
  3. 接口中方法定義的方法和方法參數,以及方法傳回類型,都與mapper.xml配置檔案中的SQL映射的id及輸入/輸出映射類型相同。

滿足這幾點,就可以使用SqlSession類擷取Mapper代理(即一個interface接口類型的對象)來執行SQL映射配置。

1、Dao(Mapper)接口的工作原理:

Dao接口的工作原理實際上就是動态代理,在執行Dao接口的方法時,實際上執行的是mybatis的代理對象,代理對象通過反射機制擷取Dao接口的類全名和方法,再通過類全名和方法找到Xml中要執行的sql語句,然後使用SqlSession對象執行sql語句并将sql執行結果傳回。

源碼解析:https://blog.csdn.net/xiaokang123456kao/article/details/76228684

2、mybatis代理實作方式

使用SqlSession對象的方法 getMapper(dao.class)

代碼如下:

public class MyTest {

    /**
     * 動态代理開發
     */
    @Test
    public void testSelectStudentsByUtils() {
        // 1、獲得sqlSession對象
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        // 2、擷取Mapper代理對象
        StudentDao mapper = sqlSession.getMapper(StudentDao.class);
        // 3、執行Mapper代理對象的查詢方法
        Student student = mapper.selectStudentById(2);
        System.out.println(student);
        // 4、關閉session
        sqlSession.close();
    }

    @Test
    public void testInsert() {
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        StudentDao mapper = sqlSession.getMapper(StudentDao.class);
        List<Student> students = mapper.selectStudents();
        students.forEach(student -> System.out.println(student));
        sqlSession.close();
    }
}
           

列印mapper對象也可以看到這是一個代理對象:

MyBatis(五)——Mybatis動态代理

繼續閱讀