十一、MyBatis查询语句专题
模块名:mybatis-007-select
打包方式:jar
引入依赖:mysql
驱动依赖、mybatis
依赖、logback
依赖、junit
依赖。
引入配置文件:jdbc.properties
、mybatis-config.xml
、logback.xml
创建pojo类:Car
创建Mapper接口:CarMapper
创建Mapper接口对应的映射文件:com/study/mybatis/mapper/CarMapper.xml
创建单元测试:CarMapperTest
拷贝工具类:SqlSessionUtil
11.1 返回Car
当查询的结果,有对应的实体类,并且查询结果只有一条时:
package com.study.mybatis.mapper;
import com.study.mybatis.pojo.Car;
/**
* Car SQL映射器
* @author sqnugy
* @version 1.0
* @since 1.0
*/
public interface CarMapper {
/**
* 根据id主键查询:结果最多只有一条
* @param id
* @return
*/
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.study.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.study.mybatis.test;
import com.study.mybatis.mapper.CarMapper;
import com.study.mybatis.pojo.Car;
import com.study.mybatis.utils.SqlSessionUtil;
import org.junit.Test;
public class CarMapperTest {
@Test
public void testSelectById(){
CarMapper mapper = SqlSessionUtil.openSession().getMapper(CarMapper.class);
Car car = mapper.selectById(35L);
System.out.println(car);
}
}
执行结果:
查询结果是一条的话可以使用List集合接收吗?当然可以。
/**
* 根据id主键查询:结果最多只有一条,可以放到List集合中吗?
* @return
*/
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);
}
执行结果:
11.2 返回List<Car>
当查询的记录条数是多条的时候,必须使用集合接收。如果使用单个实体类接收会出现异常。
/**
* 查询所有的Car
* @return
*/
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));
}
如果返回多条记录,采用单个实体类接收会怎样?
/**
* 查询多条记录,采用单个实体类接收会怎样?
* @return
*/
Car selectAll2();
<select id="selectAll2" resultType="Car">
select id,car_num carNum,brand,guide_price guidePrice,produce_time produceTime,car_type carType from t_car
</select>
@Test
public void testSelectAll2(){
CarMapper mapper = SqlSessionUtil.openSession().getMapper(CarMapper.class);
Car car = mapper.selectAll2();
System.out.println(car);
}
执行结果:
11.3 返回Map
当返回的数据,没有合适的实体类对应的话,可以采用Map集合接收。字段名做key
,字段值做value
。
查询如果可以保证只有一条数据,则返回一个Map集合即可。
/**
* 通过id查询一条记录,返回Map集合
* @param id
* @return
*/
Map<String, Object> selectByIdRetMap(Long id);
<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>
resultMap=“map”,这是因为mybatis内置了很多别名。【参见mybatis开发手册】
@Test
public void testSelectByIdRetMap(){
CarMapper mapper = SqlSessionUtil.openSession().getMapper(CarMapper.class);
Map<String,Object> car = mapper.selectByIdRetMap(35L);
System.out.println(car);
}
执行结果:
当然,如果返回一个Map集合,可以将Map集合放到List集合中吗?当然可以,这里就不再测试了。
反过来,如果返回的不是一条记录,是多条记录的话,只采用单个Map集合接收,这样同样会出现之前的异常:TooManyResultsException
11.4 返回List<Map>
查询结果条数大于等于1条数据,则可以返回一个存储Map集合的List集合。List<Map>
等同于List<Car>
/**
* 查询所有的Car,返回一个List集合。List集合中存储的是Map集合。
* @return
*/
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},
......
]
11.5 返回Map<String,Map>
拿Car
的id
做key
,以后取出对应的Map集合时更方便。
/**
* 获取所有的Car,返回一个Map集合。
* Map集合的key是Car的id。
* Map集合的value是对应Car。
* @return
*/
@MapKey("id")
Map<Long,Map<String,Object>> selectAllRetMap();
<select id="selectAllRetMap" resultType="map">
select id,car_num carNum,brand,guide_price guidePrice,produce_time produceTime,car_type carType from t_car
</select>
@Test
public void testSelectAllRetMap(){
CarMapper mapper = SqlSessionUtil.openSession().getMapper(CarMapper.class);
Map<Long,Map<String,Object>> cars = mapper.selectAllRetMap();
System.out.println(cars);
}
执行结果:
{
64={carType=燃油车, carNum=133, guidePrice=50.30, produceTime=2020-01-10, id=64, brand=丰田霸道},
66={carType=燃油车, carNum=133, guidePrice=50.30, produceTime=2020-01-10, id=66, brand=丰田霸道},
67={carType=燃油车, carNum=133, guidePrice=50.30, produceTime=2020-01-10, id=67, brand=丰田霸道},
69={carType=燃油车, carNum=133, guidePrice=50.30, produceTime=2020-01-10, id=69, brand=丰田霸道},
......
}
11.6 resultMap结果映射
查询结果的列名和java对象的属性名对应不上怎么办?
- 第一种方式:as 给列起别名
- 第二种方式:使用
resultMap
进行结果映射 - 第三种方式:是否开启驼峰命名自动映射(配置settings)
第二种方式:使用resultMap进行结果映射
/**
* 查询所有Car,使用resultMap进行结果映射
* @return
*/
List<Car> selectAllByResultMap();
<!--
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>
@Test
public void testSelectAllByResultMap(){
CarMapper carMapper = SqlSessionUtil.openSession().getMapper(CarMapper.class);
List<Car> cars = carMapper.selectAllByResultMap();
System.out.println(cars);
}
执行结果正常。
第三种方式:驼峰命名自动映射
使用这种方式的前提是:属性名遵循Java的命名规范,数据库表的列名遵循SQL的命名规范。
Java命名规范:首字母小写,后面每个单词首字母大写,遵循驼峰命名方式。
SQL命名规范:全部小写,单词之间采用下划线分割。
比如以下的对应关系:
实体类中的属性名 | 数据库表的列名 |
---|---|
carNum | car_num |
carType | car_type |
produceTime | produce_time |
如何启用该功能,在mybatis-config.xml
文件中进行配置:
<!--放在properties标签后面-->
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
/**
* 查询所有Car,启用驼峰命名自动映射
* @return
*/
List<Car> selectAllByMapUnderscoreToCamelCase();
<select id="selectAllByMapUnderscoreToCamelCase" resultType="Car">
select * from t_car
</select>
@Test
public void testSelectAllByMapUnderscoreToCamelCase(){
CarMapper carMapper = SqlSessionUtil.openSession().getMapper(CarMapper.class);
List<Car> cars = carMapper.selectAllByMapUnderscoreToCamelCase();
System.out.println(cars);
}
执行结果正常。
11.7 返回总记录条数
需求:查询总记录条数
/**
* 获取总记录条数
* @return
*/
Long selectTotal();
<!--long是别名,可参考mybatis开发手册。-->
<select id="selectTotal" resultType="long">
select count(*) from t_car
</select>
@Test
public void testSelectTotal(){
CarMapper carMapper = SqlSessionUtil.openSession().getMapper(CarMapper.class);
Long total = carMapper.selectTotal();
System.out.println(total);
}
标签:语句,Map,专题,car,List,Car,MyBatis,CarMapper,id
From: https://blog.csdn.net/wgy17734894660/article/details/143511428