【MyBatis】| MyBatis查询语句专题(接口中方法的返回值类型专栏)

目录

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

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

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

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

③怎么解决?

使用as对字段进行重名,或者使用settings标签的name属性设置为mapUnderscoreToCamelCase,value设置为true开启驼峰命名规则!

<?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.bjpowernode.mybatis.mapper.CarMapper">
    <select id="selectById" resultType="Car">
        <!--select * from  t_car where id = #{id};-->
        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};
    </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 {
    @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>

查询结果,返回的对象是多个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 mapper
        PUBLIC "-//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
            id,
            car_num as carNum,
            brand,
            guide_price as guidePrice,
            produce_time as produceTime,
            car_type as carType
        from  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 {
    @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();
    }
}

3. 返回Map

(1)当返回的数据,没有合适的实体类对应的话,可以采⽤Map集合接收;数据库中的字段名做key,数据库中的字段值做value。

(2)查询如果可以保证只有⼀条数据,则返回⼀个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 mapper
        PUBLIC "-//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 {
    @Test
    public 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 mapper
        PUBLIC "-//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 {
    @Test
    public 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 mapper
        PUBLIC "-//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
    @Test
    public 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标签中的resultMap属性当中使用(注意:不在是resultType属性了)。

一个参数是type,用来指定POJO类的类名。

在resultMap下还有一个子标签result:

首先对于有主键的需要配一个id,使用id标签,不是必须的,但可以增加效率。

然后下面使用result子标签的property属性和column属性分别指定POJO类的属性名和数据库表中的字段表之间的映射关系。

⑤也可以给当前标签配置上javaType和jdbcType属性,非必须要,但是可以增加效率,因为减少了MyBatis自动推断。

⑥select标签使用了resultMap属性,原来的resultType属性就不需要指定了。

<?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.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 {
    @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();
    }
}

(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 mapper
        PUBLIC "-//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 {
    @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();
    }
}

7. 返回总记录条数

需求:查询总记录条数,使用count函数!

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

猜你喜欢

转载自blog.csdn.net/m0_61933976/article/details/128563890