mybatis查询mysql结果的null和N/A引起的异常问题排查

背景:

        今天线上环境突发意外情况,昨天还好好的页面,突然少了两个模块,经检查发现查询结果是正常结果,但是返回数据格式却与预想的不一致,返回结果

{
    "success": true,
    "code": 200,
    "msg": null,
    "data": [
        null
    ]
}

预想中的查询结果为空时,data字段应该是一个空的数据,但是返回结果中却出现了一个空对象,数据连接层使用mybatis框架,所以怀疑mybatis做了一些转换,就转换了一下sql查询方式发现同样的sql查询不同的字段值时返回的格式会有区别,在navicat中执行sql发现查询结果还是有区别的。

返回null对象的sql为:

 SELECT SUM(media.read_count) as `count`,media.*,temp.*,channel.*
        FROM tableName media
        ORDER BY `count` desc

在Navicat执行结果为:

SELECT * FROM tableName media temp.maxDay=media.`day` ;

查询结果为:

仔细看一下会发现,查询结果仍是有区别的

  • NULL是指某个字段没有值
  • N/A是指结果集为空,是没有数据输出的。

所以当查询结果为NULL时,经过mybatis转换后便是一个null对象,返回N/A时,表示没有结果,返回的结果就是一个空的数组。

仔细观察两个sql会发现,使用聚合函数sum时返回结果就是null,查询结果为单独列时,就会返回N/A。

延伸拓展:

N/A是指结果集为空,是没有数据输出的;

NULL是指某个字段没有值;

空值一般指空字符串。

null和空值的区别:

相同点:

        null和空值都代表有数据输出。

不同点:

1、内存区别
        空值(‘’)的长度是0,是不占用空间的;
        而的NULL长度是NULL,其实它是占用空间的。

2、查询的区别
        查询null:使用函数isnull,注意isnull有不同形式
        查询空值:则使用=’ ',两个引号中间是没有空格的

3、统计的区别
        count(字段),若该字段在某一行的值为NULL,则该行不会被统计;
        若该字段在某一行的值为空值,该行会被统计
        count( * ):NULL会被统计。

