MyBatis查询两个字段,返回Map,一个字段作为key,一个字段作为value的实现

项目场景:

  在使用MyBatis,我们经常会遇到这种情况:SELECT两个字段,需要返回一个Map,其中第一个字段作为key,第二个字段作为value。MyBatis的MapKey虽然很实用,但并不能解决这种场景。


问题描述

第一种情况

我们查询出id和name两个字段,想用Map来接收它,然后想着直接MyBatis直接返回Map对象就好了

Mapper:

这种情况结果只能一条记录,多条记录会报错:nested exception is org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 3

/*** 结果只能一条记录,多条记录会报错*/
@Select("select id, name from t_test where id = 1")
Map<String, Object> selectOne();

Service测试: 

@Service
public class TestService{@Autowiredprivate TestMapper testMapper;public void selectOne() {Map<String, Object> map = testMapper.selectOne();for (Map.Entry<String, Object> entry : map.entrySet()) {System.out.println("key:"+entry.getKey()+",value:"+entry.getValue());}}
}

 打印的结果:

key:name,value:张三
key:id,value:1

发现打印的结果跟想的不一样 ,想的结果是key:1,value:张三,因为MyBatis是把结果以("id":1)、("name":"张三")的形式保存在Map中的。


第二种情况

然后使用@MapKey改进

Mapper:

这样就可以接收多条记录了

/*** Map接收多条记录*/@Select("select id, name from t_test")@MapKey("id")   //指定keyMap<Integer, Map<String, Object>> tooMany();

Service测试:  

@Service
public class TestService{@Autowiredprivate TestMapper testMapper;public void tooMany() {Map<Integer, Map<String, Object>> map = testMapper.tooMany();for (Map.Entry<Integer, Map<String, Object>> entry : map.entrySet()) {System.out.println("key:"+entry.getKey()+",value:"+entry.getValue());}}
}

 打印的结果:

key:1,value:{name=张三, id=1}
key:2,value:{name=李四, id=2}
key:3,value:{name=王五, id=3}

 数据是都能正常获取了,可还不是想要的格式,想的结果是key:1,value:张三。


解决方案:

如果要实现id字段作为key,name字段作为value,可以使用mybatis提供的ResultHandler的结果处理器,他能感知到你的每条数据(可以当做limit 1来理解),拿到该条数据你加工下,继续拿下一条数据,有点类似于for循环,每次拿到数据放到map中,最后拿到这个map。

1.xml

首先xml写好sql,@select注解也可以,但是没有xml方便,因为需要返回resultMap

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.test.dao.TestMapper"><!--这里key-value报红不影响--><resultMap id="mapResult" type="map"><result property="key" column="id"/><result property="value" column="name"/></resultMap><select id="resultHandler" resultMap="mapResult">select id, name from t_test</select></mapper>

这里大家会发现key和value会报红,其实不影响,如果实在觉得不舒服,那么可以把result这两行注释掉变成:

<resultMap id="mapResult" type="map"><!--<result property="key" column="id"/>--><!--<result property="value" column="name"/>-->
</resultMap>

 但是这样的话,后面map获取值就要改成:map.get("id"), map.get("name"),就不能兼容其它的表使用。

2.Mapper

返回值必须为void,有其它参数可以加在mapResultHandler参数之前比如:

resultHandler(Integer id, MapResultHandler<Integer, String> mapResultHandler)

/*** 使用ResultHandler实现key-value接收多条记录* 返回值必须为void,有其它参数可以加在mapResultHandler参数之前比如:* resultHandler(Integer id, MapResultHandler<Integer, String> mapResultHandler)*/void resultHandler(MapResultHandler<Integer, String> mapResultHandler);

3.ResultHandle

对应xml配置的key-value

public class MapResultHandler<K,V> implements ResultHandler<Map<K,V>> {private final Map<K,V> mappedResults = new HashMap<>();@Overridepublic void handleResult(ResultContext context) {Map map = (Map) context.getResultObject();mappedResults.put((K)map.get("key"), (V)map.get("value"));}public Map<K,V> getMappedResults() {return mappedResults;}
}

 4.Service测试:  

@Service
public class TestService{@Autowiredprivate TestMapper testMapper;public void resultHandler() {MapResultHandler<Integer, String> resultHandler = new MapResultHandler<>();testMapper.resultHandler(resultHandler);Map<Integer, String> map = resultHandler.getMappedResults();for (Map.Entry<Integer, String> entry : map.entrySet()) {System.out.println("key:"+entry.getKey()+",value:"+entry.getValue());}}
}

5.打印结果:

key:1,value:张三
key:2,value:李四
key:3,value:王五

达到了想要的效果,但是代码量也增加了,为了实现key-value牺牲太大。


备用方案:

使用ResultHandler的解决方案比较麻烦,还是使用@MapKey比较方便,就是获取value的时候再多一步,除了使用Map接收,还可以使用实体类接收。

