【MyBatis 持久层框架】Mapper代理开发详细解读

news2024/11/24 3:27:53

文章目录

  • 1. 前言
  • 2. Mapper 代理开发
  • 3. 过程剖析
  • 4. 总结

1. 前言

前面在 MyBatis 快速入门篇中,我们使用了 MyBatis 原生的开发方式操作数据库,解决了 JDBC 操作数据库时的硬编码和操作繁琐的问题。实际上,在 Java 项目中,我们更常用的是 Mapper 代理开发的方式。

image-20230126233131746

两种方式有什么不同呢?

前面在使用基本方式操作数据库时,我们使用 sqlSession 原生的方法 selectList 执行 sql 语句并处理结果集对象。示例:

List<Student> students = sqlSession.selectList("test.selectAll"); //参数是一个字符串,该字符串必须是映射配置文件的 namespace.id

该方法的参数必须是 sql 映射配置文件的 name.id ,并且是以字符串的方式传递给该方法,于是这里又出现了硬编码的问题,而且这里使用 id 的方式也不是一种方便的设计,因为我们在编码时还需要在对应的映射配置文件中寻找 id,于是出现了 Mapper 代理开发的方式来解决这个问题。

在使用 Mapper 代理开发方式操作数据库时,通过 SqlSession 类对象获取一个指定 Mapper 接口的 Mapper 代理对象,使用该代理对象就可以调用对应 Mapper 接口中的方法,而这个方法就与映射配置文件中的 id 对应,从而找到了 sql 并执行,最后处理结果集对象。示例:

//3. 执行sql
//3.1 获取StudentMapper接口的代理对象
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
List<Student> students = studentMapper.selectAll();

总的来说,Mapper 代理方式具有以下两个优点:

  • 解决了原生方式中硬编码的问题
  • 简化了后期执行 sql

2. Mapper 代理开发

从上面的例子中不难看出,使用 Mapper 代理的方式具有更多的优势,首先他不依赖于字符串的字面值,会更加的方便和安全。其次,如果你的 IDE 有代码自动补全的功能,那么它可以帮你快速的是选择映射文件的 sql 语句,而不依赖于对应的 id。

使用 Mapper 代理开发的方式,必须执行以下几个步骤:

  1. 定义与 sql 映射配置文件同名的 Mapper 接口,并将 Mapper 接口和 sql 映射配置文件防止在同一目录下
  2. 设置 sql 映射文件的 namespace 属性为 Mapper 接口的全限定名
  3. 在 Mapper 接口中定义方法,方法名就是 sql 映射文件中的sql语句的 id,并保持参数类型和返回值类型相同

下面通过案例了解 Mapper 代理开发的方式的过程,案例依然是使用入门篇中的查询学生信息,并封装为对象,存放在集合中。

第一步

org.chengzi.mapper 包下创建 StudentMapper,示例:

public interface StudentMapper {
    List<Student> selectAll();
    Student selectById(int id);
}

在 resources 下创建 org / chengzi / mapper 目录,并在该文件目录下创建 StudentMapper.xml 配置文件。这样做保证了 Mapper 接口和 sql 映射配置文件在同一文件目录下。

第二步:设置 sql 映射文件的 namespace 属性和 Mapper 接口的全限定名一致。示例:

<!--
    namespace:名称空间。必须是对应接口的全限定名
-->
<mapper namespace="org.chengzi.mapper.StudentMapper">
    <select id="selectAll" resultType="org.chengzi.pojo.User">
        select *
        from student;
    </select>
</mapper>

第三步:在 MyBatis 核心配置文件中加载 sql 映射配置文件,示例:

<mappers>
      <!--加载sql映射文件-->
      <mapper resource="org/chengzi/mapper/StudentMapper.xml"/>
</mappers>

注意:后面两步使用 / 作为文件路径分隔符

完成上面三步我们就可以编写测试代码来操作数据库,完成相关操作。示例:

public class MyBatisDemo2 {

    public static void main(String[] args) throws IOException {

        //1. 加载mybatis的核心配置文件,获取 SqlSessionFactory
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        //2. 获取SqlSession对象,用它来执行sql
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //3. 执行sql
        //3.1 获取StudentMapper接口的代理对象
        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
        List<Student> students = studentMapper.selectAll();

        System.out.println(students);
        //4. 释放资源
        sqlSession.close();
    }
}

运行结果:

image-20230128201911101

不同于 MyBatis 的基本方法,这里我们通过 sqlSession 对象对应的方法获取了 StudentMapper 接口的代理对象,使用该代理对象执行 sql 语句,封装结果集对象。返回代理对象的过程由MyBatis内部完成。

小 tips:在 MyBatis 核心配置文件中加载 sql 映射配置文件时,如果 sql 映射配置文件数量较多时,这个步骤也是比较麻烦的,MyBatis 也提供了解决这个问题的方法。

