前言:
打包⽅式: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
注:我们在Carmaper中.在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查询语句话题返回Car841.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返回多个数据返回List85当查询的记录条数多时,必须使用⽤集合接收。如果使用⽤单个实体类接收会出现异常。
///查询多个数据 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.返回Map87
如果返回的数据没有适当的实体类对应,可以采集⽤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.返回多个Map888
当然,如果返回⼀Map集合能把Map集合放在List集合中吗?当然⾥不再测试了。另一方面,如果返回不是⼀如果条记录是多个记录,则只采用⽤单个Map集合接收,也会出现以前的异常:TooManyResultsException
查询结果条数⼤如果等于一个数据,则可以返回⼀List集合存储Map集合。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,而是mapp--> <select id="selectAllRetListMap" resultType="map"> select * from t_car </select>
以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进入resultmap⾏结果映射90
1.专门定义数据库表中指定的字段名和Java属性名的结果映射对应关系。
2.type属性:用于指定POJO类的类名。
3.id属性:指定resultmap的唯一标识。这个id将来会在select标签中使用。
如果数据库表中有主键,一般都有主键,否则不符合数据库设计的第一范式。如果有主键,建议在这里配置id标签。注意:没必要。但是官方解释是什么?这种配置可以提高mybatis的效率。
POJO类属性名填写在property后面
在column后面填写数据库表的字段名
假如column和property是一样的,这个可以省略。
<resultMap id="carResultMap" type="Car"> <!--若数据库表中有主键,一般都有主键,否则不符合数据库设计的第一范式。--> <!--如果有主键,建议在这里配置id标签。注意:这不是必须的。但是 官方解释是什么?这种配置可以提高mybatis的效率。--> <id property="id" column="id"/> <!--<result property="id" column="id"/>--> <!--POJO类属性名填写在property后面--> <!--在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(); }
使⽤这种⽅类型的前提是:属性名遵循Java命名规范,数据库表的列名遵循SQL命名规范。
Java命名规范:⾸字⺟⼩写,后⾯每个单词⾸字⺟⼤写作,遵循驼峰命名⽅式。
SQL命名规范:全部⼩写作,在单词之间采集⽤下划线分割。
例如,以下方法
如何启⽤在mybatiss中,这个功能-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.mapperCarMapper接口
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查询语句专题 84public interface CarMapper { /** * 获取Car总记录条数。 92 * @return */ Long selectTotal(); /** * 查询所有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信息。 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(); /** * Car信息根据id查询 84 * @param id * @return */ Car selectById(Long id);}
test中com.powernode.mybatis.testCarMapperTest
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查询语句专题 84public 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是每个记录的主键值。 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属性名的结果映射对应关系。-- 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"/>--> <!--POJO类属性名填写在property后面--> <!--在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> <!--resultMap属性,select标签,用于指定使用哪个结果映射 。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,而是mapp--> <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_13
还有pojo类
utils类
logback.xml
jdbc.properties
pom.xml