mybatis中的一个异常,异常信息及代码如下?

`
Caused by: org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 15

at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:66)
at sun.reflect.GeneratedMethodAccessor67.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:354)
... 76 more

`根据错误提示是说本应通过selectOne这个方法返回一个结果或是空值,但是却找到了15个结果

网上搜,有的说是返回结果应该改为list集合类型,有的说检查Mybatis配置文件中返回的结果类型与Java中返回类型是否一致,检查传递参数的个数,可是我发现这些办法在我这里并不适用

相关代码如下:

mybatis的映射文件:

<!-- 通过ID获取数据 -->
    <select id="findById" parameterType="pd" resultType="pd">
        select 
        <include refid="Field"></include>
        from 
        <include refid="tableName"></include>
        <where>
            <if test="KWORDS_ID!= null and KWORDS_ID != ''">
                KWORDS_ID = #{KWORDS_ID}
            </if>
            <if test="KWORDID!= null and KWORDID != ''">
                and KWORDID = #{KWORDID}
            </if>
            <if test="KWORDNAME!= null and KWORDNAME != ''">
                and KWORDNAME = #{KWORDNAME}
            </if>
            <if test="KWORDNAME!=null and KWORDNAME !=''">
                and PARENTID = #{PARENTID}
            </if>
        </where>
    </select>

接口:

/**通过id获取数据
     * @param pd
     * @throws Exception
     */
    public PageData findById(PageData pd)throws Exception;

实现类:

    /**通过id获取数据
     * @param pd
     * @throws Exception
     */
    public PageData findById(PageData pd)throws Exception{
        return (PageData)dao.findForObject("KwordsMapper.findById", pd);
    }

其中findForObject返回的就是select One

public Object findForObject(String str, Object obj) throws Exception {
        return sqlSessionTemplate.selectOne(str, obj);
    }

Controller:

/**
     * 校验父类下唯一的代码和名字
     * @return
     * @throws Exception
     */
    @RequestMapping(value="/validate")
    @ResponseBody
    public Object validateKwords() throws Exception {
        PageData pd = new PageData();        
        Map<String,Object> map = new HashMap<String,Object>();
        pd = this.getPageData();
        if (kwordsService.findById(pd)!=null) {
            map.put("msg", "true");
        }else{
            map.put("msg", "false");
        }
        return AppUtil.returnObject(pd, map);
    }
阅读 12k
5 个回答

图片描述

看一下,是不是这个地方写的有问题,导致你的sql查询结果返回多条了。。

你的Sql查询出来多条了,应该使用List<PageData>

SelectOne底层调用的也是SelectList,你的Sql有可能返回多条数据的啊。

SqlSessionTemplate.selectOne实际代码:

public <T> T selectOne(String statement, Object parameter) {
    // Popular vote was to return null on 0 results and throw exception on too many.
    List<T> list = this.<T>selectList(statement, parameter);
    if (list.size() == 1) {
      return list.get(0);
    } else if (list.size() > 1) {
      throw new TooManyResultsException("Expected one result (or null) to be returned by selectOne(), but found: " + list.size());
    } else {
      return null;
    }
  }

很显然:KwordsMapper.findById 这个方法返回的不只有一条数据,所以会抛出TooManyResultsException,既然要findById,就要保证这个方法一定只有一条数据,修改一下这个sql吧,

 <select id="findById" parameterType="pd" resultType="pd">
...

或者使用SqlSessionTemplate.selectList也是可以的。

要么select语句加上limit 1

要么保证查询结果只有一条(即使用唯一性字段进行查询)

报错原因应该就是你告诉java要返回PageData 但是mybatis返回了List<PageData>.
你可以在控制台把报错的那个sql语句黏贴到数据库,查询看看到底是哪个查询条件错了

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题