08 MyBatis之查询专题(返回对象/Map/List封装Map/Map封装Map)+列名与属性名映射的三种方法

准备:

sql 复制代码
INSERT INTO `t_car` (`id`, `car_num`, `brand`, `guide_price`, `produce_time`, `car_type`) VALUES (165, '6666', '丰田霸道', 32.00, '2020-11-11', '燃油车');
INSERT INTO `t_car` (`id`, `car_num`, `brand`, `guide_price`, `produce_time`, `car_type`) VALUES (166, '1202', '大众速腾', 30.00, '2020-11-11', '燃油车');
INSERT INTO `t_car` (`id`, `car_num`, `brand`, `guide_price`, `produce_time`, `car_type`) VALUES (167, '1203', '奔驰GLC', 5.00, '2010-12-03', '燃油车');
INSERT INTO `t_car` (`id`, `car_num`, `brand`, `guide_price`, `produce_time`, `car_type`) VALUES (168, '1204', '奥迪Q7', 3.00, '2009-10-11', '燃油车');
INSERT INTO `t_car` (`id`, `car_num`, `brand`, `guide_price`, `produce_time`, `car_type`) VALUES (169, '1205', '朗逸', 4.00, '2001-10-11', '新能源');
INSERT INTO `t_car` (`id`, `car_num`, `brand`, `guide_price`, `produce_time`, `car_type`) VALUES (171, '1207', '奥迪A6', 30.00, '2000-01-02', '燃油车');
INSERT INTO `t_car` (`id`, `car_num`, `brand`, `guide_price`, `produce_time`, `car_type`) VALUES (172, '6666', '丰田霸道', 32.00, '2020-11-11', '燃油车');

1. 返回一个对象

需求 : 查询的结果,有对应的实体类,并且查询结果只有一条

1.1 用对象接收返回值

java 复制代码
package com.sunsplanter.mybatis.mapper;

public interface CarMapper {
    Car selectById(Long id);
}
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.sunsplanter.mybatis.mapper.CarMapper">
    <select id="selectById" resultType="Car">
        select id,car_num carNum,brand,guide_price guidePrice,produce_time produceTime,car_type carType from t_car where id = #{id}
    </select>
</mapper>
java 复制代码
package com.sunsplanter.mybatis.test;

public class CarMapperTest {

    @Test
    public void testSelectById(){
        CarMapper mapper = SqlSessionUtil.openSession().getMapper(CarMapper.class);
        Car car = mapper.selectById(35L);
        System.out.println(car);
    }
}

1.2 用list接收返回值

即使返回结果只有一条(一个对象), 仍能用list接收, 但是在将来输出的时候有些不同

java 复制代码
//mapper接口新增方法
List<Car> selectByIdToList(Long id);
xml 复制代码
<select id="selectByIdToList" resultType="Car">
  select id,car_num carNum,brand,guide_price guidePrice,produce_time produceTime,car_type carType from t_car where id = #{id}
</select>
java 复制代码
@Test
public void testSelectByIdToList(){
    CarMapper mapper = SqlSessionUtil.openSession().getMapper(CarMapper.class);
    List<Car> cars = mapper.selectByIdToList(35L);
    System.out.println(cars);
}

可以看到 , 返回的对象用方括号扩了起来

2. 返回多个对象

返回多个对象只能用list接收.

java 复制代码
List<Car> selectAll();
xml 复制代码
<select id="selectAll" resultType="Car">
  select id,car_num carNum,brand,guide_price guidePrice,produce_time produceTime,car_type carType from t_car
</select>
java 复制代码
@Test
public void testSelectAll(){
    CarMapper mapper = SqlSessionUtil.openSession().getMapper(CarMapper.class);
    List<Car> cars = mapper.selectAll();
    cars.forEach(car -> System.out.println(car));
}

3. 返回一个map

当返回的数据,没有合适的实体类对应的话,可以采用Map集合接收。字段名做key,字段值做value。

且如果可以保证只有一条数据,则返回一个Map集合即可。

java 复制代码
Map<String, Object> selectByIdRetMap(Long id);
xml 复制代码
<!--此处的resultType指定为map-->
<select id="selectByIdRetMap" resultType="map">
  select id,car_num carNum,brand,guide_price guidePrice,produce_time produceTime,car_type carType from t_car where id = #{id}
</select>
java 复制代码
@Test
public void testSelectByIdRetMap(){
    CarMapper mapper = SqlSessionUtil.openSession().getMapper(CarMapper.class);
    Map<String,Object> car = mapper.selectByIdRetMap(35L);
    System.out.println(car);
}

可以看到 , 输出的结果和用实体接收并输出是一样的.

4. 返回多个map

需求: 返回多条数据, 且都没有对应的实体接收

4.1 第一种做法List

分析: 将每条数据存入一个map, 将所有map一起存入list

java 复制代码
List<Map<String,Object>> selectAllRetListMap();
xml 复制代码
<select id="selectAllRetListMap" resultType="map">
  select id,car_num carNum,brand,guide_price guidePrice,produce_time produceTime,car_type carType from t_car