<think>我们正在处理关于Spring Boot使用MyBatis进行分页查询结果列表为null问题。根据提供的引用,我们知道MyBatis Plus提供了分页功能(引用[1][2]),而引用[3]提到了Spring Boot集成MyBatis实现分页查询(使用了PageHelper)。但是用户的问题中同时提到了MyBatisMyBatis Plus,因此我们需要区分。 用户问题结果列表显示为null。这通常意味着查询没有返回任何数据,或者分页配置不正确导致数据无法正确映射。 可能的原因及解决方案: 1. **分页插件未正确配置**:无论是MyBatis原生分页(如PageHelper)还是MyBatis Plus的分页插件,都需要配置拦截器。 2. **查询条件问题**:可能查询条件过严,导致没有匹配的数据。 3. **SQL语句问题**:SQL语句可能有误,或者分页参数传递不正确。 4. **返回类型映射问题**:结果集映射到实体类失败,可能因为字段名不匹配等原因。 根据引用[2],使用MyBatis Plus的分页步骤是: - 创建Page对象 - 调用selectPage方法 - 从返回的Page对象中获取记录列表总数 引用[3]则使用了PageHelper(MyBatis原生的分页插件)的方式。 因此,我们需要区分用户使用的是MyBatis Plus还是MyBatis(使用PageHelper)。由于用户同时提到了MyBatisMyBatis Plus,我们需要考虑两种情况。 但是,用户的问题描述中并没有明确说明使用的是哪一个,所以我们将分别讨论。 **情况一:使用MyBatis Plus** 步骤: 1. 确保已经配置了MyBatis Plus的分页插件。 在Spring Boot配置类中添加: ```java @Configuration public class MybatisPlusConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; } } ``` 2. 检查Service或Controller中的分页代码是否正确。 如引用[2]所示: ```java Page<User> page = new Page<>(1, 10); // 第一页,每页10条 Page<User> userPage = userMapper.selectPage(page, null); List<User> users = userPage.getRecords(); // 这里如果为null,可能是查询结果 ``` 如果`userPage.getRecords()`为null,首先检查数据库是否有数据,然后检查查询条件(第二个参数是Wrapper,如果为null查询所有)。 3. 检查SQL日志,看是否执行了正确的SQL语句,以及是否有异常。 **情况二:使用MyBatis + PageHelper** 步骤: 1. 确保已经配置了PageHelper插件(如引用[3]提到的配置方式)。 在配置类中(或者入口类)配置PageHelper: ```java @Configuration public class MyBatisConfig { @Bean public PageInterceptor pageInterceptor() { return new PageInterceptor(); } } ``` 或者使用配置文件配置(如application.properties): ```properties pagehelper.helperDialect=mysql ``` 2. 在查询方法前调用PageHelper.startPage方法,并且紧随其后执行查询: ```java PageHelper.startPage(1, 10); // 页码,每页数量 List<User> users = userMapper.selectUsers(); // 假设这是你的查询方法 PageInfo<User> pageInfo = new PageInfo<>(users); ``` 注意:PageHelper.startPage方法后必须紧跟一个查询语句,否则可能会失效。 3. 如果查询结果(users)为null,那么可能是数据库查询返回了null,需要检查Mapper的SQL语句映射。 **通用排查步骤:** 1. **检查数据库连接SQL语句**:确保数据库连接正常,且SQL语句查询到数据(可以在数据库客户端执行相同的SQL)。 2. **检查日志**:开启MyBatisSQL日志(在application.properties中设置`logging.level.你的Mapper包路径=DEBUG`),观察实际执行SQL语句以及返回结果。 3. **检查实体类映射**:确保数据库字段实体类属性能够正确映射(比如字段名是否一致,或者使用了正确的ResultMap)。 4. **检查分页参数**:页码每页数量是否合理(比如页码从1开始,如果传入0可能会出错)。 如果以上步骤都检查无误,但仍然得到null,可以考虑是否是其他配置问题,例如事务配置等。 最后,根据用户提供的引用,我们重点参考了引用[2](MyBatis Plus)引用[3](PageHelper)的配置用法。用户需要根据自己的实际使用情况来排查。 由于用户没有提供具体的代码,我们只能给出一般性的解决方案。 相关问题: 1. 如何配置MyBatis Plus的分页插件? 2. 使用PageHelper分页时需要注意哪些问题? 3. MyBatis如何开启SQL语句日志? 4. MyBatis结果集映射失败的可能原因有哪些? </think>### Spring Boot使用MyBatis分页查询结果列表为null的解决方案 当使用Spring Boot集成MyBatis进行分页查询时,若结果列表显示为`null`,通常由以下原因导致。以下是详细排查步骤及解决方案: --- #### 1. **分页插件未正确配置**(最常见原因) MyBatis的分页功能需要插件支持: - **MyBatis Plus**:需添加分页拦截器 ```java @Configuration public class MyBatisPlusConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); // 添加分页拦截器 interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; } } ``` - **PageHelper**:需在启动类配置 ```java @SpringBootApplication @MapperScan("com.example.mapper") public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Bean public PageInterceptor pageInterceptor() { return new PageInterceptor(); // PageHelper拦截器 } } ``` > 未配置分页插件会导致分页参数无法生效[^2][^3]。 --- #### 2. **Mapper方法调用错误** - **MyBatis Plus**:必须使用`selectPage()`方法 错误示例: ```java List<User> users = userMapper.selectList(null); // 返回普通List ``` 正确写法: ```java Page<User> page = new Page<>(1, 10); // 第1页,每页10条 Page<User> result = userMapper.selectPage(page, null); // 返回Page对象 List<User> users = result.getRecords(); // 此处获取列表 ``` > 错误的方法调用会导致分页数据丢失[^2]。 - **PageHelper**:必须紧跟查询语句 正确调用顺序: ```java PageHelper.startPage(1, 10); // 必须在查询前调用 List<User> users = userMapper.selectAll(); // 自动分页 ``` --- #### 3. **SQL映射问题** 检查XML映射文件: ```xml <!-- 返回值必须是resultType/resultMap --> <select id="selectUsers" resultType="com.example.User"> SELECT * FROM user </select> ``` 常见问题: - 返回值设为`void` - 字段名与实体类属性不匹配(如数据库`user_name` vs 实体类`userName`) - 未定义`resultMap`映射关系 --- #### 4. **分页参数错误** - 页码从**1开始**(非0) - 超出最大页数时返回列表 建议添加校验: ```java if(page.getCurrent() > page.getPages()) { throw new RuntimeException("页码超出范围"); } ``` --- #### 5. **日志排查** 在`application.properties`中开启SQL日志: ```properties # MyBatis SQL日志 logging.level.com.example.mapper=DEBUG # MyBatis Plus日志 mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl ``` 检查日志是否包含分页参数: ```sql -- 正常分页日志应包含LIMIT SELECT * FROM user LIMIT 0,10 ``` --- #### 完整修复流程: 1. 确认分页插件已配置 ✅ 2. 检查Mapper方法返回类型 ✅ 3. 验证XML映射文件 ✅ 4. 查看SQL日志确认分页参数 ✅ 5. 检查页码有效性 ✅ > 按此流程排查后,90%的分页结果null问题可解决[^1][^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值