1.环境搭建:
- 1.模块名:
mybatis-007-select
- 2.打包⽅式:
jar
- 3.引⼊依赖:
mysql驱动依赖、mybatis依赖、logback依赖、junit依赖
。 - 4.引⼊配置⽂件:
jdbc.properties、mybatis-config.xml、logback.xml
- 5.创建pojo类:
Car
- 6.创建Mapper接⼝:
CarMapper
- 7.创建Mapper接⼝对应的映射⽂件:
com/powernode/mybatis/mapper/CarMapper.xml
- 8.创建单元测试:
CarMapperTest
- 9.拷⻉⼯具类:
SqlSessionUtil
2.返回Car:
2.1.当查询的结果,有对应的实体类,并且查询结果只有⼀条时
- 1.定义接口:
CarMapper.selectById
public interface CarMapper {
/**
* 根据id主键查询:结果最多只有⼀条
* @param id
* @return
*/
Car selectById(Long id);
}
- 2.映射sql:
CarMapper.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.powernode.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>
- 3.测试类:
CarMapperTest.testSelectById
public class CarMapperTest {
@Test
public void testSelectById(){
CarMapper mapper = SqlSessionUtil.openSession().getMapper(CarMapper.class);
Car car = mapper.selectById(35L);
System.out.println(car);
}
}
-
4.查询结果:
-
5.更改SQL测试以List接收结果:
/**
* 根据id主键查询:结果最多只有⼀条,可以放到List集合中吗?
* @return
*/
List<Car> selectByIdToList(Long id);
- 6.
CarMapper.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>
- 7.
CarMapperTest.testSelectByIdToList.java
@Test
public void testSelectByIdToList(){
CarMapper mapper = SqlSessionUtil.openSession().getMapper(CarMapper.class);
List<Car> cars = mapper.selectByIdToList(35L);
System.out.println(cars);
}
- 8.当
查询结果是⼀条的话可以使⽤List集合接收也可以
:
3. 返回List:
- 1.当
查询的记录条数是多条的时候,必须使⽤集合接收
。如果使⽤单个实体类接收会出现异常。
3.1.编码测试:
- 1.
CarMapper.selectAll
/**
* 查询所有的Car
* @return
*/
List<Car> selectAll();
- 2.
CarMapper.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>
- 3.
CarMapperTest.testSelectAll
@Test
public void testSelectAll(){
CarMapper mapper = SqlSessionUtil.openSession().getMapper(CarMapper.class);
List<Car> cars = mapper.selectAll();
cars.forEach(car -> System.out.println(car));
}
4.返回Map:
4.1.返回Map说明:
- 1.当返回的数据,没有合适的实体类对应的话,可以采⽤Map集合接收。字段名做key,字段值做value
- 2.查询
如果可以保证只有⼀条数据,则返回⼀个Map集合即可
:
4.2.编码测试:
- 1.
CarMapper.selectByIdRetMap
/**
* 通过id查询⼀条记录,返回Map集合
* @param id
* @return
*/
Map<String, Object> selectByIdRetMap(Long id);
- 2.
CarMapper.xml
:rresultType=“map”,这是因为mybatis内置了很多别名。【参⻅mybatis开发⼿册】
<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>
- 3.测试:
@Test
public void testSelectByIdRetMap(){
CarMapper mapper = SqlSessionUtil.openSession().getMapper(CarMapper.class);
Map<String,Object> car = mapper.selectByIdRetMap(35L);
System.out.println(car);
}
4.3.注意事项:
- 1.如果返回⼀个Map集合,也可以将Map集合放到List集合中
- 2.如果返回的不是⼀条记录,是多条记录的话,只采⽤单个Map集合接收,会出现的异常:
TooManyResultsException
5. 返回Map<String,Map>
a.说明:
- 1.
拿Car的id做key,以后取出对应的Map集合时更⽅便
- 2.返回的数据结构:
b.说明:
- 1.
CarMapper接⼝
:
/**
* 获取所有的Car,返回⼀个Map集合。
* Map集合的key是Car的id。
* Map集合的value是对应Car。
* @return
*/
@MapKey("id")
Map<Long,Map<String,Object>> selectAllRetMap();
- 2.
CarMapper.xml
<select id="selectAllRetMap" resultType="map">
select id,car_num carNum,brand,guide_price guidePrice,produce_time produceTime,car_type carType from t_car
</select>
- 3.
CarMapperTest.testSelectAllRetMap
@Test
public void testSelectAllRetMap(){
CarMapper mapper = SqlSessionUtil.openSession().getMapper(CarMapper.class);
Map<Long,Map<String,Object>> cars = mapper.selectAllRetMap();
System.out.println(cars);
}
6 resultMap结果映射:
6.1.查询结果的列名和java对象的属性名对应不上怎么办?
a.为何会出现字段名与属性名的情况:
- 1.为何会出现不一致的情况:因为数据库规则是下划线来定义字段,然后再接口中是用驼峰的规则来定义属性。这时候就出现了字段名与属性名不一致的情况
b.解决方式:
- 1.第⼀种⽅式:
as 给列起别名
- 2.第⼆种⽅式:
使⽤resultMap进⾏结果映射
,若字段名和实体类中的属性名不一致或遇到一对多或者多对一的情况,则可以通过ResultMap设置自定义映射
- 3.第三种⽅式:
是否开启驼峰命名⾃动映射(配置settings)
6.2.分别说明3种解决属性名与字段名不一致的情况:
a.方式1:起别名的方式:
b.方式2:开启驼峰命名自动映射:
- 1.使⽤这种⽅式的前提是:属性名遵循Java的命名规范,数据库表的列名遵循SQL的命名规范。
- 2.Java命名规范:⾸字⺟⼩写,后⾯每个单词⾸字⺟⼤写,遵循驼峰命名⽅式。
- 3.SQL命名规范:全部⼩写,单词之间采⽤下划线分割。
- 4.如下方式的映射:
- 5.全局配置文件进行配置:在
全局配置文件
mybatis-config中进行配置:
c.方法3:编码使用 resultMap进⾏结果映射举例:
ResultMap标签
:设置自定义映射关系
- id:是唯一标识,不可以重复
- type:设置映射关系中实体类类型
- 子标签中的id:设置
主键
的映射关系,官方解释,配上id主键这个可以提高mybatis的效率
- 子标签中的property:设置映射关系中的属性名,必须是type属性所设置的实体类类型中的属性名
- 子标签中的colum:设置映射关系中的字段名,必须是sql语句查询出来的字段名
- 1.
CarMapper接⼝
/**
* 查询所有Car,使⽤resultMap进⾏结果映射
* @return
*/
List<Car> selectAllByResultMap();
- 2.
CarMapper.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>
- 3.
CarMapperTest.testSelectAllByResultMap
@Test
public void testSelectAllByResultMap(){
CarMapper carMapper = SqlSessionUtil.openSession().getMapper(CarMapper.class);
List<Car> cars = carMapper.selectAllByResultMap();
System.out.println(cars);
}