前言:
打包⽅式:jar
引⼊依赖:mysql驱动依赖、mybatis依赖、logback依赖、junit依赖。
引⼊配置⽂件:jdbc.properties、mybatis-config.xml、logback.xml
创建pojo类:Car
创建Mapper接⼝:CarMapper
创建Mapper接⼝对应的映射⽂件:com/powernode/mybatis/mapper/CarMapper.xml
创建单元测试:CarMapperTest
拷⻉⼯具类:SqlSessionUtil
注:我们在CarMapper.xml中的部分查询语句中使用动态sql标签,动态sql标签在course-20中讲解
这里提示一下
在CarMapper.xml中加入以下标签,不多解释具体看course-20
<!--声明一个SQL片段-->
<sql id="carColumnNameSql">
id,
car_num as carNum,
brand,
guide_price as guidePrice,
produce_time as produceTime,
car_type as carType
</sql>
如果实在不懂查询语句按以前写,例如:起别名方式
<select id="selectAll" resultType="car">
select
id,
car_num as carNum,
brand,
guide_price as guidePrice,
produce_time as ProduceTime,
car_type as carType
from
t_car
</select>
1. mybatis查询语句专题之返回Car 84
1.1 返回一个数据 84
//根据id查询Car信息 84
@Test
public void testSelectById(){
SqlSession sqlSession = SqlSessionUtil.openSession();
CarMapper mapper = sqlSession.getMapper(CarMapper.class);
Car car = mapper.selectById(44L);
System.out.println(car);
sqlSession.close();
}
<select id="selectById" resultType="car">
select
<include refid="carColumnNameSql"/>
from t_car where id = #{id}
</select>
执⾏结果:
查询结果是⼀条的话可以使⽤List集合接收吗?当然可以。
1.2 返回多个数据返回List 85
当查询的记录条数是多条的时候,必须使⽤集合接收。如果使⽤单个实体类接收会出现异常。
//查询多条数据 85
@Test
public void testSelectAll(){
SqlSession sqlSession = SqlSessionUtil.openSession();
CarMapper mapper = sqlSession.getMapper(CarMapper.class);
List<Car> cars = mapper.selectAll();
cars.forEach(car -> System.out.println(car));
sqlSession.close();
}
<select id="selectAll" resultType="car">
select
<include refid="carColumnNameSql"/>
from t_car
</select>
2. 根据品牌进行模糊查询 85
模糊查询的结果可能有多个,但是我采用一个POJO对象来接收会有问题吗?有问题
//根据品牌进行模糊查询 85
//模糊查询的结果可能有多个,但是我采用一个POJO对象来接收会有问题吗?有问题
@Test
public void testSelectByBrandLike(){
SqlSession sqlSession = SqlSessionUtil.openSession();
CarMapper mapper = sqlSession.getMapper(CarMapper.class);
// TooManyResultsException
// 什么意思?你期望的结果是返回一条记录。但是实际的SQL语句在执行的时候
// ,返回的记录条数不是一条,是多条。
Car car = mapper.selectByBrandLike("沃尔沃");
System.out.println(car);
sqlSession.close();
}
<select id="selectByBrandLike" resultType="car">
select
<include refid="carColumnNameSql"/>
from t_car
where
brand like "%"#{brand}"%"
</select>
3. 根据id查询Car,id是主键。这个结果一定是一条。 86
不可能有多条数据。那么这种情况可以使用List集合接收吗?可以
//根据id查询Car,id是主键。这个结果一定是一条。 86
//不可能有多条数据。那么这种情况可以使用List集合接收吗?可以
@Test
public void testSelectById2(){
SqlSession sqlSession = SqlSessionUtil.openSession();
CarMapper mapper = sqlSession.getMapper(CarMapper.class);
List<Car> cars = mapper.selectById2(166L);
System.out.println(cars);
sqlSession.close();
}
<select id="selectById2" resultType="car">
select
<!--将声明的sql片段包含进来。-->
<include refid="carColumnNameSql"/>
from t_car where id = #{id}
</select>
4. 返回Map 87
当返回的数据,没有合适的实体类对应的话,可以采⽤Map集合接收。字段名做key,字段值做value。查询如果可以保证只有⼀条数据,则返回⼀个Map集合即可。
/根据id获取汽车信息。将汽车信息放到Map集合中。 87
@Test
public void testSelectByIdRetMap(){
SqlSession sqlSession = SqlSessionUtil.openSession();
CarMapper mapper = sqlSession.getMapper(CarMapper.class);
Map<String, Object> car = mapper.selectByIdRetMap(44L);
System.out.println(car);
sqlSession.close();
}
<!--resultType="java.util.Map"有别名:map-->
<select id="selectByIdRetMap" resultType="map">
select * from t_car where id = #{id}
</select>
5. 返回多个Map 88
当然,如果返回⼀个Map集合,可以将Map集合放到List集合中吗?当然可以,这⾥就不再测试了。反过来,如果返回的不是⼀条记录,是多条记录的话,只采⽤单个Map集合接收,这样同样会出现之前的异常:TooManyResultsException
查询结果条数⼤于等于1条数据,则可以返回⼀个存储Map集合的List集合。List等同于List
//查询所有的Car信息。返回一个存放Map集合的List集合。 88
@Test
public void testSelectAllRetListMap(){
SqlSession sqlSession = SqlSessionUtil.openSession();
CarMapper mapper = sqlSession.getMapper(CarMapper.class);
List<Map<String, Object>> maps = mapper.selectAllRetListMap();
maps.forEach(map -> System.out.println(map));
sqlSession.close();
}
<!--这个resultType不是list,是map-->
<select id="selectAllRetListMap" resultType="map">
select * from t_car
</select>
6. 返回大Map 89
拿Car的id做key,以后取出对应的Map集合时更⽅便。
@MapKey("id") // 将查询结果的id值作为整个大Map集合的key。
//查询所有的Car,返回一个大Map集合。 89
//Map集合的key是每条记录的主键值。
//Map集合的value是每条记录。
@Test
public void testSelectAllRetMap(){
SqlSession sqlSession = SqlSessionUtil.openSession();
CarMapper mapper = sqlSession.getMapper(CarMapper.class);
Map<Long, Map<String, Object>> map = mapper.selectAllRetMap();
System.out.println(map);
sqlSession.close();
}
<select id="selectAllRetMap" resultType="map">
select * from t_car
</select>
7. 结果映射 90
查询结果的列名和java对象的属性名对应不上怎么办?
7.1 第⼀种⽅式:as 给列起别名
例如
<select id="selectAll" resultType="car">
select
id,
car_num as carNum,
brand,
guide_price as guidePrice,
produce_time as ProduceTime,
car_type as carType
from
t_car
</select>
7.2 第⼆种⽅式:使⽤resultMap进⾏结果映射 90
1.专门定义一个结果映射,在这个结果映射当中指定数据库表的字段名和Java类的属性名的对应关系。
2. type属性:用来指定POJO类的类名。
3. id属性:指定resultMap的唯一标识。这个id将来要在select标签中使用。
如果数据库表中有主键,一般都是有主键,要不然不符合数据库设计第一范式。如果有主键,建议这里配置一个id标签,注意:这不是必须的。但是官方的解释是什么呢?这样的配置可以让mybatis提高效率。
property后面填写POJO类的属性名
column后面填写数据库表的字段名
如果column和property是一样的,这个可以省略。
<resultMap id="carResultMap" type="Car">
<!--如果数据库表中有主键,一般都是有主键,要不然不符合数据库设计第一范式。-->
<!--如果有主键,建议这里配置一个id标签,注意:这不是必须的。但是
官方的解释是什么呢?这样的配置可以让mybatis提高效率。-->
<id property="id" column="id"/>
<!--<result property="id" column="id"/>-->
<!--property后面填写POJO类的属性名-->
<!--column后面填写数据库表的字段名-->
<result property="carNum" column="car_num" javaType="java.lang.String" jdbcType="VARCHAR"/>
<!--如果column和property是一样的,这个可以省略。-->
<!--<result property="brand" column="brand"/>-->
<result property="guidePrice" column="guide_price"/>
<result property="produceTime" column="produce_time"/>
<result property="carType" column="car_type" javaType="string" jdbcType="VARCHAR"/>
</resultMap>
//查询所有的Car信息。使用resultMap标签进行结果映射。 90
@Test
public void testSelectAllByResultMap(){
SqlSession sqlSession = SqlSessionUtil.openSession();
CarMapper mapper = sqlSession.getMapper(CarMapper.class);
List<Car> cars = mapper.selectAllByResultMap();
cars.forEach(car -> System.out.println(car));
sqlSession.close();
}
7.3 第三种⽅式:是否开启驼峰命名⾃动映射(配置settings)91
使⽤这种⽅式的前提是:属性名遵循Java的命名规范,数据库表的列名遵循SQL的命名规范。
Java命名规范:⾸字⺟⼩写,后⾯每个单词⾸字⺟⼤写,遵循驼峰命名⽅式。
SQL命名规范:全部⼩写,单词之间采⽤下划线分割。
例如下面的方式
如何启⽤该功能,在mybatis-config.xml⽂件中进⾏配置:
<!--mybatis的全局设置-->
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
//查询所有的Car信息。但是启用了驼峰命名自动映射机制。91
@Test
public void testSelectAllByMapUnderscoreToCamelCase(){
SqlSession sqlSession = SqlSessionUtil.openSession();
CarMapper mapper = sqlSession.getMapper(CarMapper.class);
List<Car> cars = mapper.selectAllByMapUnderscoreToCamelCase();
cars.forEach(car -> System.out.println(car));
sqlSession.close();
}
<select id="selectAllByMapUnderscoreToCamelCase" resultType="Car">
select * from t_car
</select>
8. 返回总记录条数 92
//获取Car的总记录条数。 92
@Test
public void testSelectTotal(){
SqlSession sqlSession = SqlSessionUtil.openSession();
CarMapper mapper = sqlSession.getMapper(CarMapper.class);
Long total = mapper.selectTotal();
System.out.println("总记录条数:" + total);
sqlSession.close();
}
<!--<select id="selectTotal" resultType="java.lang.Long">-->
<select id="selectTotal" resultType="_long">
select count(*) from t_car
</select>
9. 主要代码汇总
main中com.powernode.mybatis.mapper
接口CarMapper
package com.powernode.mybatis.mapper;
import com.powernode.mybatis.pojo.Car;
import org.apache.ibatis.annotations.MapKey;
import java.util.List;
import java.util.Map;
// mybatis查询语句专题 84
public interface CarMapper {
/**
* 获取Car的总记录条数。 92
* @return
*/
Long selectTotal();
/**
* 查询所有的Car信息。但是启用了驼峰命名自动映射机制。 91
* @return
*/
List<Car> selectAllByMapUnderscoreToCamelCase();
/**
* 查询所有的Car信息。使用resultMap标签进行结果映射。 90
* @return
*/
List<Car> selectAllByResultMap();
/**
* 查询所有的Car,返回一个大Map集合。 89
* Map集合的key是每条记录的主键值。
* Map集合的value是每条记录。
* {
* 160={car_num=3333, id=160, guide_price=32.00, produce_time=2000-10-10, brand=奔驰E300L, car_type=新能源},
* 161={car_num=4444, id=161, guide_price=32.00, produce_time=2000-10-10, brand=奔驰C200, car_type=新能源},
* 162={car_num=9999, id=162, guide_price=30.00, produce_time=2020-10-11, brand=帕萨特, car_type=燃油车},
* 163={car_num=9991, id=163, guide_price=30.00, produce_time=2020-11-11, brand=凯美瑞, car_type=燃油车},
* 158={car_num=1111, id=158, guide_price=3.00, produce_time=2000-10-10, brand=比亚迪汉, car_type=新能源},
* 159={car_num=2222, id=159, guide_price=32.00, produce_time=2000-10-10, brand=比亚迪秦, car_type=新能源}
* }
* @return
*/
@MapKey("id") // 将查询结果的id值作为整个大Map集合的key。 89
Map<Long, Map<String,Object>> selectAllRetMap();
/**
* 查询所有的Car信息。返回一个存放Map集合的List集合。 88
* @return
*/
List<Map<String,Object>> selectAllRetListMap();
/**
* 根据id获取汽车信息。将汽车信息放到Map集合中。 87
* +-----+---------+----------+-------------+--------------+----------+
* | id | car_num | brand | guide_price | produce_time | car_type |
* +-----+---------+----------+-------------+--------------+----------+
* | 158 | 1111 | 比亚迪汉 | 3.00 | 2000-10-10 | 新能源 |
* +-----+---------+----------+-------------+--------------+----------+
*
* Map<String, Object>
* k v
* -----------------------
* "id" 158
* "car_num" 1111
* "brand" 比亚迪汉
* ....
*
* @param id
* @return
*/
Map<String, Object> selectByIdRetMap(Long id);
/**
* 根据id查询Car,id是主键。这个结果一定是一条。 86
* 不可能有多条数据。那么这种情况可以使用List集合接收吗?
* @param id
* @return
*/
List<Car> selectById2(Long id);
/**
* 根据品牌进行模糊查询。
* 模糊查询的结果可能有多个,但是我采用一个POJO对象来接收会有问题吗?
* @param brand
* @return
*/
Car selectByBrandLike(String brand);
/**
* 获取所有的Car 85
* @return
*/
List<Car> selectAll();
/**
* 根据id查询Car信息 84
* @param id
* @return
*/
Car selectById(Long id);
}
test中com.powernode.mybatis.test
CarMapperTest
package com.powernode.mybatis.test;
import com.powernode.mybatis.mapper.CarMapper;
import com.powernode.mybatis.pojo.Car;
import com.powernode.mybatis.utils.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
import java.util.Map;
// mybatis查询语句专题 84
public class CarMapperTest {
//获取Car的总记录条数。 92
@Test
public void testSelectTotal(){
SqlSession sqlSession = SqlSessionUtil.openSession();
CarMapper mapper = sqlSession.getMapper(CarMapper.class);
Long total = mapper.selectTotal();
System.out.println("总记录条数:" + total);
sqlSession.close();
}
//查询所有的Car信息。但是启用了驼峰命名自动映射机制。91
@Test
public void testSelectAllByMapUnderscoreToCamelCase(){
SqlSession sqlSession = SqlSessionUtil.openSession();
CarMapper mapper = sqlSession.getMapper(CarMapper.class);
List<Car> cars = mapper.selectAllByMapUnderscoreToCamelCase();
cars.forEach(car -> System.out.println(car));
sqlSession.close();
}
//查询所有的Car信息。使用resultMap标签进行结果映射。 90
@Test
public void testSelectAllByResultMap(){
SqlSession sqlSession = SqlSessionUtil.openSession();
CarMapper mapper = sqlSession.getMapper(CarMapper.class);
List<Car> cars = mapper.selectAllByResultMap();
cars.forEach(car -> System.out.println(car));
sqlSession.close();
}
//查询所有的Car,返回一个大Map集合。 89
//Map集合的key是每条记录的主键值。
//Map集合的value是每条记录。
@Test
public void testSelectAllRetMap(){
SqlSession sqlSession = SqlSessionUtil.openSession();
CarMapper mapper = sqlSession.getMapper(CarMapper.class);
Map<Long, Map<String, Object>> map = mapper.selectAllRetMap();
System.out.println(map);
sqlSession.close();
}
//查询所有的Car信息。返回一个存放Map集合的List集合。 88
@Test
public void testSelectAllRetListMap(){
SqlSession sqlSession = SqlSessionUtil.openSession();
CarMapper mapper = sqlSession.getMapper(CarMapper.class);
List<Map<String, Object>> maps = mapper.selectAllRetListMap();
maps.forEach(map -> System.out.println(map));
sqlSession.close();
}
//根据id获取汽车信息。将汽车信息放到Map集合中。 87
@Test
public void testSelectByIdRetMap(){
SqlSession sqlSession = SqlSessionUtil.openSession();
CarMapper mapper = sqlSession.getMapper(CarMapper.class);
Map<String, Object> car = mapper.selectByIdRetMap(44L);
System.out.println(car);
sqlSession.close();
}
//根据id查询Car,id是主键。这个结果一定是一条。 86
//不可能有多条数据。那么这种情况可以使用List集合接收吗?可以
@Test
public void testSelectById2(){
SqlSession sqlSession = SqlSessionUtil.openSession();
CarMapper mapper = sqlSession.getMapper(CarMapper.class);
List<Car> cars = mapper.selectById2(42L);
System.out.println(cars);
sqlSession.close();
}
//根据品牌进行模糊查询 85
//模糊查询的结果可能有多个,但是我采用一个POJO对象来接收会有问题吗?有问题
@Test
public void testSelectByBrandLike(){
SqlSession sqlSession = SqlSessionUtil.openSession();
CarMapper mapper = sqlSession.getMapper(CarMapper.class);
// TooManyResultsException
// 什么意思?你期望的结果是返回一条记录。但是实际的SQL语句在执行的时候
// ,返回的记录条数不是一条,是多条。
Car car = mapper.selectByBrandLike("沃尔沃");
System.out.println(car);
sqlSession.close();
}
//查询多条数据 85
@Test
public void testSelectAll(){
SqlSession sqlSession = SqlSessionUtil.openSession();
CarMapper mapper = sqlSession.getMapper(CarMapper.class);
List<Car> cars = mapper.selectAll();
cars.forEach(car -> System.out.println(car));
sqlSession.close();
}
//根据id查询Car信息 84-85
@Test
public void testSelectById(){
SqlSession sqlSession = SqlSessionUtil.openSession();
CarMapper mapper = sqlSession.getMapper(CarMapper.class);
Car car = mapper.selectById(44L);
System.out.println(car);
sqlSession.close();
}
}
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="selectTotal" resultType="java.lang.Long">-->
<select id="selectTotal" resultType="_long">
select count(*) from t_car
</select>
<select id="selectAllByMapUnderscoreToCamelCase" resultType="Car">
select * from t_car
</select>
<!-- 90
1.专门定义一个结果映射,在这个结果映射当中指定数据库表的字段名和Java类的属性名的对应关系。
2. type属性:用来指定POJO类的类名。
3. id属性:指定resultMap的唯一标识。这个id将来要在select标签中使用。
-->
<resultMap id="carResultMap" type="Car">
<!--如果数据库表中有主键,一般都是有主键,要不然不符合数据库设计第一范式。-->
<!--如果有主键,建议这里配置一个id标签,注意:这不是必须的。但是
官方的解释是什么呢?这样的配置可以让mybatis提高效率。-->
<id property="id" column="id"/>
<!--<result property="id" column="id"/>-->
<!--property后面填写POJO类的属性名-->
<!--column后面填写数据库表的字段名-->
<result property="carNum" column="car_num" javaType="java.lang.String" jdbcType="VARCHAR"/>
<!--如果column和property是一样的,这个可以省略。-->
<!--<result property="brand" column="brand"/>-->
<result property="guidePrice" column="guide_price"/>
<result property="produceTime" column="produce_time"/>
<result property="carType" column="car_type" javaType="string" jdbcType="VARCHAR"/>
</resultMap>
<!--select标签的resultMap属性,用来指定使用哪个结果映射
。resultMap后面的值是resultMap的id-->
<select id="selectAllByResultMap" resultMap="carResultMap">
select * from t_car
</select>
<select id="selectAllRetMap" resultType="map">
select * from t_car
</select>
<!--这个resultType不是list,是map-->
<select id="selectAllRetListMap" resultType="map">
select * from t_car
</select>
<!--resultType="java.util.Map"有别名:map-->
<select id="selectByIdRetMap" resultType="map">
select * from t_car where id = #{id}
</select>
<!--声明一个SQL片段-->
<sql id="carColumnNameSql">
id,
car_num as carNum,
brand,
guide_price as guidePrice,
produce_time as produceTime,
car_type as carType
</sql>
<select id="selectById2" resultType="car">
select
<!--将声明的sql片段包含进来。-->
<include refid="carColumnNameSql"/>
from t_car where id = #{id}
</select>
<select id="selectByBrandLike" resultType="car">
select
<include refid="carColumnNameSql"/>
from t_car
where
brand like "%"#{brand}"%"
</select>
<select id="selectAll" resultType="car">
select
<include refid="carColumnNameSql"/>
from t_car
</select>
<select id="selectById" resultType="car">
select
<include refid="carColumnNameSql"/>
from t_car where id = #{id}
</select>
</mapper>
mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="jdbc.properties"/>
<!--mybatis的全局设置-->
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<typeAliases>
<package name="com.powernode.mybatis.pojo"/>
</typeAliases>
<environments default="dev">
<environment id="dev">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<package name="com.powernode.mybatis.mapper"/>
</mappers>
</configuration>
以下不做补充参考前名course-15代码在course13_1
还有pojo类
utils类
logback.xml
jdbc.properties
pom.xml
标签:语句,mapper,专题,Map,car,sqlSession,mybatis,CarMapper,id From: https://blog.51cto.com/u_15784725/6423916