1.创建实体类

// User实体类
public class User {private Integer id;private String name;// 省略getter和setter方法
}

2.Mapper

/*** 实体类接收多条记录*/
@Select("select id, name from t_test")
@MapKey("id")   //指定key
Map<Integer, User> getUser();

3. Service测试:  

@Service
public class TestService{@Autowiredprivate TestMapper testMapper;public void getUser() {Map<Integer, User> map = testMapper.getUser();for (Map.Entry<Integer, User> entry : map.entrySet()) {System.out.println("key:"+entry.getKey()+",value:"+entry.getValue());}}
}

 4.打印结果:

key:1,value:User(id=1, name=张三)
key:2,value:User(id=2, name=李四)
key:3,value:User(id=3, name=王五)

总结 

  1. Map<String, Object>只能接收单条数据。
  2. @MapKey指定key,可以接受多条数据,会把查询得到的每一行数据封装成一个Map(key=id,value=Map),然后把所有的Map又以字段名为key,都封装进一个Map或者实体类中。
  3. ResultHandle可以实现一个字段作为key,一个字段作为value的效果,但是比较麻烦些。

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

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

相关文章

【Unity】向量应用:已知入射方向和法向量求反射方向(跳弹系统)

文章目录 已知入射方向和法向量求反射方向已知条件解题思路代码范例 已知入射方向和法向量求反射方向 已知条件 已知入射向量v1和法向量n&#xff08;OB&#xff09;&#xff0c;求反射向量v2&#xff0c;上述向量均为单位向量。 解题思路 设 AO为 v1 &#xff1b;OB为 n …

实验13 BGP路径选择

实验13 BGP路径选择 一、 原理描述二、 实验目的三、 实验内容四、 实验配置五、 实验步骤 一、 原理描述 与域内路由不同&#xff0c;域间路由更加注重策略&#xff0c;而不是技术。在域内进行选路&#xff0c;可以使用路由算法计算出到达目的子网的最短路径&#xff1b;而在…

如何完美解决 Oracle Database 19c 安装程序 - 第7步(共8步)卡住,半小时都不动

&#x1f680; 如何完美解决 Oracle Database 19c 安装程序 - 第7步&#xff08;共8步&#xff09;卡住&#xff0c;半小时都不动 摘要 在安装 Oracle Database 19c 时&#xff0c;很多用户会在第7步&#xff08;共8步&#xff09;遇到卡住的问题&#xff0c;尤其是安装程序长…

行业模板|DataEase应用平台对接大屏模板推荐

DataEase开源数据可视化分析工具于2022年6月发布模板市场&#xff08;https://templates-de.fit2cloud.com&#xff09;&#xff0c;并于2024年1月新增适用于DataEase v2版本的模板分类。模板市场旨在为DataEase用户提供专业、美观、拿来即用的大屏模板&#xff0c;方便用户根据…

Spring框架的最新进展:2023年Spring Boot和Spring Cloud功能更新

引用 Spring框架的最新动态&#xff1a;2023年Spring Boot与Spring Cloud功能升级 Spring框架作为Java开发领域的重要技术之一&#xff0c;一直致力于简化开发流程和提高开发效率。2023年&#xff0c;Spring Boot和Spring Cloud两大核心组件再次迎来功能升级&#xff0c;为开…

哪个充电宝牌子好用又实惠?盘点四大平价充电宝分享

在当今快节奏的生活中&#xff0c;充电宝已成为我们日常生活中不可或缺的一部分。然而&#xff0c;面对市场上琳琅满目的充电宝品牌和型号&#xff0c;许多消费者误以为选择容量越大、价格越高的充电宝就是最好的选择。实际上&#xff0c;买充电宝并不是一味追求高容量和高价格…

深入解析知识付费平台的核心功能模块:满足个性化学习需求的数字化教育新星

在数字化学习的大潮中&#xff0c;知识付费平台已成为教育行业的一颗新星&#xff0c;它以满足用户需求为核心&#xff0c;提供便捷高效的学习渠道。该平台汇聚了各类专业知识&#xff0c;覆盖职业技能、生活兴趣和人文社科等多个领域&#xff0c;满足不同用户的学习需求。同时…

【scrapy】爬虫,从429状态码说起

许久未爬&#xff0c;发现爬不动了&#xff0c;哈哈哈&#xff0c;记录下这次失败的爬取经历 问题描述 针对这样的一个网站&#xff1a; https://www.farfetch.cn/cn/shopping/women/dresses-1/items.aspx?page1&view96&sort3 需求&#xff1a; 1.需要爬取列表页…

TOP10!YashanDB斩获广东省优秀信创产品与解决方案双料荣誉