如果 Mapper 接口名称和 sql 映射文件名称相同,并在同一目录下,则可以使用包扫描的方式简化 sql 映射文件的加载,只需要在核心配置文件中将加载 sql 映射配置文件的部分修改为:

<mappers>
    <!--加载sql映射文件-->
    <!-- <mapper resource="org/chengzi/mapper/UserMapper.xml"/>-->
    <!--Mapper代理方式-->
    <package name="org.chengzi.mapper"/>
</mappers>

3. 过程剖析

在使用 Mapper 代理开发时,我们通过 SqlSessionFactory 类的 openSession() 方法获取了 SqlSession 类对象,接着通过 SqlSession 类对象获取指定 Mapper接口的 Mapper 代理对象。

在获取 Mapper 代理对象时,我们可以找到对应的 Mapper 接口,在同一个目录下可以找到对应的与该接口同名的 sql 映射文件。使用代理对象调用对应Mapper接口中的方法,该方法对应着 sql映射配置文件中的 id 属性,通过 id 属性可以找到 对应的 sql 语句,进而执行了sql语句并封装结果集对象。

例如在上面案例中,studentMapper 代理对象执行了 selectAll() 方法,返回 List 对象,其实其底层还是执行了下面的语句:

 List<User> users = sqlSession.selectList("test.selectAll"); 

4. 总结

使用 MyBatis 原生方式开发,部分过程依赖于字符串常量值,存在硬编码的问题,同时使用命令空间和 sql 唯一标识作为执行 sql 的参数,在编写代码时比较麻烦。使用 Mapper 代理的方式具有更多的优势,首先他不依赖于字符串的字面值,会更加的方便和安全。其次,如果你的 IDE 有代码自动补全的功能,那么它可以帮你快速的是选择映射文件的 sql 语句,而不依赖于对应的 id。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/185370.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python3——函数

