> 文档中心 > 【MyBatis】| MyBatis查询语句专题(核心知识)

【MyBatis】| MyBatis查询语句专题(核心知识)

目录

一:MyBatis查询语句专题

1. 返回Car对象

2. 返回List

3. 返回Map

4. 返回List

5. 返回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进行查询,返回的是Car    Car selectById(Long id);}

三兄弟之二:CarMapper.xml文件,编写sql语句

①namespace指定的一定是接口的包名,select的id一定是方法的方法名!

②select * from  t_car where id = #{id};这样查询肯定会有问题,前面已经接触过,除了id和brand字段,其它字段都为空;因为数据库表中的字段名与Car对象的字段名不相同!

③怎么解决?使用as对字段进行重名!

      select     id,     car_num as carNum,     brand,     guide_price as guidePrice,     produce_time as produceTime,     car_type as carType from  t_car where id = #{id};    

三兄弟之三: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 {    @Test    public 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对象,这就需要一个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 selectAll();}

三兄弟之二:CarMapper.xml文件,编写sql语句

没有where查询条件,查询的是所有数据库表中的结果

     select     id,     car_num as carNum,     brand,     guide_price as guidePrice,     produce_time as produceTime,     car_type as carType from  t_car;    

三兄弟之三: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 {    @Test    public void testSelectAll(){ SqlSession sqlSession = SqlSessionUtil.openSession(); CarMapper mapper = sqlSession.getMapper(CarMapper.class); List 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 selectByIdReturnMap(Long id);}

三兄弟之二:CarMapper.xml文件,编写sql语句

注:这里主要就是resultType属性的值怎么写?我们使用Map集合进行接收,所以就使用:java.util.Map,当然也可以使用MyBatis内置的别名map。

     select *  from  t_car where id = #{id};    

三兄弟之三: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 {    @Test    public void testSelectByIdReturnMap(){ SqlSession sqlSession = SqlSessionUtil.openSession(); CarMapper mapper = sqlSession.getMapper(CarMapper.class); Map map = mapper.selectByIdReturnMap(1L); System.out.println(map); sqlSession.close();    }}

4. 返回List

如果返回的数据,没有合适的实体类对应,并且查询结果条数⼤于等于1条数据,则可以返回⼀个存储Map集合的List集合:List,实际上就等同于List。

 三兄弟之一:CarMapper接口,编写方法

上面是查询返回一条结果,使用Map集合接收即可;现在是查询所有,返回的是一个存放Map集合的List集合。

package com.bjpowernode.mybatis.mapper;public interface CarMapper {    // 查询所有的Car信息,返回的是一个存放Map集合的List集合    List<Map> selectAllReturnListMap();}

三兄弟之二:CarMapper.xml文件,编写sql语句

注:这里主要就是resultType属性的值还是填写List集合的里面元素Map集合

     select *  from  t_car;    

三兄弟之三: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 {    @Test    public void testSelectAllReturnListMap(){ SqlSession sqlSession = SqlSessionUtil.openSession(); CarMapper mapper = sqlSession.getMapper(CarMapper.class); List<Map> maps = mapper.selectAllReturnListMap(); maps.forEach(map-> System.out.println(map)); sqlSession.close();    }}

5. 返回Map

返回List的时候,取数据并不好取,假如取id是3的元素,需要遍历整个集合;所以我们可以返回一个大Map集合的方式: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> selectAllReturnMapMap();}

三兄弟之二:CarMapper.xml文件,编写sql语句

注:这里resultType属性的值还是填写大Map集合的里面元素小Map集合

     select *  from  t_car;    

三兄弟之三: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    @Test    public void testSelectAllReturnMapMap(){ SqlSession sqlSession = SqlSessionUtil.openSession(); CarMapper mapper = sqlSession.getMapper(CarMapper.class); Map<Long, Map> 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 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属性就不需要指定了。

              <!-- -->                 select * from t_car;    

三兄弟之三: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 {    @Test    public void testSelectAllByResultMap(){ SqlSession sqlSession = SqlSessionUtil.openSession(); CarMapper mapper = sqlSession.getMapper(CarMapper.class); List cars = mapper.selectAllByResultMap(); cars.forEach(car -> System.out.println(car)); sqlSession.close();    }}

(2)是否开启驼峰命名⾃动映射(配置settings)

前提:属性名遵循Java的命名规范,数据库表的列名遵循SQL的命名规范。

①Java命名规范:⾸字⺟⼩写,后⾯每个单词⾸字⺟⼤写,遵循驼峰命名⽅式。

②SQL命名规范:全部⼩写,单词之间采⽤下划线分割。

⽐如以下的对应关系:

如何启⽤该功能,在核心配置文件mybatis-config.xml中进⾏配置:

 

 三兄弟之一: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 selectAllByMapUnderscoreToCamelCase();}

三兄弟之二:CarMapper.xml文件,编写sql语句

     select * from t_car;    

 三兄弟之三: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 {    @Test    public void testSelectAllByMapUnderscoreToCamelCase(){ SqlSession sqlSession = SqlSessionUtil.openSession(); CarMapper mapper = sqlSession.getMapper(CarMapper.class); List 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(别名)

     select count(*) from t_car;    

 三兄弟之三: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 {   @Test    public void testSelectTotal(){ SqlSession sqlSession = SqlSessionUtil.openSession(); CarMapper mapper = sqlSession.getMapper(CarMapper.class); Long total = mapper.selectTotal(); System.out.println("总记录条数"+total); sqlSession.close();    }}