springboot整合mybatis返回map的3个注意点
参考网址:
https://blog.csdn.net/super_DuoLa/article/details/109646158?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522161413563716780255235187%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=161413563716780255235187&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_v2~rank_v29-1-109646158.first_rank_v2_pc_rank_v29&utm_term=springboot%E6%95%B4%E5%90%88mybatis%E8%BF%94%E5%9B%9Emap%E4%B8%BAnull
提出问题
说明:
之前在写项目时,使用mybatis返回类型为map遇到的问题,现在整理一下
3个问题
- map中value为null返回不显示此k-v
- map返回值不安顺寻
- 返回字段区别名
1.准备工作
- 新建springboot+mybatis简单的工程
- pojo类
package com.shaoming.model.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class Emp {
/** | int(11) | NO | PRI | NULL | auto_increment |*/
private Integer id;
/** | varchar(50) | YES | | NULL | |*/
private String name;
/** | varchar(50) | YES | | NULL | |*/
private String job;
/** | double | NO | | NULL | |*/
private Double salary;
}
- 建库脚本
-- ----------------------------
-- Table structure for emp
-- ----------------------------
DROP TABLE IF EXISTS `emp`;
CREATE TABLE `emp` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`job` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`salary` double NOT NULL,
PRIMARY KEY (`id`) USING BTREE
) ;
INSERT INTO `emp` VALUES (1, 'name', 'job', 2000);
INSERT INTO `emp` VALUES (2, 'name', 'job', 2000);
INSERT INTO `emp` VALUES (3, 'name', NULL, 20000);
INSERT INTO `emp` VALUES (4, NULL, NULL, 2000);
数据库数据
+----+------+------+--------+
| id | name | job | salary |
+----+------+------+--------+
| 1 | name | job | 2000 |
| 2 | name | job | 2000 |
| 3 | name | NULL | 20000 |
| 4 | NULL | NULL | 2000 |
+----+------+------+--------+
- mapper接口和xml
EmpMapper
@Mapper
public interface EmpMapper {
/**
* 返回类型使用map去接受
* @return
*/
List<HashMap<String,Object>> selectListByMap();
}
EmpMapper.xml
<?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.shaoming.mapper.EmpMapper">
<select id="selectListByMap" resultType="java.util.HashMap">
select id,name,job,salary from emp
</select>
</mapper>
2.编写测试类测试
package com.shaoming;
import com.shaoming.mapper.EmpMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class DaoTest2 {
@Autowired
private EmpMapper empMapper;
@Test
public void test1(){
empMapper.selectListByMap().forEach(System.out::println);
}
}
控制台输出
{name=name, id=1, job=job, salary=2000.0}
{name=name, id=2, job=job, salary=2000.0}
{name=name, id=3, salary=20000.0}
{id=4, salary=2000.0}
出现的问题
1.如果数据库字段的值为null,那么会不显示查询结果
2.查询的数据没有顺序
3.需要给数据库字段起别名
3.推荐的写法
修改后的mapper接口
@Mapper
public interface EmpMapper {
/**
* 返回类型使用map去接受
* @return
*/
List<LinkedHashMap<String,Object>> selectListByMap();
}
修改后的mapper.xml
<?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.shaoming.mapper.EmpMapper">
<select id="selectListByMap" resultType="java.util.LinkedHashMap">
select id,name,job,salary as sal from emp
</select>
</mapper>
修改springboot配置(重要)
当返回值为map类型,数据库字段的值为空时,显示该字段
在application.properties中进行配置(mybatis同理)
mybatis-plus.configuration.call-setters-on-nulls=true
测试控制台打印
{id=1, name=name, job=job, sal=2000.0}
{id=2, name=name, job=job, sal=2000.0}
{id=3, name=name, job=null, sal=20000.0}
{id=4, name=null, job=null, sal=2000.0}
4.总结(很重要)
以上都是特殊情况的做法,一般我们都是用实体类接受查询的返回结果
因为阿里规范有说明
强制】不允许直接拿 HashMap 与 Hashtable 作为查询结果集的输出。
说明: resultClass=”Hashtable”, 会置入字段名和属性值,但是值的类型不可控。
Hashtable 类型极为难易控制,要检测类型,又要判空,增加代码量,是在不必要。