</select>
java 复制代码
@Test
public void testSelectAllRetListMap(){
    CarMapper mapper = SqlSessionUtil.openSession().getMapper(CarMapper.class);
    List<Map<String,Object>> cars = mapper.selectAllRetListMap();
    System.out.println(cars);
}

执行结果

//方括号包裹
[
  {carType=燃油车, carNum=103, guidePrice=50.30, produceTime=2020-10-01, id=33, brand=奔驰E300L}, 
  {carType=电车, carNum=102, guidePrice=30.23, produceTime=2018-09-10, id=34, brand=比亚迪汉}, 
  {carType=燃油车, carNum=103, guidePrice=50.30, produceTime=2020-10-01, id=35, brand=奔驰E300L}, 
  {carType=燃油车, carNum=103, guidePrice=33.23, produceTime=2020-10-11, id=36, brand=奔驰C200},
  ......
]

4.2 第二种做法Map<String,Map>

分析:

大Map的键: 每条数据的id

大Map的值: 每条数据存入小Map

优势: 拿数据的id作为key, 将来可以比list更方便取出指定某条数据

java 复制代码
//@MapKey注解指定, selectAllRetMap方法返回的map中,将id字段的值作为外层大Map的键
@MapKey("id")
Map<Long,Map<String,Object>> selectAllRetMap();
xml 复制代码
<select id="selectAllByMapUnderscoreToCamelCase" resultType="map">
  select * from t_car
</select>
java 复制代码
@Test
public void testSelectAllByMapUnderscoreToCamelCase(){
    CarMapper carMapper = SqlSessionUtil.openSession().getMapper(CarMapper.class);
    Map<Long, Map<String,object>> cars = carMapper.selectAllByMapUnderscoreToCamelCase();
    System.out.println(cars);
}

5. 列名与属性名映射的三种方法

按照开发规范, 大多数时候数据库的列名与实体字段属性名并不相同, 此时需要考虑怎么让系统正确绑定二者

● 第一种方式:as 给列起别名

● 第二种方式:使用resultMap进行结果映射

● 第三种方式:开启驼峰命名自动映射(配置settings)

5.1 as 给列起别名

这种方式虽然非常直观, 但是字段多起来后代码会复杂

xml 复制代码
<!--列名在前, 实体属性在后-->
<select id="listAllCars" resultType="car">
select 
	id,
	car_num as carNum
	from t_car
</select>

5. 使用resultMap进行结果映射

xml 复制代码
<!--
        resultMap:
            id:这个结果映射的标识,作为select标签的resultMap属性的值。
            type:结果集要映射的类。可以使用别名。
-->
<resultMap id="carResultMap" type="car">
  <!--对象的唯一标识,官方解释是:为了提高mybatis的性能。建议写上。-->
  <id property="id" column="id"/>
  <result property="carNum" column="car_num"/>
  <!--当属性名和数据库列名一致时,可以省略。但建议都写上。-->
  <!--javaType用来指定属性类型。jdbcType用来指定列类型。一般可以省略。-->
  <result property="brand" column="brand" javaType="string" jdbcType="VARCHAR"/>
  <result property="guidePrice" column="guide_price"/>
  <result property="produceTime" column="produce_time"/>
  <result property="carType" column="car_type"/>
</resultMap>

<!--resultMap属性的值必须和resultMap标签中id属性值一致。-->
<select id="selectAllByResultMap" resultMap="carResultMap">
  select * from t_car
</select>

5.3 自动驼峰映射

首先, 开启自动驼峰映射必须满足条件, 即

属性名遵循Java的命名规范,数据库表的列名遵循SQL的命名规范。

xml 复制代码
<!--放在properties标签后面-->
<settings>
  <setting name="mapUnderscoreToCamelCase" value="true"/>
  <setting name="autoMappingBehavior" value="FULL"/>
</settings>
相关推荐
莳光.13 分钟前
122、java的LambdaQueryWapper的条件拼接实现数据sql中and (column1 =1 or column1 is null)
java·mybatis
qq_441996054 小时前
Mybatis官方生成器使用示例
java·mybatis
꧁惜若༒奔已꧂21 小时前
spring使用xml文件整合事务+druid+mybatis
xml·spring·mybatis
小桥流水人家jjh1 天前
Mybatis执行自定义SQL并使用PageHelper进行分页
java·数据库·spring boot·sql·mybatis
黑马师兄1 天前
Mybatis
java·mybatis
Neoest2 天前
场景解决之mybatis当中resultType= map时,因某个字段为null导致返回的map的key不存在怎么处理
mybatis
ZWZhangYu2 天前
【MyBatis源码】深入分析TypeHandler原理和源码
数据库·oracle·mybatis
小鸡脚来咯3 天前
springboot 整合mybatis
java·spring boot·mybatis
种树人202408193 天前
MyBatis xml 文件中 SQL 语句的小于号未转义导致报错
mybatis
码农派大星。3 天前
MyBatis操作--进阶
mybatis