一、动态代理
使用SqlSession.getMapper(dao接口.class) 获取这个dao接口的对象,不要自己写实现了
回顾没有动态代理的代码:
StudentDao–Dao层的接口
1 2 3 4 5 6 7 8 9
| public interface StudentDao {
List<Student> selectStudent();
int insertStudent(Student student);
}
|
StudentDaoImpl–Dao层的接口的实现类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| public class StudentDaoImpl implements StudentDao {
@Override public List<Student> selectStudent() { SqlSession sqlSession = MyBatisUtils.getSqlSession(); String sqlId = "com.apps.dao.StudentDao.selectStudent"; List<Student> studentsList = sqlSession.selectList(sqlId); sqlSession.close(); return studentsList; }
@Override public int insertStudent(Student student) { SqlSession sqlSession = MyBatisUtils.getSqlSession(); String sqlId = "com.apps.dao.StudentDao.insertStudent"; int insert = sqlSession.insert(sqlId, student); sqlSession.commit(); sqlSession.close(); return insert; }
}
|
注意:MyBatisUtils.getSqlSession();是自己定义的工具类用于获取SqlSession对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| package com.apps.utils;
import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException; import java.io.InputStream;
public class MyBatisUtils {
private static SqlSessionFactory factory;
static { try { String config = "mybatis-config.xml"; InputStream in = Resources.getResourceAsStream(config); factory = new SqlSessionFactoryBuilder().build(in); } catch (IOException e) { e.printStackTrace(); } }
public static SqlSession getSqlSession() { return factory.openSession();
}
}
|
回到我们的StudentDaoImpl–Dao层的接口的实现类,我们看selectStudent()方法,我们通过调用sqlSession对象的selectList方法传入Dao接口的方法全限定名称,这个selectList方法底层就是根据方法全限定名称,获取方法返回值,使用指定的sql语句等。实现这个Dao接口中的方法很麻烦,大部分操作都相同。
所以sqlSession对象给了我们getMapper()方法,传入dao接口.class,获取dao接口的实现类对象,它的底层就是通过反射来实现的,如调用getMapper()方法实现selectStudent()方法时,它会获取这方法的全限定名称,通过全限定名称使用指定的sql语,内部区分调用sqlSession对象的selectList()方法,然后关闭对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| public class TestStudentDao {
@Test public void testSelectStudent() {
SqlSession sqlSession = MyBatisUtils.getSqlSession(); StudentDao studentDao = sqlSession.getMapper(StudentDao.class); List<Student> studentList = studentDao.selectStudent(); studentList.forEach(student -> System.out.println(student)); }
@Test public void testInsertStudent() { SqlSession sqlSession = MyBatisUtils.getSqlSession(); StudentDao studentDao = sqlSession.getMapper(StudentDao.class); Student s = new Student(1005,"小李子","sb@qq.com",33); int i = studentDao.insertStudent(s); sqlSession.commit(); System.out.println(i); }
}
|
不用写dao层实现类,现在只要定义接口,在使用、测试时通过sqlSession.getMapper(接口.class)获取实现类。