Mybatis返回Map對象的實(shí)現(xiàn)
一、場景介紹
假設(shè)有如下一張學(xué)生表:
CREATE TABLE `student` ( `id` int NOT NULL AUTO_INCREMENT COMMENT '主鍵', `name` varchar(100) NOT NULL COMMENT '姓名', `gender` varchar(10) NOT NULL COMMENT '性別', `grade` int NOT NULL COMMENT '年級', PRIMARY KEY (`id`) ) ENGINE=InnoDB COMMENT='學(xué)生信息表';
我們通過一組 ids,想獲得 id 跟學(xué)生對象的映射 Map<Integer, Student>,可以這樣做:
1、先通過 ids 獲取對象列表
2、再通過 stream 流式運(yùn)算得到 id-Student 映射
這樣做雖然也沒有問題,但是這樣 service 層就會散落一堆這樣流式運(yùn)算的代碼。不是很美觀,應(yīng)該在DAO層就提供這種能力。Mybatis 提供給我們查詢 Map 的方式。
@Service public class StudentServiceImpl implements StudentService { @Autowired private StudentMapper mapper; @Override public Map<Integer, Student> findMapByIds(List<Integer> ids) { List<Student> students = mapper.listByIds(ids); Map<Integer, Student> map = students.stream().collect(Collectors.toMap(Student::getId, Function.identity())); return map; } } --------------------------------------------------------------- @Test public void test() { List<Integer> list = Arrays.asList(1,2,3); Map<Integer, Student> map = studentService.findMapByIds(list); System.out.println(map); } 輸出: {1=Student(id=1, name=小明, gender=male, grade=1), 2=Student(id=2, name=小紅, gender=female, grade=2), 3=Student(id=3, name=小李, gender=male, grade=3)}
二、Mybatis @MapKey 方式
Mybatis 提供了 @MapKey 注解,注解的 value 用來指定 key 的取值字段。
可以看到,效果是一樣的。
@Mapper public interface StudentMapper { /** * 這種基礎(chǔ)的查詢,不應(yīng)該先獲取 List 流,然后再轉(zhuǎn)換, * 這樣會使整個項(xiàng)目散落一地這種代碼 * 應(yīng)該在DAO層就提供這種能力 */ @MapKey("id") Map<Integer, Student> findMapByIds(List<Integer> ids); } ------------------------------------------------------------- <?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.study.student.mapper.StudentMapper"> <select id="findMapByIds" resultType="com.study.student.entity.Student"> select * from student s <where> and s.id in <foreach collection="ids" item="id" open="(" separator="," close=")"> #{id} </foreach> </where> </select> </mapper> ------------------------------------------------------------- @Service public class StudentServiceImpl implements StudentService { @Autowired private StudentMapper mapper; @Override public Map<Integer, Student> findMapByIds(List<Integer> ids) { /* List<Student> students = mapper.listByIds(ids); Map<Integer, Student> map = students.stream().collect(Collectors.toMap(Student::getId, Function.identity())); return map; */ return mapper.findMapByIds(ids); } } ------------------------------------------------------------- @Test public void test() { List<Integer> list = Arrays.asList(1,2,3); Map<Integer, Student> map = studentService.findMapByIds(list); System.out.println(map); } 輸出: {1=Student(id=1, name=小明, gender=male, grade=1), 2=Student(id=2, name=小紅, gender=female, grade=2), 3=Student(id=3, name=小李, gender=male, grade=3)}
但如果 @MapKey 的 value 配置了記錄重復(fù)的字段會怎么樣?
就比如,@MapKey("grade"),grade = 1,2,3 的記錄并非唯一。
@Mapper public interface StudentMapper { List<Student> listByIds(List<Integer> ids); /** * @MapKey 的 value 是 grade 這種非唯一字段 */ @MapKey("grade") Map<Integer, Student> findMapByIds(List<Integer> ids); }
這個時候會發(fā)現(xiàn),返回的記錄被覆蓋了。
id in [1,6] 的 grade=1 的記錄有 小明跟小智,
小明先查詢出來,
map.put(1, Student(id=1, name=小明, gender=male, grade=1))
小智后查詢出來,
map.put(1, Student(id=6, name=小智, gender=male, grade=1))
同一個key,小智覆蓋了小明。
那如果我們希望返回 Map<grade:Integer, List<Student>> 怎么辦呢?
@Test public void test2() { List<Integer> list = Arrays.asList(1,2,3,4,5,6); Map<Integer, Student> map = studentService.findMapByIds(list); System.out.println(map); } 輸出: {1=Student(id=6, name=小智, gender=male, grade=1), 2=Student(id=4, name=小林, gender=male, grade=2), 3=Student(id=5, name=小婷, gender=female, grade=3)}
三、Stream 返回 Map<Integer, List<Student>>
遺憾的是,筆者找了 Mybatis 跟 MybatisPlus 也沒找到此類方法,所以這一塊,還是只能用流式計(jì)算來做。
@Mapper public interface StudentMapper { List<Student> listByIds(List<Integer> ids); } ------------------------------------------------------------- <?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.study.student.mapper.StudentMapper"> <select id="listByIds" resultType="cn.al.admin.entity.finance.Student"> select * from student s <where> and s.id in <foreach collection="ids" item="id" open="(" separator="," close=")"> #{id} </foreach> </where> </select> </mapper> ------------------------------------------------------------- @Service public class StudentServiceImpl implements StudentService { @Autowired private StudentMapper mapper; @Override public Map<Integer, List<Student>> getMapByIds(List<Integer> ids) { List<Student> students = mapper.listByIds(ids); return students.stream().collect(Collectors.groupingBy(Student::getGrade)); } } ------------------------------------------------------------- @Test public void test3() { List<Integer> list = Arrays.asList(1,2,3,4,5,6); Map<Integer, List<Student>> map = studentService.getMapByIds(list); System.out.println(map); } 輸出: {1=[Student(id=1, name=小明, gender=male, grade=1), Student(id=6, name=小智, gender=male, grade=1)], 2=[Student(id=2, name=小紅, gender=female, grade=2), Student(id=4, name=小林, gender=male, grade=2)], 3=[Student(id=3, name=小李, gender=male, grade=3), Student(id=5, name=小婷, gender=female, grade=3)]}
四、MybatisPlus 返回 List<Map<String, Object>>
如果希望查詢返回 List<Map<String, Object>> Map 的 key 是數(shù)據(jù)庫 column name
package com.study.student.mapper; import com.study.student.entity.Student; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.*; @Mapper public interface StudentMapper extends BaseMapper<Student> { } ------------------------------------------------------------ package com.study.student.service.impl; import com.study.student.entity.Student; import com.study.student.mapper.StudentMapper; import com.study.student.service.StudentService; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.stereotype.Service; import java.util.List; import java.util.Map; @Service public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student> implements StudentService { @Override public List<Map<String, Object>> getMapList(List<Integer> ids) { LambdaQueryWrapper<Student> wrapper = new LambdaQueryWrapper<>(); wrapper.in(Student::getId, ids); return this.getBaseMapper().selectMaps(wrapper); } } ------------------------------------------------------------ @Test public void test4() { List<Integer> list = Arrays.asList(1,2,3,4,5,6); List<Map<String, Object>> map = studentService.getMapList(list); System.out.println(map); } 輸出: [{gender=male, grade=1, name=小明, id=1, photo_url=url1}, {gender=female, grade=2, name=小紅, id=2, photo_url=url2}, {gender=male, grade=3, name=小李, id=3, photo_url=url3}, {gender=male, grade=2, name=小林, id=4, photo_url=url4}, {gender=female, grade=3, name=小婷, id=5, photo_url=url5}, {gender=male, grade=1, name=小智, id=6, photo_url=url6}]
五、JSON 返回 List<Map<String, Object>>
如果希望查詢返回 List<Map<String, Object>> Map 的 key 是對象 property。需要借助 JSON 工具類,比如 cn.hutool.core.bean.BeanUtil#beanToMap
package com.study.student.service.impl; import com.study.student.entity.Student; import com.study.student.mapper.StudentMapper; import com.study.student.service.StudentService; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.stereotype.Service; import cn.hutool.core.bean.BeanUtil; import java.util.List; import java.util.Map; @Service public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student> implements StudentService { @Override public List<Map<String, Object>> getMapList(List<Integer> ids) { List<Student> students = this.listByIds(ids); return students.stream().map(BeanUtil::beanToMap).collect(Collectors.toList()); } } ------------------------------------------------------------ @Test public void test5() { List<Integer> list = Arrays.asList(1,2,3,4,5,6); List<Map<String, Object>> map = studentService.getMapList(list); System.out.println(map); } 輸出: [{id=1, name=小明, gender=male, grade=1, photoUrl=url1}, {id=2, name=小紅, gender=female, grade=2, photoUrl=url2}, {id=3, name=小李, gender=male, grade=3, photoUrl=url3}, {id=4, name=小林, gender=male, grade=2, photoUrl=url4}, {id=5, name=小婷, gender=female, grade=3, photoUrl=url5}, {id=6, name=小智, gender=male, grade=1, photoUrl=url6}]
六、MybatisPlus 返回 Map<String, Object>
Map 的 key 是數(shù)據(jù)庫 column name
package com.study.student.service.impl; import com.study.student.entity.Student; import com.study.student.mapper.StudentMapper; import com.study.student.service.StudentService; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.stereotype.Service; import java.util.List; import java.util.Map; @Service public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student> implements StudentService { @Override public Map<String, Object> getMapById(Integer id) { LambdaQueryWrapper<Student> wrapper = new LambdaQueryWrapper<>(); wrapper.eq(Student::getId, id); return this.getMap(wrapper); } } ------------------------------------------------------------ @Test public void test6() { Map<String, Object> map = studentService.getMapById(6); System.out.println(map); } 輸出: {gender=male, grade=1, name=小智, id=6, photo_url=url6}
七、JSON 返回 Map<String, Object>
Map 的 key 是對象 property
package com.study.student.service.impl; import com.study.student.entity.Student; import com.study.student.mapper.StudentMapper; import com.study.student.service.StudentService; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.stereotype.Service; import cn.hutool.core.bean.BeanUtil; import java.util.List; import java.util.Map; @Service public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student> implements StudentService { @Override public Map<String, Object> getMapById(Integer id) { Student student = this.getById(id); return BeanUtil.beanToMap(student); } } ------------------------------------------------------------ @Test public void test7() { Map<String, Object> map = studentService.getMapById(6); System.out.println(map); } 輸出: {id=6, name=小智, gender=male, grade=1, photoUrl=url6}
到此這篇關(guān)于Mybatis返回Map對象的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Mybatis返回Map對象內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
spring如何實(shí)現(xiàn)兩個xml配置文件間的互調(diào)
這篇文章主要介紹了spring如何實(shí)現(xiàn)兩個xml配置文件間的互調(diào),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-11-11springboot在filter中如何用threadlocal存放用戶身份信息
這篇文章主要介紹了springboot中在filter中如何用threadlocal存放用戶身份信息,本文章主要描述通過springboot的filter類,在過濾器中設(shè)置jwt信息進(jìn)行身份信息保存的方法,需要的朋友可以參考下2024-07-07SpringBoot統(tǒng)一功能處理實(shí)現(xiàn)的全過程
最近在做項(xiàng)目時需要對異常進(jìn)行全局統(tǒng)一處理,主要是一些分類入庫以及記錄日志等,下面這篇文章主要給大家介紹了關(guān)于SpringBoot統(tǒng)一功能處理實(shí)現(xiàn)的相關(guān)資料,文中通過圖文以及實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-01-01SpringBoot項(xiàng)目POM文件的使用小結(jié)
本文主要詳細(xì)介紹了Maven中SpringBoot項(xiàng)目的POM文件配置,包括項(xiàng)目的依賴和插件,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-11-11