准备:
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 用对象接收返回值
package com.sunsplanter.mybatis.mapper;
public interface CarMapper {
Car selectById(Long id);
}
<?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>
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接收, 但是在将来输出的时候有些不同
//mapper接口新增方法
List<Car> selectByIdToList(Long id);
<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>
@Test
public void testSelectByIdToList(){
CarMapper mapper = SqlSessionUtil.openSession().getMapper(CarMapper.class);
List<Car> cars = mapper.selectByIdToList(35L);
System.out.println(cars);
}
可以看到 , 返回的对象用方括号扩了起来
2. 返回多个对象
返回多个对象只能用list接收.
List<Car> selectAll();
<select id="selectAll" resultType="Car">
select id,car_num carNum,brand,guide_price guidePrice,produce_time produceTime,car_type carType from t_car
</select>
@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集合即可。
Map<String, Object> selectByIdRetMap(Long id);
<!--此处的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>
@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
List<Map<String,Object>> selectAllRetListMap();
<select id="selectAllRetListMap" resultType="map">
select id,car_num carNum,brand,guide_price guidePrice,produce_time produceTime,car_type carType from t_car
</select>
@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更方便取出指定某条数据
//@MapKey注解指定, selectAllRetMap方法返回的map中,将id字段的值作为外层大Map的键
@MapKey("id")
Map<Long,Map<String,Object>> selectAllRetMap();
<select id="selectAllByMapUnderscoreToCamelCase" resultType="map">
select * from t_car
</select>
@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 给列起别名
这种方式虽然非常直观, 但是字段多起来后代码会复杂
<!--列名在前, 实体属性在后-->
<select id="listAllCars" resultType="car">
select
id,
car_num as carNum
from t_car
</select>
5. 使用resultMap进行结果映射
<!--
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的命名规范。
<!--放在properties标签后面-->
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
<setting name="autoMappingBehavior" value="FULL"/>
</settings>