近日&#xff0c;2024广东软件风云榜结果出炉&#xff0c;表彰为广东软件产业和数字经济、新型工业化发展作出突出贡献的企业、企业家、优秀产品等。深算院崖山数据库系统 YashanDB荣获广东省“2024年优秀信息技术应用创新产品TOP10”和“2024年优秀信息技术应用创新行业应用解…

java 对象实际占用内存大小预估工具类ObjectSizeUtil

java 对象实际占用内存大小预估工具类 返回对象占用预估字节数 返回字节数对应格式化后的字符串&#xff08;xx Kb&#xff09; 使用效果 依赖了lombock和hutool&#xff0c;项目不用这个可以去掉日志&#xff0c;稍微改写一下。 import cn.hutool.core.util.ClassUtil; i…

docker怎么拉取全部镜像,打包所有镜像

因为docker&#xff0c;所以我把电脑上之前的镜像全部打包出来了 你们也可以打包&#xff0c;我提供一个脚本&#xff0c;你运行即可 export_docker.sh #!/bin/bash# 导出目录 EXPORT_DIR"docker_images_backup" mkdir -p "$EXPORT_DIR"# 获取所有镜像 …

PythonPoc基础编写(3)---批量刷cnvd

文章目录 前言一、发现过程二、使用步骤1.引入库2.读入数据结果 总结 前言 想刷cnvd&#xff1f;最重要的是登录进行测试功能点 一、发现过程 找到一个网站 发现登录失败返回200 登录成功则是重定向 302 那就写一个脚本吧 二、使用步骤 1.引入库 import requests 2.读入…

安装AutoCAD异常

问题&#xff1a; 安装Autodesk产品时&#xff0c;显示以下消息&#xff0c;且安装未完成。 正在等待操作系统重新启动。 请重新启动计算机以安装 AutoCAD 2024。 操作系统&#xff1a; Windows 10Windows 11 原因&#xff1a; Windows注册表项已损坏。Microsoft Visual C …

微射流均质机可用于纳米制剂和材料制备 我国市场需求空间广阔

微射流均质机可用于纳米制剂和材料制备 我国市场需求空间广阔 微射流均质机是一种纳米级乳化及分散的处理设备&#xff0c;工作原理是在加压状态下&#xff0c;高压流体经过微细孔径喷嘴后&#xff0c;形成高速微射流&#xff0c;从而产生强大的涡流和切应力&#xff0c;将颗粒…

ESP8266-01S烧录MQTT固件ERROR问题

今天在烧录ESP8266固件时遇到了这个问题&#xff0c;技术客服给了个有效的解决方案。 选择固件的时候可以先确认自己的模块是ESP8266或者EPS8285主控&#xff0c;这在选择DOWNLOADTOOL时还不一样。 然后波特率是115200&#xff0c;我在这个地方选错成1152000。 当然上面都不…

【ARM Cache 及 MMU 系列文章 1.4 -- 如何判断 L3 Cache 是否实现?】

请阅读【ARM Cache 及 MMU/MPU 系列文章专栏导读】 及【嵌入式开发学习必备专栏】 文章目录 Cluster Configuration Register代码实现什么是Single-Threaded Core?什么是PE(Processor Execution units)?Single-Threaded Core与PE的关系对比多线程(Multithreading)Cluster…

gridview自带编辑功能如何判断用户修改的值的合法性

在使用GridView的编辑功能更新值时&#xff0c;确保输入的值合法性是十分重要的。为了实现这一点&#xff0c;你可以在GridView的RowUpdating事件中加入代码来检查用户输入的值。如果发现输入的值不合法&#xff0c;你可以取消更新操作并向用户显示错误消息。下面是如何实现的步…

小区噪音监测管理系统设计

一、引言 随着城市化进程的加快&#xff0c;小区居民对于居住环境的要求日益提高。其中&#xff0c;噪音污染已成为影响居民生活质量的重要因素。因此&#xff0c;设计一套小区噪音监测管理系统&#xff0c;对于提升居民的生活品质和小区管理效率具有重要意义。本文将详细阐述…

数据资产驱动的智能化决策:深度剖析数据资产在提升企业决策效率与准确性中的关键作用

在数字化、信息化日益普及的今天&#xff0c;数据已经成为企业发展的重要资产。数据资产不仅能够帮助企业更好地了解市场需求、优化业务流程&#xff0c;还能在决策过程中提供科学、精准的支持。本文将深入剖析数据资产在提升企业决策效率与准确性中的关键作用&#xff0c;探讨…

电脑文件防泄密软件——天锐绿盾 - 中科数安—— 哪个好

在选择电脑文件防泄密软件时&#xff0c;天锐绿盾和中科数安都是值得考虑的选项。以下是对这两款软件的详细比较&#xff1a; www.drhchina.com PC地址&#xff1a; https://isite.baidu.com/site/wjz012xr/2eae091d-1b97-4276-90bc-6757c5dfedee 功能全面性&#xff1a; 天锐…