目录
一:MyBatis查询语句专题
1. 返回Car对象
2. 返回List<Car>
3. 返回Map
4. 返回List<Map>
5. 返回Map<String,Map>
6. resultMap结果映射
7. 返回总记录条数
一:MyBatis查询语句专题
前期准备:
模块名:mybatis-008-select
打包⽅式:jar
引⼊依赖:mysql驱动依赖、mybatis依赖、logback依赖、junit依赖。
引⼊配置⽂件:jdbc.properties、mybatis-config.xml、logback.xml
创建pojo类:com.bjpowernode.mybatis.pojo.Car
创建Mapper接⼝:com.bjpowernode.mybatis.mapper.CarMapper
创建Mapper接⼝对应的映射⽂件:com/powernode/mybatis/mapper/CarMapper.xml
创建单元测试:com.bjpowernode.mybatis.test.CarMapperTest
拷⻉⼯具类:com.bjpowernode.mybatis.utils.SqlSessionUtils
1. 返回Car对象
查询结果,返回的对象是一个Car对象!
三兄弟之一:CarMapper接口,编写方法
在接口中定义抽象方法,通过id查询,返回的是一个Car对象
package com.bjpowernode.mybatis.mapper;import com.bjpowernode.mybatis.pojo.Car;public interface CarMapper {// 根据id进行查询,返回的是CarCar selectById(Long id);
}
三兄弟之二:CarMapper.xml文件,编写sql语句
①namespace指定的一定是接口的包名,select的id一定是方法的方法名!
②select * from t_car where id = #{id};这样查询肯定会有问题,前面已经接触过,除了id和brand字段,其它字段都为空;因为数据库表中的字段名与Car对象的字段名不相同!
③怎么解决?使用as对字段进行重名!
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.bjpowernode.mybatis.mapper.CarMapper"><select id="selectById" resultType="Car"><!--select * from t_car where id = #{id};-->selectid,car_num as carNum,brand,guide_price as guidePrice,produce_time as produceTime,car_type as carTypefrom t_car where id = #{id};</select>
</mapper>
三兄弟之三:CarMappeTest类,用来编写测试类
package com.bjpowernode.mybatis.test;import com.bjpowernode.mybatis.mapper.CarMapper;
import com.bjpowernode.mybatis.pojo.Car;
import com.bjpowernode.mybatis.utils.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;public class CarMapperTest {@Testpublic void testSelectById(){SqlSession sqlSession = SqlSessionUtil.openSession();CarMapper mapper = sqlSession.getMapper(CarMapper.class);Car car = mapper.selectById(1L);System.out.println(car);sqlSession.close();}
}
2. 返回List<Car>
查询结果,返回的对象是多个Car对象,这就需要一个List集合进行存储!
三兄弟之一:CarMapper接口,编写方法
在接口中定义抽象方法,查询所有的Car,返回的是多个Car对象,使用List集合接收。
注:或者进行模糊查询,返回的也是多个Car对象。
注:如果明知道返回的是多个对象,但是就用一个POJO类Car来接收,会报TooManyResultsException异常:表示期望的结果是返回一条数据,但是实际的SQL语句在执行的时候,返回的记录不是一条、是多条。
注:如果知道返回的数据是一个Car对象,但是我们用一个List集合进行接收,这是没问题的
package com.bjpowernode.mybatis.mapper;import com.bjpowernode.mybatis.pojo.Car;public interface CarMapper {// 获取所有的Car,返回一个List集合List<Car> selectAll();
}
三兄弟之二:CarMapper.xml文件,编写sql语句
没有where查询条件,查询的是所有数据库表中的结果
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.bjpowernode.mybatis.mapper.CarMapper"><select id="selectById" resultType="Car">selectid,car_num as carNum,brand,guide_price as guidePrice,produce_time as produceTime,car_type as carTypefrom t_car;</select>
</mapper>
三兄弟之三:CarMappeTest类,用来编写测试类
查询所有,返回的是一个List集合,遍历这个集合打印即可
package com.bjpowernode.mybatis.test;import com.bjpowernode.mybatis.mapper.CarMapper;
import com.bjpowernode.mybatis.pojo.Car;
import com.bjpowernode.mybatis.utils.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;public class CarMapperTest {@Testpublic 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();}
}
3. 返回Map
当返回的数据,没有合适的实体类对应的话,可以采⽤Map集合接收;数据库中的字段名做key,数据库中的字段值做value。 查询如果可以保证只有⼀条数据,则返回⼀个Map集合即可。 例如:
三兄弟之一:CarMapper接口,编写方法
根据id进行查询返回的是一个Map集合,Map集合的key肯定是一个String类型;Map集合的value肯定是一个Object,因为具体的类型都不相同
package com.bjpowernode.mybatis.mapper;public interface CarMapper {// 根据id返回汽车信息,将汽车信息放到Map集合Map<String, Object> selectByIdReturnMap(Long id);
}
三兄弟之二:CarMapper.xml文件,编写sql语句
注:这里主要就是resultType属性的值怎么写?我们使用Map集合进行接收,所以就使用:java.util.Map,当然也可以使用MyBatis内置的别名map。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.bjpowernode.mybatis.mapper.CarMapper"><select id="selectByIdReturnMap" resultType="map">select * from t_car where id = #{id};</select>
</mapper>
三兄弟之三:CarMappeTest类,用来编写测试类
package com.bjpowernode.mybatis.test;import com.bjpowernode.mybatis.mapper.CarMapper;
import com.bjpowernode.mybatis.pojo.Car;
import com.bjpowernode.mybatis.utils.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;public class CarMapperTest {@Testpublic void testSelectByIdReturnMap(){SqlSession sqlSession = SqlSessionUtil.openSession();CarMapper mapper = sqlSession.getMapper(CarMapper.class);Map<String, Object> map = mapper.selectByIdReturnMap(1L);System.out.println(map);sqlSession.close();}
}
4. 返回List<Map>
如果返回的数据,没有合适的实体类对应,并且查询结果条数⼤于等于1条数据,则可以返回⼀个存储Map集合的List集合:List<Map>,实际上就等同于List<Car>。
三兄弟之一:CarMapper接口,编写方法
上面是查询返回一条结果,使用Map集合接收即可;现在是查询所有,返回的是一个存放Map集合的List集合。
package com.bjpowernode.mybatis.mapper;public interface CarMapper {// 查询所有的Car信息,返回的是一个存放Map集合的List集合List<Map<String,Object>> selectAllReturnListMap();
}
三兄弟之二:CarMapper.xml文件,编写sql语句
注:这里主要就是resultType属性的值还是填写List集合的里面元素Map集合
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.bjpowernode.mybatis.mapper.CarMapper"><select id="selectAllReturnListMap" resultType="map">select * from t_car;</select>
</mapper>
三兄弟之三:CarMappeTest类,用来编写测试类
package com.bjpowernode.mybatis.test;import com.bjpowernode.mybatis.mapper.CarMapper;
import com.bjpowernode.mybatis.pojo.Car;
import com.bjpowernode.mybatis.utils.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;public class CarMapperTest {@Testpublic void testSelectAllReturnListMap(){SqlSession sqlSession = SqlSessionUtil.openSession();CarMapper mapper = sqlSession.getMapper(CarMapper.class);List<Map<String, Object>> maps = mapper.selectAllReturnListMap();maps.forEach(map-> System.out.println(map));sqlSession.close();}
}
5. 返回Map<String,Map>
返回List<Map>的时候,取数据并不好取,假如取id是3的元素,需要遍历整个集合;所以我们可以返回一个大Map集合的方式:Map<String,Map>;拿Car的id做key,Map集合做value,以后取出对应的Map集合时更⽅便。
三兄弟之一:CarMapper接口,编写方法
①上面的方式,如果取出某个数据,需要遍历整个集合,所以我们采用另一种方式存储:
拿Car的id做key,Map集合做value,再放到一个大Map集合当中!
②使用这种方式需要一个注解:@MapKey("id"),表示将每个数据查询结果的id作为整个大Map集合的key
package com.bjpowernode.mybatis.mapper;public interface CarMapper {// 查询所有的Car,返回一个大Map集合@MapKey("id") Map<Long,Map<String,Object>> selectAllReturnMapMap();
}
三兄弟之二:CarMapper.xml文件,编写sql语句
注:这里resultType属性的值还是填写大Map集合的里面元素小Map集合
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.bjpowernode.mybatis.mapper.CarMapper"><select id="selectAllReturnMapMap" resultType="map">select * from t_car;</select>
</mapper>
三兄弟之三:CarMappeTest类,用来编写测试类
注:取出来的数据就是查询出所有的数据放到一个大Map集合当中
package com.bjpowernode.mybatis.test;import com.bjpowernode.mybatis.mapper.CarMapper;
import com.bjpowernode.mybatis.pojo.Car;
import com.bjpowernode.mybatis.utils.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;public class CarMapperTest {@Test@Testpublic void testSelectAllReturnMapMap(){SqlSession sqlSession = SqlSessionUtil.openSession();CarMapper mapper = sqlSession.getMapper(CarMapper.class);Map<Long, Map<String, Object>> doubleMap = mapper.selectAllReturnMapMap();System.out.println(doubleMap);sqlSession.close();}
}
6. resultMap结果映射
查询结果的列名和java对象的属性名对应不上怎么办?
①第⼀种⽅式:as 给列起别名,前面一直在用的方法。
②第⼆种⽅式:使⽤resultMap进⾏结果映射。
③第三种⽅式:是否开启驼峰命名⾃动映射。
(1)使⽤resultMap进⾏结果映射
三兄弟之一:CarMapper接口,编写方法
package com.bjpowernode.mybatis.mapper;import com.bjpowernode.mybatis.pojo.Car;
import org.apache.ibatis.annotations.MapKey;
import java.util.*;public interface CarMapper {// 查询所有的Car信息,使用resultMap标签进行结果映射List<Car> selectAllByResultMap();
}
三兄弟之二:CarMapper.xml文件,编写sql语句
①前面都是使用as进行重命名,并且需要把每个字段都写出来,比较麻烦。
②现在专门定义一个结果映射,在这个结果映射当中指定数据库表的字段名和Java类的属性名的对应关系。
③结果映射resultMap有两个参数:
一个参数是id,指定resultMap的唯一标识,这个id将来在select标签中使用。
一个参数是type,用来指定POJO类的类名。
④在resultMap下还有一个子标签result;首先对于有主键的需要配一个id,不是必须的,但可以增加效率;下面使用result子标签的property属性和column属性分别指定POJO类的属性名和数据库表中的字段表之间的映射关系。
⑤也可以给当前标签配置上javaType和jdbcType属性,非必须要,但是可以增加效率,因为减少了MyBatis自动推断。
⑥select标签使用了resultMap属性,原来的resultType属性就不需要指定了。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.bjpowernode.mybatis.mapper.CarMapper"><!--这里的car就是com.bjpowernode.mybatis.pojo.Car,使用了内置的别名--><resultMap id="CarResultMap" type="car"><!--数据库表中有主键,建议配一个id,可以提高效率--><id property="id" column="id" /><!--property后面填写POJO类的属性名,column后面填写数据库表中的字段名--><result property="carNum" column="car_num" /><!--如果property和column是一样的,可以省略--><!-- <result property="brand" column="brand" />--><result property="guidePrice" column="guide_price" /><result property="produceTime" column="produce_time" /><!--当然也可以指定javaType和jdbcType属性,减少自动推断,效率可能更高--><result property="carType" column="car_type" javaType="string" jdbcType="VARCHAR" /></resultMap><!--select标签的resultMap属性用来指定使用哪个结果映射,后面跟的是resultMap的id--><select id="selectAllByResultMap" resultMap="CarResultMap">select * from t_car;</select>
</mapper>
三兄弟之三:CarMappeTest类,用来编写测试类
package com.bjpowernode.mybatis.test;import com.bjpowernode.mybatis.mapper.CarMapper;
import com.bjpowernode.mybatis.pojo.Car;
import com.bjpowernode.mybatis.utils.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;import java.util.List;
import java.util.Map;public class CarMapperTest {@Testpublic 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();}
}
(2)是否开启驼峰命名⾃动映射(配置settings)
前提:属性名遵循Java的命名规范,数据库表的列名遵循SQL的命名规范。
①Java命名规范:⾸字⺟⼩写,后⾯每个单词⾸字⺟⼤写,遵循驼峰命名⽅式。
②SQL命名规范:全部⼩写,单词之间采⽤下划线分割。
⽐如以下的对应关系:
如何启⽤该功能,在核心配置文件mybatis-config.xml中进⾏配置:
<!--放在properties标签后⾯-->
<settings><setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
三兄弟之一:CarMapper接口,编写方法
package com.bjpowernode.mybatis.mapper;import com.bjpowernode.mybatis.pojo.Car;
import org.apache.ibatis.annotations.MapKey;
import java.util.*;public interface CarMapper {// 查询所有Car,启⽤驼峰命名⾃动映射List<Car> selectAllByMapUnderscoreToCamelCase();
}
三兄弟之二:CarMapper.xml文件,编写sql语句
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.bjpowernode.mybatis.mapper.CarMapper"><select id="selectAllByMapUnderscoreToCamelCase" resultType="car">select * from t_car;</select>
</mapper>
三兄弟之三:CarMappeTest类,用来编写测试类
package com.bjpowernode.mybatis.test;import com.bjpowernode.mybatis.mapper.CarMapper;
import com.bjpowernode.mybatis.pojo.Car;
import com.bjpowernode.mybatis.utils.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;import java.util.List;
import java.util.Map;public class CarMapperTest {@Testpublic 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();}
}
7. 返回总记录条数
需求:查询总记录条数
三兄弟之一:CarMapper接口,编写方法
方法的返回类型定义成Long或者Integer都可以,这里就使用Long
package com.bjpowernode.mybatis.mapper;import com.bjpowernode.mybatis.pojo.Car;
import org.apache.ibatis.annotations.MapKey;
import java.util.*;public interface CarMapper {// 获取总记录条数Long selectTotal();
}
三兄弟之二:CarMapper.xml文件,编写sql语句
注:前面我们返回的类型是Long,所以这里resultType的指定类型也是long(别名)
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.bjpowernode.mybatis.mapper.CarMapper"><select id="selectTotal" resultType="long">select count(*) from t_car;</select>
</mapper>
三兄弟之三:CarMappeTest类,用来编写测试类
package com.bjpowernode.mybatis.test;import com.bjpowernode.mybatis.mapper.CarMapper;
import com.bjpowernode.mybatis.pojo.Car;
import com.bjpowernode.mybatis.utils.SqlSessionUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;import java.util.List;
import java.util.Map;public class CarMapperTest {@Testpublic void testSelectTotal(){SqlSession sqlSession = SqlSessionUtil.openSession();CarMapper mapper = sqlSession.getMapper(CarMapper.class);Long total = mapper.selectTotal();System.out.println("总记录条数"+total);sqlSession.close();}
}