目录 一、函数定义 二、函数调用 1.打印Hello World 2.判断最大值 3.计算矩形面积 4.help说明文档 三、参数传递 (一)位置参数 (二)关键字参数 (三)默认参数(缺省参数) (四)可变参数(收集参数) 1.位置可变参数(接收所有的位置参数&#xff0c;返回一个元组) 2.关键…

高通开发系列 - MSM8909 lk aboot阶段点灯操作

By: fulinux E-mail: fulinux@sina.com Blog: https://blog.csdn.net/fulinus 喜欢的盆友欢迎点赞和订阅! 你的喜欢就是我写作的动力! 目录 第一种LK提供的接口实现第二种直接操作寄存器这篇文章之前请参考下:高通开发系列 - MSM8909指示灯操作 在LK中点灯有两种方式,一种…

JAVA-定位排查bug

在开发过程中难免会遇到bug&#xff0c;理解bug的含义&#xff0c;定位bug的位置&#xff0c;对于解决bug至关重要&#xff01;掌握高效的排错技巧&#xff0c;对于程序员来说必不可少。 目录 一、错误异常的分类 二、常见报错信息及原因&#xff08;持续更新中&#xff09;…

域内权限维持:AdminSDHolder

01、简介 AdminSDHolder是一个特殊的AD容器&#xff0c;通常作为某些特权组成员的对象的安全模板。Active Directory将采用AdminSDHolder对象的ACL并定期将其应用于所有受保护的AD账户和组&#xff0c;以防止意外和无意的修改并确保对这些对象的访问是安全的。如果攻击者能完全…

Flex布局和主要属性用法详解

目录 前言 一个小例子 基本概念&#xff1a; 设置在主轴上的排列方式 设置在侧轴上的排列方式 更换主轴和侧轴方向 换行 align-content属性 元素&#xff08;子容器&#xff09;的相关属性 flex-basis flex-grow flex-shrink属性 flex属性 前言 flex布局是继标准…

JDBC-Statement

1.Statement执行静态sql语句&#xff08;“字符串”&#xff09; 返回结果 2.&#xff01;实际工作一般用PreparedStatement来进行sql语句的执行&#xff0c;因为sql注入的风险 3and4.SQl注入就是Statement没有检查我们输入sql语句&#xff0c;一些别有用心的可能写一些危害数据…

智能手表主控芯片盘点,智能手表GUI,智能手表市场

聚焦&#xff1a;无线连接芯片&#xff0c;市场&#xff0c;技术 祝大家新年快乐&#xff0c;开工大吉&#xff01;趁寒假简单梳理了下智能手表应用&#xff0c;做个分享&#xff0c;不对的地方欢迎交流指正&#xff1b; 01 市场容量&#xff0c;分类及拓扑 2个数据供参考 一个…

C++ dll、lib 的定义以及引用,

最近在研究socket&#xff0c;发现socket程序要依赖ws2_32.dll,涉及到动态链接库&#xff0c;有点懵&#xff0c;上网恶补了一下链接库的知识&#xff0c;最后总结出这么一篇文章 链接库分为两种&#xff1a;动态链接库(dll) 和静态链接库(lib) 动态链接库 &#xff1a; 动态链…

【C++】C++11语法解析

&#x1f308;欢迎来到C专栏~~C11 (꒪ꇴ꒪(꒪ꇴ꒪ )&#x1f423;,我是Scort目前状态&#xff1a;大三非科班啃C中&#x1f30d;博客主页&#xff1a;张小姐的猫~江湖背景快上车&#x1f698;&#xff0c;握好方向盘跟我有一起打天下嘞&#xff01;送给自己的一句鸡汤&#x1f…

大数据分析案例-基于多元线性回归算法构建用户信用评分模型

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

ue4c++日记9(指定区域生成角色)

目录 创建C类 头文件 代码文件 结果 创建C类 头文件 // Fill out your copyright notice in the Description page of Project Settings.#pragma once#include "CoreMinimal.h" #include "GameFramework/Actor.h" #include "ASPawnVolum.generated…

vSphere with Tanzu概念介绍

vSphere with Tanzu是在vSphere7.0及之后出现的新功能&#xff0c;它可以在虚拟化层创建一个Kubernetes 控制平面&#xff0c;并将vSphere 集群资源转化为Kubernetes集群资源&#xff0c;这样可以直接在ESXI主机上运行Kubernetes工作负载&#xff0c;创建Kubernetes集群并部署容…

测试环境频繁Full GC问题的解决思路

背景 上游调用方&#xff0c;反馈当前welink-front服务不可用&#xff1b; 临时解决办法 手动重启welink-front服务&#xff0c;重启之后观测到业务日志正常刷&#xff0c;说明该问题暂时得到了解决&#xff1b; 但没过多久&#xff0c;上游调用方的同学又找来了&#xff0…

C++ 继承

一. 概念 继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段&#xff0c;它允许程序员在保持原有类特性的基础上进行扩展&#xff0c;增加功能&#xff0c;这样产生新的类&#xff0c;称派生类。继承呈现了面向对程序设计的层次结构&#xff0c;体现了由…

IDEA开发 常用代码规范插件 常用辅助类插件

规范类 阿里巴巴规范 Alibaba Java Coding Guidelines 插件地址 阿里官方出的开源的代码规范插件 GitHub地址 配合阿里出的规范手册《码出高效 Java开发手册》食用效果更佳 不用购买哈&#xff01;GitHub上开源的 码出高效&#xff1a;Java开发手册下载 静态代码检查 Sonar…

数学建模学习笔记(14)聚类模型

聚类模型K均值聚类算法和K均值聚类算法系统聚类算法&#xff08;层次聚类&#xff09;DBSCAN聚类算法聚类问题概述&#xff1a;把样本划分为由相似的对象组成的多个类的过程。 K均值聚类算法和K均值聚类算法 K均值聚类算法流程&#xff1a; 指定需要划分的簇的个数K。随机选…

【Redis | 黑马点评】商户查询缓存

文章目录什么是缓存&#xff1f;添加商户缓存缓存更新策略主动更新策略实现商铺查询的缓存与数据库双写一致缓存穿透问题的解决思路编码解决商品查询的缓存穿透问题缓存雪崩问题及解决思路缓存击穿问题及解决思路基于互斥锁的方式解决缓存击穿问题基于逻辑过期的方式解决缓存击…

初始网络编程

专栏简介: JavaEE从入门到进阶 题目来源: leetcode,牛客,剑指offer. 创作目标: 记录学习JavaEE学习历程 希望在提升自己的同时,帮助他人,,与大家一起共同进步,互相成长. 学历代表过去,能力代表现在,学习能力代表未来! 目录 1.网络发展史 1.1 独立模式 1.2 网络互联 1.3 局…

一文全解决 数据库连接报错Communications link failure,create connection SQLException

具体报错如下&#xff1a; 解决思路&#xff1a; 当时看到数据库报错Communications link failure我就想到应该是数据库连接不上的问题&#xff0c;具体想了以下几种情况 1.数据库未连接 1.1过期了&#xff0c;mysql里有一个wait_timeout的值需要大于数据库连接池的最大超时时…

新来测试用一手Postman实现UI自动化测试拿下了大厂面试官

看到这篇文章的标题&#xff0c;是不是有小伙伴会感到惊讶呢&#xff1f; Postman不是做接口测试的吗&#xff1f;为什么还能做UI自动化测试呢&#xff1f; 其实&#xff0c;只要你了解Selenium的运行原理&#xff0c;就可以理解为什么Postman也能实现UI自动化测试了。 Sele…