MyBatis03--Dao 代理模式
MyBatis 使用传统 Dao 开发方式
使用 Dao 的实现类,操作数据库
Dao 开发
1)创建 Dao 接口实现类
public class StudentDaoImpl implements StudentDao(){
}
2)实现接口中 select 方法
@Override
public List<Student> selectStudents() {
SqlSession sqlSession = MybatisUtil.getSqlSession();
String sqlId = "com.suyv.mybatis.dao.StudentDao.selectStudents";
//执行sql语句
List<Student> students = sqlSession.selectList(sqlId);
//关闭sqlSession
sqlSession.close();
return students;
}
测试查询操作:
@Test
public void testSelectStudent(){
StudentDao dao = new StudentDaoImpl();
List<Student> studentList = dao.selectStudents();
for (Student stu:studentList){
System.out.println(stu);
}
}
结果展示:
3)实现接口中 insert 方法
@Override
public int insertStudent(Student student) {
SqlSession sqlSession = MybatisUtil.getSqlSession();
String sqlId = "com.suyv.mybatis.dao.StudentDao.insertStudent";
//执行sql语句
int nums = sqlSession.insert(sqlId,student);
//事务提交
sqlSession.commit();
//关闭sqlSession
sqlSession.close();
return nums;
}
测试查询操作:
@Test
public void testInsertStudents(){
StudentDao dao = new StudentDaoImpl();
Student student = new Student();
student.setId(1003);
student.setName("盾山1");
student.setEmail("dunshan@qq.com");
student.setAge(28);
int nums = dao.insertStudent(student);
System.out.print("添加学生的数量:"+nums);
}
结果展示:
4)实现接口中 update 方法
@Override
public int updateStudent(Student student) {
SqlSession sqlSession = MybatisUtil.getSqlSession();
String sqlId = "com.suyv.mybatis.dao.StudentDao.updataStudent";
int num = sqlSession.update(sqlId,student);
sqlSession.commit();
sqlSession.close();
return num;
}
测试查询操作:
@Test
public void testUpdataStudent(){
StudentDao dao = new StudentDaoImpl();
Student student = new Student();
student.setId(1003);
student.setAge(500);
int nums = dao.updateStudent(student);
System.out.print("修改学生的数量:"+nums);
}
结果展示:
4)实现接口中 delete 方法
@Override
public int deleteStudent(int id) {
SqlSession sqlSession = MybatisUtil.getSqlSession();
String sqlId = "com.suyv.mybatis.dao.StudentDao.deleteStudent";
int num = sqlSession.update(sqlId,id);
sqlSession.commit();
sqlSession.close();
return num;
}
测试查询操作:
@Test
public void testDeleteStudent(){
StudentDao dao = new StudentDaoImpl();
int id = 1003;
int nums = dao.deleteStudent(id);
System.out.print("删除学生的数量:"+nums);
}
结果展示:
传统 Dao 开发方式的分析
在前面例子中自定义 Dao 接口实现类时发现一个问题:Dao 的实现类其实并没有干实质性工作,它仅仅就是通过 SqlSession 的相关 API 定位到映射文件 mapper 中相应 id 的 SQL 语句,真正对数据库进行操作的工作其实是由框架通过 mapper 中的 SQL 完成的。
所以,MyBatis 框架就抛开了 Dao 的实现类,直接定位到映射文件 mapper 中的相应 SQL 语句,对数据库进行操作。这种对 Dao 的实现方式称为 Mapper 的动态代理方式。
Mapper 动态代理方式无需程序员实现 Dao 接口。接口是由 MyBatis 结合映射文件自动生成的动态代理实现的。
Dao 代理实现 CURD
实现步骤
1)去掉 Dao 接口实现类
2)getMapper 获取代理对象
只需调用 SqlSession 的 getMapper()方法,即可获取指定接口的实现类对象。该方法的参数为指定 Dao接口类的 class 值。
SqlSession session = factory.openSession();
StudentDao dao = session.getMapper(StudentDao.class);
使用工具类:
StudentDao studentDao = MyBatisUtil.getSqlSession().getMapper(StudentDao.class);
3)使用 Dao 代理对象方法执行 sql 语句
实现原理
select 方法:
@Test
public void testSelectStudent(){
SqlSession sqlSession = MybatisUtil.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
//调用dao的方法,执行数据库操作
List<Student> students = dao.selectStudents();
for (Student stu:students){
System.out.println(stu);
}
}
insert 方法:
@Test
public void testInsertStudents(){
SqlSession sqlSession = MybatisUtil.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
Student student = new Student();
student.setId(1007);
student.setName("明世隐");
student.setEmail("mingshiyin@qq.com");
student.setAge(22);
int nums = dao.insertStudent(student);
sqlSession.commit();
System.out.print("添加学生的数量:"+nums);
}
update 方法
@Test
public void testUpdateStudent(){
SqlSession sqlSession = MybatisUtil.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
Student student = new Student();
student.setId(1007);
student.setAge(28);
int nums = dao.updateStudent(student);
sqlSession.commit();
System.out.print("修改学生的数量:"+nums);
}
delete 方法
@Test
public void testDeleteStudent(){
SqlSession sqlSession = MybatisUtil.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
int id = 1007;
int nums = dao.deleteStudent(id);
sqlSession.commit();
System.out.print("删除学生的数量:"+nums);
}
原理
动态代理:
MapperProxy 类定义:
invoke()方法:
重点方法: