MyBatis(十一)、MyBatis查询语句专题

准备工作:

模块名:mybatis-007-select

打包方式: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

MyBatis(十一)、MyBatis查询语句专题_第1张图片

MyBatis(十一)、MyBatis查询语句专题_第2张图片

pom.xml



    4.0.0

    com.powernode
    mybatis-008-select
    1.0-SNAPSHOT
    jar

    
        
            org.mybatis
            mybatis
            3.5.10
        
        
            mysql
            mysql-connector-java
            8.0.30
        
        
            ch.qos.logback
            logback-classic
            1.2.11
        
        
            junit
            junit
            4.13.2
            test
        
    


    
        17
        17
        UTF-8
    

mybatis-config





    

    
        
    

    
        
            
            
                
                
                
                
            
        
    
    
        
    

logback




    
    
        
            
            %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n
        
    

    
    
    
    
    

    
    
        
        
    

jdbc.properties




    
    
        
            
            %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n
        
    

    
    
    
    
    

    
    
        
        
    

CarMapper

package com.powernode.mybatis.mapper;

import com.powernode.mybatis.pojo.Car;

/**
 * @author wuw
 * @since 2023-04-11 10:13:56
 */
public interface CarMapper {

  
}

Car

package com.powernode.mybatis.pojo;

/**
 * @author wuw
 * @since 2023-02-01 15:16:01
 */
public class Car {

    //数据库表中的字段应该和pojo类的属性一一对应
    private Long id;
    private String carNum;
    private String brand;
    private Double guidePrice;
    private String produceTime;
    private String carType;

    public Car(Long id, String carNum, String brand, Double guidePrice, String produceTime, String carType) {
        this.id = id;
        this.carNum = carNum;
        this.brand = brand;
        this.guidePrice = guidePrice;
        this.produceTime = produceTime;
        this.carType = carType;
    }

    public Car(){

    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getCarNum() {
        return carNum;
    }

    public void setCarNum(String carNum) {
        this.carNum = carNum;
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public Double getGuidePrice() {
        return guidePrice;
    }

    public void setGuidePrice(Double guidePrice) {
        this.guidePrice = guidePrice;
    }

    public String getProduceTime() {
        return produceTime;
    }

    public void setProduceTime(String produceTime) {
        this.produceTime = produceTime;
    }

    public String getCarType() {
        return carType;
    }

    public void setCarType(String carType) {
        this.carType = carType;
    }

    @Override
    public String toString() {
        return "car{" +
                "id=" + id +
                ", carNum='" + carNum + '\'' +
                ", brand='" + brand + '\'' +
                ", guidePrice=" + guidePrice +
                ", produceTime='" + produceTime + '\'' +
                ", carType='" + carType + '\'' +
                '}';
    }
}

SqlSessionUtil

package com.powernode.mybatis.utils;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

/**
 * @author wuw
 * @since 2023-04-04 09:42:28
 */
public class SqlSessionUtil {
    private static SqlSessionFactory sqlSessionFactory;

    /**
     * 类加载时初始化sqlSessionFactory对象
     */
    static {
        try {
            SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
            sqlSessionFactory = sqlSessionFactoryBuilder.build(Resources.getResourceAsStream("mybatis-config.xml"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static ThreadLocal local = new ThreadLocal<>();

    /**
     * 每调用一次openSession()可获取一个新的会话,该会话支持自动提交。
     *
     * @return 新的会话对象
     */
    public static SqlSession openSession() {
        SqlSession sqlSession = local.get();
        if (sqlSession == null) {
            sqlSession = sqlSessionFactory.openSession();
            local.set(sqlSession);
        }
        return sqlSession;
    }

    /**
     * 关闭SqlSession对象
     * @param sqlSession
     */
    public static void close(SqlSession sqlSession){
        if (sqlSession != null) {
            sqlSession.close();
        }
        local.remove();
    }
}

CarMapper.xml





    

一、返回Car

当查询的结果,有对应的实体类,并且查询结果只有一条时:

第一步、CarMapper接口

package com.powernode.mybatis.mapper;

import com.powernode.mybatis.pojo.Car;

/**
 * @author wuw
 * @since 2023-04-11 10:13:56
 */
public interface CarMapper {

    /**
     * 根据Id查Car信息
     * @param Id
     * @return
     */
    Car selectById(Long Id);
}

第二步、CarMapper.xml





    

第三步、运行测试类

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.junit.Test;

public class CarMapperTest {

    @Test
    public void testSelectById(){
        CarMapper mapper = SqlSessionUtil.openSession().getMapper(CarMapper.class);
        Car car = mapper.selectById(10L);
        System.out.println(car);
    }
}

第四步、执行结果

MyBatis(十一)、MyBatis查询语句专题_第3张图片

 查询结果是一条的话可以使用List集合接收吗?当然可以

第一步、CarMapper接口

/**
* 根据id主键查询:结果最多只有一条,可以放到List集合中吗?
* @return
*/
List selectByIdToList(Long id);

第二步、CarMapper.xml

第三步、运行测试类

@Test
public void testSelectByIdToList(){
    CarMapper mapper = SqlSessionUtil.openSession().getMapper(CarMapper.class);
    List cars = mapper.selectByIdToList(9L);
    System.out.println(cars);
}

第四步、执行结果

MyBatis(十一)、MyBatis查询语句专题_第4张图片

二、返回List

当查询的记录条数是多条的时候,必须使用集合接收。如果使用单个实体类接收会出现异常。

第一步、CarMapper接口

/**
* 查询所有的Car
* @return
*/
List selectAll();

第二步、CarMapper.xml

第三步、运行测试类方法

@Test
public void testSelectAll(){
    CarMapper mapper = SqlSessionUtil.openSession().getMapper(CarMapper.class);
    List cars = mapper.selectAll();
    cars.forEach(car -> System.out.println(car));
}

第四步、查看执行结果

MyBatis(十一)、MyBatis查询语句专题_第5张图片

如果返回多条记录,采用单个实体类接收会怎样?

第一步、CarMapper接口

/**
* 查询多条记录,采用单个实体类接收会怎样?
* @return
*/
Car selectAll2();

第二步、CarMapper.xml

第三步、运行测试类方法

@Test
public void testSelectAll2(){
    CarMapper mapper = SqlSessionUtil.openSession().getMapper(CarMapper.class);
    Car car = mapper.selectAll2();
    System.out.println(car);
}

第四步、查看执行结果

MyBatis(十一)、MyBatis查询语句专题_第6张图片三、返回Map

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

查询如果可以保证只有一条数据,则返回一个Map集合即可。

MyBatis(十一)、MyBatis查询语句专题_第7张图片

 第一步、CarMapper接口

/**
 * 通过id查询一条记录,返回Map集合
 * @param id
 * @return
 */
Map selectByIdRetMap(Long id);

第二步、CarMapper.xml

resultMap="map",这是因为mybatis内置了很多别名。【参见mybatis开发手册】

第三步、运行测试类方法

@Test
public void testSelectByIdRetMap(){
    CarMapper mapper = SqlSessionUtil.openSession().getMapper(CarMapper.class);
    Map car = mapper.selectByIdRetMap(31L);
    System.out.println(car);
}

第四步、查看执行结果

 MyBatis(十一)、MyBatis查询语句专题_第8张图片

当然,如果返回一个Map集合,可以将Map集合放到List集合中吗?当然可以,这里就不再测试了。

反过来,如果返回的不是一条记录,是多条记录的话,只采用单个Map集合接收,这样同样会出现之前的异常:TooManyResultsException

四、List

查询结果条数大于等于1条数据,则可以返回一个存储Map集合的List集合。List等同于List

MyBatis(十一)、MyBatis查询语句专题_第9张图片

第一步、CarMapper接口

/**
     * 查询所有的Car,返回一个List集合。List集合中存储的是Map集合。
     * @return
     */
List> selectAllRetListMap();

第二步、CarMapper.xml

第三步、运行测试类方法

@Test
public void testSelectAllRetListMap(){
    CarMapper mapper = SqlSessionUtil.openSession().getMapper(CarMapper.class);
    List> cars = mapper.selectAllRetListMap();
    System.out.println(cars);
}

第四步、 查看执行结果

 MyBatis(十一)、MyBatis查询语句专题_第10张图片

 五、返回Map

拿Car的id做key,以后取出对应的Map集合时更方便

MyBatis(十一)、MyBatis查询语句专题_第11张图片

第一步、CarMapper接口

/**
     * 获取所有的Car,返回一个Map集合。
     * Map集合的key是Car的id。
     * Map集合的value是对应Car。
     * @return
     */
@MapKey("id")
Map> selectAllRetMap();

第二步、CarMapper.xml

第三步、运行测试类方法

@Test
public void testSelectAllRetMap(){
    CarMapper mapper = SqlSessionUtil.openSession().getMapper(CarMapper.class);
    Map> cars = mapper.selectAllRetMap();
    System.out.println(cars);
}

第四步、 查看执行结果

 MyBatis(十一)、MyBatis查询语句专题_第12张图片

六、resultMap结果映射

查询结果的列名和java对象的属性名对应不上怎么办?

  • 第一种方式:as 给列起别名
  • 第二种方式:使用resultMap进行结果映射
  • 第三种方式:是否开启驼峰命名自动映射(配置settings)

之前用的第一种方式,现在介绍一下第二和第三种方式

使用resultMap进行结果映射

第一步、CarMapper接口

/**
     * 查询所有Car,使用resultMap进行结果映射
     * @return
     */
List selectAllByResultMap();

第二步、CarMapper.xml



  
  
  
  
  
  
  
  
  



第三步、运行测试类方法

@Test
public void testSelectAllByResultMap(){
    CarMapper carMapper = SqlSessionUtil.openSession().getMapper(CarMapper.class);
    List cars = carMapper.selectAllByResultMap();
    System.out.println(cars);
}

第四步、查看执行结果

MyBatis(十一)、MyBatis查询语句专题_第13张图片

执行结果正常。 

是否开启驼峰命名自动映射

使用这种方式的前提是:属性名遵循Java的命名规范,数据库表的列名遵循SQL的命名规范。

Java命名规范:首字母小写,后面每个单词首字母大写,遵循驼峰命名方式。

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

比如以下的对应关系:

实体类中的属性名

数据库表的列名

carNum

car_num

carType

car_type

produceTime

produce_time

 如何启用该功能,在mybatis-config.xml文件中进行配置:



  

第一步、CarMapper接口

/**
* 查询所有Car,启用驼峰命名自动映射
* @return
*/
List selectAllByMapUnderscoreToCamelCase();

第二步、CarMapper.xml配置文件

第三步、运行测试类方法

@Test
public void testSelectAllByMapUnderscoreToCamelCase(){
    CarMapper carMapper = SqlSessionUtil.openSession().getMapper(CarMapper.class);
    List cars = carMapper.selectAllByMapUnderscoreToCamelCase();
    System.out.println(cars);
}

第四步、查看执行结果

MyBatis(十一)、MyBatis查询语句专题_第14张图片

执行结果正常。 

七、返回总记录条数

需求:查询总记录条数

第一步、CarMapper接口

/**
     * 获取总记录条数
     * @return
     */
Long selectTotal();

第二步、carMapper.xml


第三步、运行测试类方法

@Test
public void testSelectTotal(){
    CarMapper carMapper = SqlSessionUtil.openSession().getMapper(CarMapper.class);
    Long total = carMapper.selectTotal();
    System.out.println(total);
}

第四步、查看执行结果

MyBatis(十一)、MyBatis查询语句专题_第15张图片

你可能感兴趣的:(mybatis,java,开发语言)