使用动态代理的条件分析
我们需要用到StudentDao.xml(Mapper文件)中的信息,所以我们先把他拷贝过来,供大家往下看的时候进行翻阅:
<?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.bipt.dao.StudentDao">
<select id="selectStudents" resultType="com.bipt.domain.Student">
select id,name,email,age from Student order by id
</select>
<insert id="insertStudent">
insert into student value (#{id},#{name},#{email},#{age})
</insert>
</mapper>
-
我们分析上面的代码所的查处的结论: 我们在StudentDao中所写的方法,大多数都是重复性的代码,而主要区别在于该方法执行的SQL语句,也就是各个方法中sqlId的值, 也就是全限定名称+标签id的值:
String sqlId = "com.bipt.dao.StudentDao.selectStudents"; String sqlId = "com.bipt.dao.StudentDao.insertStudent";
拿到这个sqlId的值之后,我们就能够执行StudentDao.xml(Mapper文件)中的sql语句了.
-
我们再来观察基于StudentDao接口实现的StudentDaoImpl类中的两行代码
//StudentDaoImpl类中selectStudents()方法的stundentDao对象调用selectStudents的语句: List<Student> students = stundentDao.selectStudents(); //StudentDaoImpl类中insertStudents()方法的stundentDao对象调用insertStudent的语句: int i = studentDao.insertStudent(student);
-
在这两行代码中,studentDao的全限定名称为com.bipt.dao.StudentDao
而这个全限定名称与StudentDao.xml配置文件中的namespace是完全一样的.
-
在往后我们可以发现,StudentDao所调用的方法名称,与StudentDao.xml(Mapper文件)中标签id值完全一样
-
那么怎么来判断这个是执行的哪种操作呢(select,delete,insert or update)?
通过Dao中方法的返回值可以确定mybatis要调用的sqlSession的方法
如果返回值为List, 调用的是sqlSession.selectList()方法
如果返回值为int或非List 需要观察Mapper文件中的标签或 就会调用sqlSession中相应的inset 或者update等方法
-
MyBatis的动态代理: MyBatis根据dao的方法调用,获取执行SQL语句的信息.
mybatis根据你的dao接口,创建出一个dao接口的实现类,并创建出这个类的对象,完成sqlSession调用方法,访问数据库.
-
动态代理getMapper()
我们要求在Mapper文件中,namespace为接口的全限定名称,语句id为Mapper文件中的方法名称,满足这些条件后我们就可以使用我们的动态代理了.
使用MyBatis的动态代理机制,使用sqlSession.getMapper(dao接口) getMapper就能够获取dao对应的实现类对象,然后我们就能够调用相应的方法进行对数据库的操作.
private static void select() {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
//我们可以调用dao的方法,执行对数据库的操作
List<Student> students = dao.selectStudents();
for (Student stu : students) {
System.out.println(stu);
}
}
结果: