当前位置: 首页 > news >正文

MyBatis补充

控制类和dao层接口以及mapper中的xml是怎样的关联的?

在Mybatis中,控制类和dao层接口是通过mapper的xml文件进行连接的。

  1. 控制类调用dao层接口中的方法,通过接口实现进行访问数据库操作。
  2. dao层接口定义数据库操作的方法,提供给控制类调用。
  3. mapper的xml文件中定义了dao层接口中方法的具体实现,包括SQL语句的编写和参数的映射关系。
  4. 接口实现是通过Mybatis的动态代理机制实现的。Mybatis会根据接口和对应的mapper的xml文件生成接口的实现类,并在需要访问数据库时调用mapper中的SQL语句进行操作。

MyBatis动态SQL

动态 SQL 只有几个基本元素,与 JSTL 或 XML 文本处理器相似,十分简单明了,大量的判断都可以在 MyBatis 的映射 XML 文件里配置,以达到许多需要大量代码才能实现的功能。

动态 SQL 大大减少了编写代码的工作量,更体现了 MyBatis 的灵活性、高度可配置性和可维护性。

元素作用备注
if判断语句单条件分支判断
choose(when、otherwise)相当于Java中的switch case语句多条件分支判断
trim、where辅助元素用于处理一些SQL拼装问题
foreach循环语句在in语句等列举条件常用
bind辅助元素拼接参数

where 标签

where 标签主要用来简化 SQL 语句中的条件判断,可以自动处理 AND/OR 条件

if 标签

MyBatis if 类似于 Java 中的 if 语句,是 MyBatis 中最常用的判断语句。使用 if 标签可以节省许多拼接 SQL 的工作,把精力集中在 XML 的维护上。

bind 标签

bind 标签可以通过 OGNL [对象导航图语言(Object Graph Navigation Language)]表达式自定义一个上下文变量。

	<!-- resultType查出来的结果中的每一行都要映射成该类型的对象,写全称 --><select id="getStaff" resultType="com.easy.bean.Staff">select * from staff <!-- 根据参数不同组合出不同的SQL语句 动态SQL语句 标签 --><where><!-- 编写条件语句 如果where标签中有内容 会自动添加where关键字 --><if test="checktext !=null and checktest !=''"><!-- 重新定义参数内容 --><bind name="liketext" value="'%'+checktext+'%'"/>name like #{liketext}</if></where></select>

foreach 标签

foreach 标签用于循环语句,它很好的支持了数组和 List、set 接口的集合,并对此提供遍历的功能。

foreach 标签主要有以下属性

  • item:表示集合中每一个元素进行迭代时的别名。
  • index:指定一个名字,表示在迭代过程中每次迭代到的位置。
  • open:表示该语句以什么开始(既然是 in 条件语句,所以必然以(开始)。
  • separator:表示在每次进行迭代之间以什么符号作为分隔符(既然是 in 条件语句,所以必然以,作为分隔符)
  • close:表示该语句以什么结束(既然是 in 条件语句,所以必然以)结束)。
	<insert id="addList">insert into staff(code,name,salary,username,userpass)values<foreach collection="list" item="it" separator=",">(#{it.code},#{it.name},#{it.salary},#{it.username},#{it.userpass})</foreach></insert>

注意:

使用 foreach 标签时,最关键、最容易出错的是 collection 属性,该属性是必选的,但在不同情况下该属性的值是不一样的,主要有以下 3 种情况:

  1. 如果传入的是单参数且参数类型是一个 List,collection 属性值为 list。
  2. 如果传入的是单参数且参数类型是一个 array 数组,collection 的属性值为 array。
  3. 如果传入的参数是多个,需要把它们封装成一个 Map,当然单参数也可以封装成 Map。Map 的 key 是参数名,collection 属性值是传入的 List 或 array 对象在自己封装的 Map 中的 key。

choose、when和otherwise 标签

MyBatis 中动态语句 choose-when-otherwise 类似于 Java 中的 switch-case-default 语句。由于 MyBatis 并没有为 if 提供对应的 else 标签,如果想要达到<if>...<else>...</else> </if> 的效果,可以借助 <choose>、<when>、<otherwise> 来实现。

当判断条件中有字符串时,比较用双等号,里面的字符串用双引号,外面用单引号。

在xml文件中,尖括号<>有特殊含义,小于号用 &lt; 替换,大于号用 &gt; 替换

	<select id="getStaffBySalary" resultType="com.easy.bean.Staff">select * from staff<where><!-- 参数名 salarytext --><choose><when test='salarytext == "低"'><!-- 用&lt表示小于号,用&gt表示大于号 -->salary &lt;= 5000</when><when test='salarytext == "中"'>salary &gt;5000 and salary &lt;=8000</when><otherwise>salary &gt;8000</otherwise></choose></where></select>

set 标签

在 Mybatis 中,update 语句可以使用 set 标签动态更新列。set 标签可以为 SQL 语句动态的添加 set 关键字,剔除追加到条件末尾多余的逗号。

    <update id="editStaffItem">update staff<set><!-- set标签会去除多余的逗号 --><if test='name!=null and name!=""'>name=#{name},</if><if test="salary!=null">salary=#{salary},</if></set><where><!-- where标签会去除多余的and,or -->id=#{id}</where></update>

trim 标签

trim 一般用于去除 SQL 语句中多余的 AND 关键字、逗号,或者给 SQL 语句前拼接 where、set 等后缀,可用于选择性插入、更新、删除或者条件查询等操作。

这种效果和where相同,where本身已经可以做到去除多余的and,or的功能。


resultMap元素

resultMap 是 MyBatis 中最复杂的元素,主要用于解决实体类属性名与数据库表中字段名不一致的情况,可以将查询结果映射成实体对象。

为了使数据库的查询结果和返回值类型中的属性能够自动匹配,通常会对 MySQL 数据库和 JavaBean 采用同一套命名规则,即 Java 命名驼峰规则,这样就不需要再做映射了(数据库表字段名和属性名不一致时需要手动映射)。

一对一关联查询

通过 <resultMap> 元素的子元素 <association> 处理一对一级联关系

<association> 元素中通常使用以下属性。

  • property:指定映射到实体类的对象属性。
  • column:指定表中对应的字段(即查询返回的列名)
  • javaType:指定映射到实体对象属性的类型。
  • select:指定引入嵌套查询的子 SQL 语句,该属性用于关联映射中的嵌套查询。

查询员工及其部门,根据id将部门id子查询的结果映射到员工类Staff的部门属性dep上:

	<resultMap id="staffAndDep" type="com.easy.bean.Staff"><association column="dep_id" select="getStaffDep" property="dep"></association></resultMap><select id="getStaffDep" resultType="com.easy.bean.Department">select * from department where id=#{dep_id}</select><!-- 一对一查询或一对多查询需要指定映射方式 resultMap --><select id="getStaffAndDep" resultMap="staffAndDep">select * from staff</select>

控制类的方法:

	@GetMapping("staff/dep")public CommonResult getStaffAndDep() {List<Staff> lists = dao.getStaffAndDep();return CommonResult.success(lists);}

数据访问层接口:

    List<Staff> getStaffAndDep();


一对多关联查询

通过 <resultMap> 元素的子元素 <collection> 处理一对多级联关系,collection 可以将关联查询的多条记录映射到一个 list 集合属性中。

查询部门及其下的员工信息,根据id将查询结果映射到部门类的员工列表里:

	<resultMap id="departmentAndStaff" type="com.easy.bean.Department"><!-- <id column="id" property="depid"></id><result column="name" property="depname"></result> --><result column="id" property="id"></result><collection fetchType="lazy" column="id" select="getDepStaff" property="staffList"></collection></resultMap><select id="getDepStaff" resultType="com.easy.bean.Staff">select * from staff where dep_id=#{id}</select>

result 标签中的内容确保了id列被映射到Department对象的id属性上,如果result不指定id,系统会将id用于子查询的映射而不进行封装,导致最后id属性为默认值0

控制类方法:

	@GetMapping("dep")//@Transactionalpublic CommonResult getDep() {List<Department> list=departmentDao.getDep();return CommonResult.success(list);}

数据访问层接口:

	List<Department> getDep();

resultType和resultMap的区别:

MyBatis 的每一个查询映射的返回类型都是 resultMap,只是当我们提供的返回类型是 resultType 时,MyBatis 会自动把对应的值赋给 resultType 所指定对象的属性,而当我们提供的返回类型是 resultMap 时,MyBatis 会将数据库中的列数据复制到对象的相应属性上,可用于复制查询。


MyBatis缓存

MyBatis 提供了一级缓存和二级缓存的支持。默认情况下,MyBatis 只开启一级缓存

一级缓存

  • 一级缓存是基于 PerpetualCache(MyBatis自带)的 HashMap 本地缓存,作用范围为 SQLession 域内。当 session flush(刷新)或者 close(关闭)之后,该 session 中所有的 cache(缓存)就会被清空。
  • 在参数和 SQL 完全一样的情况下,我们使用同一个 SqlSession 对象调用同一个 mapper 的方法,往往只执行一次 SQL。因为使用 SqlSession 第一次查询后,MyBatis 会将其放在缓存中,再次查询时,如果没有刷新,并且缓存没有超时的情况下,SqlSession 会取出当前缓存的数据,而不会再次发送 SQL 到数据库。
  • 在参数和 SQL 完全一样的情况下,我们使用同一个 SqlSession 对象调用同一个 mapper 的方法,往往只执行一次 SQL。因为使用 SqlSession 第一次查询后,MyBatis 会将其放在缓存中,再次查询时,如果没有刷新,并且缓存没有超时的情况下,SqlSession 会取出当前缓存的数据,而不会再次发送 SQL 到数据库。

@Transactional 注解是用于标记在方法或类上的注解,可以声明一个事务的边界。当方法或类被@Transactional注解标记时,Spring会自动为其创建一个事务,并在方法执行前开启事务、执行方法体、执行成功后提交事务,或在遇到异常时进行回滚。

	@GetMapping("dep")@Transactionalpublic CommonResult getDep() {List<Department> list=departmentDao.getDep();System.out.println("-------------");list=departmentDao.getDep();return CommonResult.success();}

在启动类上使用 @EnableTransactionManagement 注解用于开启Spring的声明式事务管理。

@SpringBootApplication
@EnableTransactionManagement
public class EasySpringApplication {public static void main(String[] args) {SpringApplication.run(EasySpringApplication.class, args);}
}

通过两个事务相关的注解确保两次方法调用在同一个SqlSession中,验证一级缓存:

通过日志可以看到,两次调用方法只执行了一次SQL语句。


二级缓存

二级缓存是全局缓存,作用域超出 SQLsession 范围之外,可以被所有 SqlSession 共享。手动开启

在mapper的xml文件中使用以下语句开启二级缓存:

	<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true" />

二级缓存要求参与的对象都是可序列化的,实现Serializable接口。

测试代码:

	@GetMapping("dep")public CommonResult getDep() {List<Department> list=departmentDao.getDep();System.out.println("-------------");list=departmentDao.getDep();return CommonResult.success();}

从日志可见:二级缓存已生效。


懒加载

MyBatis的懒加载是一种延迟加载机制,允许在需要时才加载关联对象的属性。默认情况下,MyBatis使用的是立即加载,即在执行查询语句时,同时加载关联对象的属性。但在某些情况下,如果查询结果中包含了大量的关联对象,且这些关联对象可能在业务逻辑中并不总是需要的,这时懒加载就能提高查询性能和减少内存消耗

懒加载可以在以下两种场景中使用:

  1. 延迟加载关联对象:当你在查询对象时,并不立即加载关联对象的属性,只有在真正访问关联对象的属性时,才会执行额外的查询语句来加载关联对象的数据。

  2. 延迟加载集合属性:当你查询对象并包含有关联的集合属性时,仅在访问这些集合属性时才会执行额外的查询语句来加载集合属性中的数据。

懒加载在 collection 标签中设置属性 fetchType="lazy"

fetchType用于控制数据库查询时关联对象的加载时机和方式。它决定了是在查询主对象时立即加载关联对象(迫切加载),还是在访问关联对象时才从数据库中加载(懒加载)。

	<resultMap id="departmentAndStaff" type="com.easy.bean.Department"><result column="id" property="id"></result><collection fetchType="lazy" column="id" select="getDepStaff" property="staffList"></collection></resultMap><select id="getDepStaff" resultType="com.easy.bean.Staff">select * from staff where dep_id=#{id}</select><select id="getDep" resultMap="departmentAndStaff">select * from department</select>

测试代码:

	@GetMapping("dep")public CommonResult getDep() {List<Department> list=departmentDao.getDep();System.out.println("-------------");System.out.println(list.get(0));System.out.println(list.get(1));return CommonResult.success();}

从日志中可见:在方法刚调用时仅执行了 select * from department 并没有立即进行子查询,

当方法访问到集合元素 list.get(0) 和 list.get(1) 时,子查询语句才分别执行。

相关文章:

MyBatis补充

控制类和dao层接口以及mapper中的xml是怎样的关联的&#xff1f; 在Mybatis中&#xff0c;控制类和dao层接口是通过mapper的xml文件进行连接的。 控制类调用dao层接口中的方法&#xff0c;通过接口实现进行访问数据库操作。dao层接口定义数据库操作的方法&#xff0c;提供给控制…...

系统架构师(每日一练16)

每日一练 答案与解析 1.软件测试一般分为两个大类:动态测试和静态测试。前者通过运行程序发现错误&#xff0c;包括()等方法;后者采用人工和计算机辅助静态分析的手段对程序进行检测&#xff0c;包括()等方法。答案与解析 问题1 A.边界值分析、逻辑覆盖、基本路径 B.桌面检查、…...

实践致知第17享:电脑忽然黑屏的常见原因及处理方法

一、背景需求 小姑电话说&#xff1a;最近&#xff0c;电脑忽然就黑屏了&#xff08;如下图所示&#xff09;&#xff0c;但是等待几十秒甚至一分钟&#xff0c;电脑就能自然恢复了&#xff0c;这种状况一天能出现三四次&#xff0c;怎么办&#xff1f; 二、分析诊断 电脑黑屏…...

微信小程序--实现地图定位---获取经纬度

(1) (2) (3) html: <view class"titleTwo" style"border: none;"><view class"fontSize30 invoiceTile">企业地址</view><view class"invoiceRight" bind:tap"tapChooseAddress" data-maptype"…...

【Python系列】使用 `isinstance()` 替代 `type()` 函数

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

【多模态大模型】 BLIP-2 in ICML 2023

一、引言 论文&#xff1a; BLIP-2: Bootstrapping Language-Image Pre-training with Frozen Image Encoders and Large Language Models 作者&#xff1a; Salesforce Research 代码&#xff1a; BLIP-2 特点&#xff1a; 该方法分别使用冻结的图像编码器&#xff08;ViT-L/…...

HPC高性能计算平台

随着技术的发展和数据量的爆炸性增长&#xff0c;企业面临的挑战日益复杂&#xff0c;对计算能力的需求也在不断增加。这些问题的解决超出了传统计算方法的能力范围&#xff0c;高性能计算&#xff08;HPC&#xff09;正是为解决这类问题而生。 高性能计算&#xff08;HPC&…...

前端常用的几个工具网站

觉得不错的前端工具类网站 1、Grid布局生成 https://cssgrid-generator.netlify.app 2、拟物按钮样式生成 https://neumorphism.io 3、玻璃形态效果 在线制作CSS玻璃形态 4、一些Button、checkBox、switch、card的css样式 零代码 - 精美CSS样式库 5、CSS阴影生成 在线创建…...

支付功能之代收代付

有很多老板问小编&#xff1a;“这个分账功能好是好&#xff0c;也能搞定项目中的二清问题和税务纠纷&#xff0c;但还是太复杂了&#xff0c;每次要添加被分账对象都需要提交材料进行审核&#xff0c;太繁琐了&#xff0c;有没有更方便快捷的支付产品来解决资金问题&#xff1…...

QPixmap

pixel[ˈpɪksl]像素 QPixmap 是 Qt 框架中用于处理图像的一个类。它主要用于在屏幕上显示和处理图像&#xff0c;提供了许多实用的功能&#xff0c;如加载、保存、缩放、旋转、合并等。 绘制 从文件加载&#xff1a;从指定文件加载图像。 QPixmap pixmap(":/images/exam…...

Laravel门面之下:构建自定义门面应用的艺术

Laravel门面之下&#xff1a;构建自定义门面应用的艺术 在Laravel框架中&#xff0c;门面&#xff08;Facade&#xff09;提供了一种将类静态调用与面向对象代码解耦的优雅方式。门面是一个全局可访问的类&#xff0c;它为底层复杂的服务提供了一个简单的接口。然而&#xff0…...

智启万象 | 2024 Google 开发者大会直播攻略

8 月 7 日上午 9:30 2024 Google 开发者大会 主旨演讲直播将准时开启 想要在线上探索大会精彩内容&#xff1f; 快查收这份观看指南&#xff01; 8 月 7 日上午 9:30 2024 Google 开发者大会开幕 锁定大会官网观看主旨演讲现场直播&#xff01; 本次大会内容将同步于多个…...

技巧:print打印内容到控制台时信息显示不全

# 请求一个接口&#xff0c;res是响应内容&#xff0c;使用res.text打印的信息不全 #使用流式处理响应 #如果你需要流式处理大的响应&#xff0c;确保你在处理响应内容的同时不会提前结束流。resself.request_base(select_api,change_datachange_data)print("")# pri…...

3.表的操作

目录 创建表 创建表案例&#xff1a; 查看表结构 修改表 1.增加新列 2.修改列的属性 3.删除列 4.修改表名 5.修改列 删除表 创建表 语法&#xff1a; CREATE TABLE [IF NOT EXISTS] table_name(field1 datatype1 [COMMENT 注释信息],field2 datatype2 [COMMENT 注释…...

AI回答:C#项目编译后生成部分文件的主要职责

【引入】以ConsoleApp1为例&#xff0c;请问C#编译之后以下文件有啥用 1.bin\runtimes 文件夹存放什么&#xff0c;有什么用&#xff1f; bin\runtimes 文件夹存放了项目的运行时相关文件&#xff0c;这些文件包括了各种目标平台的运行时库。 2.bin\生成的exe文件可以在别的电脑…...

RPC通信的简单流程

远程调用者假设需要调用Login方法&#xff0c;将调用的信息通过muduo库&#xff0c;同时进行了序列化和反序列化&#xff0c;发送到Rpcprovider上&#xff0c;RpcProvider通过对象和方法表来确定需要调用哪个服务对象的哪个方法。 UserRpcServiceRpc和UseRpcServiceRpcStub是继…...

前端发版(发包)缓存,需要强制刷新问题处理

问题原因&#xff1a; 浏览器问题 一、创建初始版本文件(public/version.json) { "version": "1722240835844" }二、设置版本判断&#xff08;version.js&#xff09; import axios from "axios";const isNewVersion () > {let baseUrl …...

洛谷练习(8.4/8.5)

题目 P2036 PERKET题目描述思路代码 P3799 小 Y 拼木棒题目描述思路代码 P1010 幂次方题目描述思路代码 P1498 南蛮图腾题目描述思路代码 P1928 外星密码题目描述思路代码 P2036 PERKET 题目描述 比较苦度和酸度的最小差值 思路 搜索最小差值 代码 void dfs(int sd,int k…...

DLMS/COSEM中的信息安全:加密算法(下)1

4.公钥算法 4.1概述 一般来说,公钥密码系统使用难以解决的问题作为算法的基础。RSA算法基于非常大的整数的素因子分解。椭圆曲线密码学(ECC)是基于求解椭圆曲线离散对数问题(ECDLP)的难度。与RSA相比,ECC提供了相似的安全级别,但密钥大小明显减少。ECC特别适用于嵌入式…...

ES6中的Promise、async、await,超详细讲解!

Promise是es6引入的异步编程新解决方案&#xff0c;Promise实例和原型上有reject、resolve、all、then、catch、finally等多个方法&#xff0c;语法上promise就是一个构造函数&#xff0c;用来封装异步操作并可以获取其成功或失败的结果&#xff0c;本篇文章主要介绍了ES6中的P…...

为什么Gartner刚下调3家明星厂商评级?AI原生数据库选型必须重看这7项硬指标,否则Q3上线即重构

第一章&#xff1a;Gartner评级下调背后的AI原生数据库范式转移 2026奇点智能技术大会(https://ml-summit.org) Gartner近期将多家传统关系型数据库厂商在“云数据库管理系统魔力象限”中的位置下调&#xff0c;其公开报告明确指出&#xff1a;“评估标准已从‘事务吞吐与SQL…...

2026-04-11 全国各地响应最快的 BT Tracker 服务器(电信版)

数据来源&#xff1a;https://bt.me88.top 序号Tracker 服务器地域网络响应(毫秒)1http://211.75.210.221:6969/announce广东广州电信322http://60.249.37.20:80/announce广东东莞电信333http://211.75.205.189:6969/announce广东深圳电信364udp://132.226.6.145:6969/announc…...

为什么你的LangChain应用上线3个月就不可维护?——AI原生债务的4层腐蚀模型与熔断机制设计

第一章&#xff1a;AI原生软件研发技术债务管理策略 2026奇点智能技术大会(https://ml-summit.org) AI原生软件区别于传统软件的核心在于其生命周期深度耦合模型迭代、数据漂移、推理服务演进与反馈闭环。技术债务在此类系统中不再仅体现为代码冗余或架构腐化&#xff0c;更表…...

天天流鼻血,是否会把身体血都流光?

天天流鼻血,每次都能弄湿好几张纸巾,这种反复的出血确实让人揪心。我能理解你对身体变化的担忧,尤其是之前检查正常,现在却持续出血,难免会怀疑:是不是身体悄悄发生了变化? 核心结论‌:‌凝血功能在短期内一般不会突然恶化,但长期反复失血、潜在疾病进展或药物影响等…...

实验室安全必备:5种危险有机试剂的淬灭操作指南(含实操视频)

实验室安全必修课&#xff1a;5种高危有机试剂的精准淬灭实战手册 推开有机化学实验室的门&#xff0c;扑面而来的除了试剂特有的气味&#xff0c;还有潜藏在每个操作步骤中的安全挑战。氢化锂铝遇水瞬间释放的氢气、硼氢化钠与酸接触时产生的自燃性硼烷、三光气分解时可能生成…...

基于ModelEngine Nexent与RAG技术:构建智能AI心理医生全流程指南

本文将手把手带你使用ModelEngine Nexent框架&#xff0c;基于RAG技术构建一个能提供专业心理支持的AI助手。我们将从环境配置开始&#xff0c;逐步实现知识库构建、智能体编排到最终部署的全流程。 文章目录一、认识ModelEngine二、环境配置三、模型配置3.1 准备API-Key3.2 配…...

构建高可用CephFS NFS网关:NFS-Ganesha与RADOS集群的深度整合

1. 为什么需要CephFS的NFS网关&#xff1f; 想象一下你有个超大的仓库&#xff08;CephFS&#xff09;&#xff0c;里面堆满了各种宝贝文件。但每次取东西都得用专门的叉车&#xff08;Ceph客户端&#xff09;&#xff0c;而大多数工人&#xff08;普通服务器&#xff09;只会开…...

MambaOut部署指南:本地、云端和边缘设备的完整解决方案

MambaOut部署指南&#xff1a;本地、云端和边缘设备的完整解决方案 【免费下载链接】MambaOut MambaOut: Do We Really Need Mamba for Vision? (CVPR 2025) 项目地址: https://gitcode.com/gh_mirrors/ma/MambaOut MambaOut是一个高效的计算机视觉模型&#xff0c;它通…...

AI Linux运维——项目部署(一)

一、项目介绍 中州养老系统为养老院量身定制开发专业的养老管理软件产品&#xff1b;涵盖来访管理、入退管理、在住管理、服务管理 、财务管理等功能模块&#xff0c;涉及从来访参观到退住办理的完整流程。 项目原型访问地址&#xff1a;https://codesign.qq.com/s/45927762406…...

【研报300】长安猎手增程式皮卡前后桥动传系统解读:快速量产的动传系统设计

本报告提供限时下载&#xff0c;请查看文后提示以下仅为报告部分内容&#xff1a;摘要&#xff1a;长安猎手增程式皮卡的前后桥动传系统&#xff0c;采用基于燃油皮卡底盘的改造方案&#xff0c;前桥通过电机传动轴复用成熟燃油车桥&#xff0c;后桥采用偏置同轴电驱桥&#xf…...