百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

Mybatis系列-4-Mapper动态代理(mybatis接口动态代理原理)

myzbx 2025-03-24 18:31 34 浏览

冰冻三尺,非一日之寒。

Mybatis相关源码及文档:

 Mybatis官方技术文档  https://mybatis.org/mybatis-3/zh/index.html
 
 Mybatis源码包下载:https://github.com/mybatis/mybatis-3/releases
 
 所有代码及笔记gitee路径:https://gitee.com/simple-coding/all-demo-code.git

一.Mapper动态代理引入

不引入Mapper动态代理时,如下,我们会定义DAO实现类进行Mybatis的相关操作:

 @Override
 public int save(Student student)  throws Exception{
     try (SqlSession sqlSession = MyBatisUtils.getSqlSession();){
         //mapper.namespace+id
         int updateCount = sqlSession.update("test.save", student);
         sqlSession.commit();
         return updateCount;
     } catch (Exception e) {
         e.printStackTrace();
         throw e;
     }
 }
 
 @Override
 public List findAllStudent()  throws Exception{
     try (  SqlSession sqlSession = MyBatisUtils.getSqlSession();){
         //mapper.namespace+id
         return sqlSession.selectList("test.findAllStudent");
     }catch (Exception e) {
         e.printStackTrace();
         throw e;
     }
 }

上边这段代码也就是仅仅获取SqlSession调用与其相关的API,没有什么实质操作,而且两个方法除了API不同外其它部分几乎一模一样。

什么是Mapper动态代理:Mapper动态代理方式是指程序员在编码过程中只需编写DAO接口而不需要实现Dao接口。接口的实现是由MyBatis结合mapper映射文件自动生成的动态代理实现的。

二、Mapper动态代理演示

1.创建表SQL

 create table student(
   id int not null PRIMARY key auto_increment comment '主键',
   name varchar(20) comment '姓名',
   idNum  varchar(20) COMMENT '学号'
 ) comment '学生表';

2.创建实体类(lombok 插件)

 @Data
 @AllArgsConstructor
 @NoArgsConstructor
 public class Student {
     private Integer id;//主键
     private String name;//姓名
     private String idNum;//学号
 }

3.只定义Dao接口

 /**
  * 描述:Mapper动态代理
  */
 public interface StudentDao {
     /**
      * 保存学生
      * @param student
      * @return
      */
     int save(Student student) throws Exception;
 
     /**
      * 查询所有学生
      * @return
      */
     List findAllStudent() throws Exception;
 
     /**
      * 查询一个学生封装成map
      * @return
      */
     List<Map> findOneMap(Integer id) throws Exception;
 
     /**
      * 查询所有学生封装成map
      * @return
      */
     List<Map> findListMap() throws Exception;
 
     /**
      * 删除所有学生
      * @return
      */
     int deleteById(Integer id) throws Exception;
 
     /**
      * 修改所有学生
      * @return
      */
     int updateStudent(Student student) throws Exception;
 }

4.主配置mapper配置

 
 
  
  
 

