mybatis plus分页查询报错Expected one result (or null) to be returned by selectOne(), but found: 10

mybatis plus分页查询报错Expected one result (or null) to be returned by selectOne(), but found: 10

报错信息

org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 10

	at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:77)
	at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:446)
	at com.sun.proxy.$Proxy197.selectOne(Unknown Source)
	at org.mybatis.spring.SqlSessionTemplate.selectOne(SqlSessionTemplate.java:166)
	at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.execute(MybatisMapperMethod.java:89)
	at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.invoke(MybatisMapperProxy.java:62)
	at com.sun.proxy.$Proxy343.queryInspectOrderList(Unknown Source)
	at com.sffix.recovery.storage.test.InspectControllerTest.test1(InspectControllerTest.java:51)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)

mapper定义

    /**
     * 查询审单统计列表
     * @param vo
     * @return
     */
    Page<UpDoorInspectionVO> queryInspectOrderList(@Param("vo") UpDoorInspectionSearchVO vo,@Param("page")  IPage<UpDoorInspectionVO> page);

在这里插入图片描述

单元测试

    @Test
    public void test1(){
        Page<UpDoorInspectionVO> page = new Page<>();
        Page<UpDoorInspectionVO> upDoorInspectionVOIPage = recycleUpDoorInspectionsMapper.queryInspectOrderList(new UpDoorInspectionSearchVO(), page);
        System.out.println(upDoorInspectionVOIPage.getRecords());
    }

问题分析:

从报错栈去打开mybatis plus源码debug便知,在决定是否为分页时,判定条件里有第一个参数是否为IPage的实现类。
在这里插入图片描述

解决办法:

把IPage参数放在第一个参数位置就好了

<think>好的,我现在需要解决用户在MyBatis中一对多映射时使用selectOne()方法返回多个结果导致的错误。错误信息是“Expected one result (or null) to be returned by selectOne(), but found: 3”。首先,我需要理解这个问题的根本原因。 根据用户提供的引用[1],selectOne方法内部其实是调用了selectList,然后检查结果数量。如果结果超过一个,就会抛出异常。这说明当用户使用selectOne时,期望查询返回0或1条记录,但实际返回了3条,所以报错了。 接下来,用户的问题出现在一对多映射的情况下。通常,一对多映射会在resultMap中使用<collection>标签来关联多个子记录。例如,一个订单对应多个订单项。用户可能在查询时,虽然主表(如订单)只有一条记录,但子表(订单项)有多条记录,导致MyBatis在处理结果集时,主记录被多次组合,从而生成了多个主对象? 不过,这种情况似乎不太可能导致selectOne报错,因为主查询本身应该只返回一条主记录,即使有多个子记录。可能用户是在某个关联查询中,主查询本身返回了多条记录。比如,在JOIN查询中,如果没有正确去重,可能会返回多条主记录,从而导致selectOne报错。 另外,用户可能错误地在应该返回多个结果的情况下使用了selectOne方法。例如,他们可能预期某个条件只会匹配一条记录,但实际数据库中存在多条符合条件的数据。 解决方案可能包括: 1. 检查SQL语句,确保主查询只返回一条记录。可以通过添加LIMIT 1或者更精确的WHERE条件来限制结果数量。 2. 使用selectList代替selectOne,并在代码中处理结果,比如取第一个元素或者检查数量。 3. 在MyBatis的XML映射文件中,确保resultMap正确配置了一对多关系,避免因为JOIN导致的多条结果被误认为多条主记录。 另外,引用[3]提到MyBatis在处理结果集时,会为每个结果创建对象,并填充属性。如果主键重复,MyBatis可能无法正确合并结果,导致生成多个主对象。这时候需要确保结果集的主键是唯一的,或者在resultMap中配置合适的id元素来帮助MyBatis识别唯一主记录。 例如,假设用户的查询涉及到两个表的JOIN,返回了三条记录,但主表的主键在这三条记录中是相同的,但由于JOIN导致结果集有重复的主键记录,MyBatis在映射时可能会生成三个主对象,而实际上应该合并为一个,并收集所有的子记录。这时候需要检查resultMap是否配置了<id>标签,以便MyBatis能正确识别主键,合并重复的记录。 总结可能的解决步骤: 1. 确保SQL查询本身返回的主记录数量为1。可以通过日志查看实际执行的SQL和返回的结果数量。 2. 如果主记录确实可能返回多条,应改用selectList,并在代码中处理。 3. 检查resultMap的配置,确保主对象的id字段正确配置,避免因结果集重复导致MyBatis生成多个对象。 4. 在查询中添加必要的条件或限制,确保只返回一条主记录。 例如,用户可能在查询中使用了LEFT JOIN,但由于关联条件不准确,导致主记录重复出现。这时候需要调整JOIN条件或者在查询中使用DISTINCT关键字。 最后,用户需要确保在可能返回多个结果的查询中不使用selectOne方法,或者在数据库层面通过约束确保查询条件的唯一性。</think>### 问题分析 当MyBatis的`selectOne()`方法返回多个结果时,通常是因为以下原因: 1. **查询条件不唯一**:SQL语句未正确限制结果数量,导致返回多条数据[^1]。 2. **一对多映射配置错误**:主表与子表关联时,JOIN操作可能生成重复的主记录,但未正确合并结果。 3. **未正确处理结果集**:`resultMap`配置中缺少主键(`<id>`)定义,导致MyBatis无法识别唯一对象。 --- ### 解决方案 #### 1. **确保SQL查询返回唯一结果** - 在SQL中添加限制条件(如`LIMIT 1`)或优化查询逻辑: ```sql SELECT * FROM user WHERE id = #{id} LIMIT 1 ``` - 检查WHERE条件是否唯一(如使用主键或唯一索引字段)。 #### 2. **改用selectList方法** 若结果可能为多个,应在Mapper接口中使用`selectList`,并在代码中处理结果数量: ```java List<User> users = sqlSession.selectList("selectUsers", params); if (users.size() > 1) { throw new TooManyResultsException(); } return users.get(0); ``` #### 3. **正确配置resultMap** 在一对多映射中,需通过`<id>`标签标识主键,帮助MyBatis合并重复的主记录: ```xml <resultMap id="userWithOrdersMap" type="User"> <id property="id" column="user_id"/> <!-- 关键:定义主键 --> <collection property="orders" ofType="Order"> <id property="orderId" column="order_id"/> </collection> </resultMap> ``` #### 4. **检查JOIN查询的去重** 若使用JOIN导致主记录重复,可通过以下方式解决: - 添加`DISTINCT`关键字: ```sql SELECT DISTINCT u.*, o.* FROM user u LEFT JOIN orders o ON u.id = o.user_id ``` - 使用子查询分离主表和子表查询。 --- ### 示例配置 ```xml <!-- 正确的一对多映射配置 --> <select id="selectUserWithOrders" resultMap="userWithOrdersMap"> SELECT u.id AS user_id, o.id AS order_id FROM user u LEFT JOIN orders o ON u.id = o.user_id WHERE u.id = #{id} </select> ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HumorChen99

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值