MyBatis03--Dao 代理模式

本文介绍了MyBatis的传统Dao开发方式,包括创建Dao接口实现类并实现CURD操作,然后分析了这种方式的局限性。接着,文章详细阐述了Dao的代理实现,通过去除实现类,直接使用getMapper获取动态代理对象来执行SQL。最后,解释了Mapper动态代理的实现原理,主要涉及MapperProxy类的invoke方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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()方法:
在这里插入图片描述
重点方法:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

憨憨浩浩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值