5.Dao接口同目录下定义mapper.xml

 
 
 
    
    
           insert into student(name,idNum) values(#{name},#{idNum})
    
 
     
 
     
 
     
 
     
         delete from student where id = #{id}
     
 
     
         update student set name=#{name},idNum=#{idNum} where id = #{id}
     
 

6.测试类

使用getMapper获取代理实例。

 /**
  * 描述:日志配置及入门案例讲解示例
  */
 public class MybatisTest {
     private StudentDao studentDao;
     private SqlSession sqlSession;
     private Logger logger = LoggerFactory.getLogger(MybatisTest.class);
     @Before
     public void initStudentDao() throws Exception {
         sqlSession = MyBatisUtils.getSqlSession();
         studentDao = sqlSession.getMapper(StudentDao.class);
     }
     @After
     public void close() throws Exception {
         sqlSession.close();
     }
     /**
      * 保存学生
      * @return
      */
     @Test
     public void save() throws Exception{
         Student student = new Student("法外狂徒2","002");
         logger.info("更新前student:{}",student);
         int saveCount = studentDao.save(student);
         sqlSession.commit();
         logger.info("更新条数:{}",saveCount);
         logger.info("更新后student:{}",student);
     }
 
     /**
      * 查询所有学生
      * @return
      */
     @Test
     public void findAllStudent() throws Exception{
         studentDao.findAllStudent().forEach(System.out::println);
     }
 
     /**
      * 查询一个学生封装成map
      * @return
      */
     @Test
     public void findOneMap() throws Exception{
         studentDao.findOneMap(1).forEach(System.out::println);
     }
 
     /**
      * 查询所有学生封装成map
      * @return
      */
     @Test
     public void findListMap() throws Exception{
         studentDao.findListMap().forEach(System.out::println);
     }
 
     /**
      * 删除所有学生
      * @return
      */
     @Test
     public void deleteById() throws Exception{
         int deleteCount = studentDao.deleteById(4);
         sqlSession.commit();
         logger.info("删除条数:{}",deleteCount);
     }
 
     /**
      * 修改所有学生
      * @return
      */
     @Test
     public void updateStudent() throws Exception{
         Student student = new Student(4,"法外狂徒666","666");
         int updateCount = studentDao.updateStudent(student);
         sqlSession.commit();
         logger.info("修改条数:{}",updateCount);
     }
 }

框架在更新,技术在进步,之前的Mybatis的动态代理不支持Map查询,现在已经支持了。

三、Mybatis的Maven项目

前面已经说到使用Mapper动态代理,Mapper接口和xml配置文件,文件名一致且要放到同一个目录下。同一个目录说白了classpath相同。

也就是说你可以单独在resource类路径下创建同名包只存放xml。

如果使用maven创建项目,且源文件在同一个目录,这时就需要在pom中添加如下代码:

 
     
     
         
             src/main/java
             
                 **/*.xml
             
             true
         
     
 

否则,报错如图

报错图


四、总结

单独使用Mybatis时,使用Mapper动态代理步骤

  • 主配置使用

 
  
 


 
  
  • 只定义Dao接口
  • mapper的namespace与Dao全限定类名一致,statement的id为dao接口方法名
  • mapper与dao接口同名且同包
  • 使用SqlSession.getMapper(StudentDao.class);获取代理类
  • 操作dao接口方法

小伙伴有啥疑问,可以留言指教!!!

相关推荐

Xbox Series X具有比PS5更高的有效I/O吞吐量

来源:cnBeta在今年3月宣布XboxSeriesX时,微软就已经预告了全新的XboxVelocity架构,宣称可为次世代主机带来前所未有的功能体验。据悉,XboxVelocity体系结构有...

科个普:固态硬盘之友!DirectStorage显存直通车

谁能想到有一天,固态硬盘之友竟然是一个API——为了解决游戏Loading烦人的等待时间,微软利用NVMeSSD的超高读写速度特性,有针对性的开发了DirectStorageAPI,它可以让游戏直...

虚拟机备份应注意四大问题_虚拟机备份命令

2015-01-1405:48:00作者:赵为民虚拟化技术在近两年发展的非常快,很多企业都采用虚拟机技术来解决企业IT基础设施所面临的一些问题,如硬件过度浪费,扩展难等问题,但对于企业来说,保证企...

PS4支持进入倒计时:2026年春季新发售的PS4游戏将停用部分功能

PlayStation似乎正在逐步开始淘汰对上世代主机PS4的支持。据InsiderGaming独家报道,PS4的一些传统服务将在2026年春季停止提供。InsiderGaming收到的文件显示...

2026年春季起索尼PS4平台新发行游戏将停用部分旧版PSN功能

IT之家10月2日消息,据游戏媒体InsiderGaming今天报道,部分文件显示,索尼互娱似乎已经准备开始逐步淘汰PS4游戏机。InsiderGaming收到的文件显示,索尼...

吞吐量18.09GB/s,硬盘启用DirectStorage 1.1的GPU解压功能实测

IT之家12月21日消息,AMD在今年5月初曾表示,即便用户装备了NVMe的存储设备,也可能无法满足SmartAccessStorage(该技术建立在微软DirectStora...

面试官:如何让localStorage支持过期时间设置?

聊到localStorage想必熟悉前端的朋友都不会陌生,我们可以使用它提供的getItem,setItem,removeItem,clear这几个API轻松的对存储在浏览器本地的...

2025年是时候对localstorage说再见了

localStorage隐藏风险在前端开发领域,localStorage自诞生之日起就一直是数据持久化的首选方案。凭借其看似简单的setItem/getItemAPI,它成为了存储用户偏好和应用状...

前端最能打的本地存储方案_前端数据存储

前言之前开发了一个离线存储的需求,需要在本地存储较大的数据量,并且还要考虑到多种场景下的存储方式兼容。产品的原话就是“要又大又全”。既然存储量大,也要覆盖全多种设备多种浏览器。方案选择既然要存储的数量...

抛弃 localStorage,这个存储方案更安全更高效

在前端开发的世界里,浏览器存储一直是我们处理客户端数据持久化的重要工具。多年来,localStorage凭借其简单易用的API和跨会话持久化能力,成为了许多开发者的默认选择。然而,随着Web...

软件性能测试中链接追踪工具Zipkin工具的使用

大家好,今天一起来学习一下在软件性能测试过程中如何使用Zipkin这个工具来追踪链接程序逻辑链路上的相关问题首先我们了解一下Zipkin是什么?Zipkin是Twitter的一个开源项目,基于G...

Vue3管理系统实现动态路由和动态侧边菜单栏

在做Vue管理系统的时候,都会遇到的一个需求:每个用户的权限是不一样的,那么他可以访问的页面(路由),可以操作的菜单选项是不一样的,如果由后端控制,我们前端需要去实现动态路由,动态渲染侧边菜单栏。实现...

JS删除上一条浏览器历史记录的方法(登录回退)

JS使用window.location.replace删除上一条浏览器历史记录的方法(登录回退)一、问题如果用户登录状态过期,或者没有登录,当用户登录之后回退上一个页面的时候,就会回退到登录页面,这样...

LightRAG: 简单快速的检索增强生成工具

这里是Aideas,每日分享AI相关资讯。本文由AideasAgent整理并推荐。项目地址:/HKUDS/LightRAG,程序语言:Python,收藏:14,287,分支:1,996,...

实战指南:React 路由与Ant Design集成

路由管理:如何在React项目中集成react-router-dom使用前的准备:安装react-router-dom为了在React项目中使用路由功能,首先需要安装react-router-dom...