文章目錄
-
-
- 一、原始Dao層開發
-
- 1、原理
- 2、代碼
- 二、Mapper動态代理
-
- 1、Dao(Mapper)接口的工作原理:
- 2、mybatis代理實作方式
-
一、原始Dao層開發
1、原理
前面的例子我們是将SQL的執行寫在了測試方法中,在實際的開發中我們肯定是調用Dao接口的方法去執行sql的,也就是我們所說的原始Dao層開發,通過Dao接口的實作類去關聯執行對應的sql,步驟如下:
- 需要我們手動編寫dao接口和dao接口的實作類。
- 在實作類中使用一些對象,由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動态代理的方法并不難,但是使用要遵守一定的開發規範,如下:
- 建立一個interface接口,接口名稱保持與某個mapper.xml配置檔案相同。
- mapper的namespace指定interface全路徑名。
- 接口中方法定義的方法和方法參數,以及方法傳回類型,都與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對象也可以看到這是一個代理對象: