关于Mybatis的错误Statement returned more than one row, where no more than one was expected

项目场景:

SpringMVC项目,关于mybatis一对多关联查询的问题。

问题描述:

错误提示: Statement returned more than one row, where no more than one was expected

mn.java:

public class Mn {
    private int m;
    private int n;
    
    @Override
    public String toString() {
        return "Mn{" +
                "m=" + m +
                ", n=" + n +
                '}';
    }
}

xyz.java:

@Repository
public class Xyz {
    private String x;
    private String y;
    private String z;
    private List<Mn> mns;

    @Override
    public String toString() {
        return "Xyz{" +
                "x='" + x + '\'' +
                ", y='" + y + '\'' +
                ", z='" + z + '\'' +
                ", mn=" + mns +
                '}';
    }
}

daomapper.java:

@Results({
            @Result(property = "x" ,column = "x"),
            @Result(property = "y" ,column = "y"),
            @Result(property = "z" ,column = "z"),
            @Result(
                    property = "mns",
                    column = "x",
                    javaType = Mn.class,
                    many = @Many(select ="package1.mapper.DaoMapper.getMn" )
            )
    })
    @Select("select * from xyz where x=${k}")
    List<Xyz> daoSelect1(int k);

@Results(id = "mnMap",
            value = {
            @Result(property = "m" , column = "m"),
            @Result(property = "n" , column = "n")
    })
    @Select("select * from mn where m=${m}")
    List<Mn> getMn(int m);

测试类:

public class MybatisTest {
    private DaoMapper daoMapper;
    @Before
    public void initMapper() throws IOException {
        InputStream inputStream=Resources.getResourceAsStream("mybatisConfig.xml");
        SqlSession sqlSession=new SqlSessionFactoryBuilder().build(inputStream).openSession();
        daoMapper =sqlSession.getMapper(DaoMapper.class);
    }

    @Test
    public void mybatistest1() throws IOException {
        List<Xyz> xyzs = daoMapper.daoSelect1(2);
        for(Xyz x:xyzs ){
            System.out.println(x.toString());
        }
    }
}

控制台:

Created connection 1541708640.
Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@5be49b60]
==>  Preparing: select * from xyz where x=2
==> Parameters: 
<==    Columns: x, y, z
<==        Row: 2, 1, 44
====>  Preparing: select * from mn where m=2
====> Parameters: 
<====    Columns: m, n
<====        Row: 2, 2222
<====        Row: 2, 3333
<====      Total: 2

org.apache.ibatis.exceptions.PersistenceException: 
### Error querying database.  Cause: org.apache.ibatis.executor.ExecutorException: Statement returned more than one row, where no more than one was expected.
### The error may exist in package1/mapper/DaoMapper.java (best guess)
### The error may involve package1.mapper.DaoMapper.getMn
### The error occurred while handling results
### SQL: select * from mn where m=2
### Cause: org.apache.ibatis.executor.ExecutorException: Statement returned more than one row, where no more than one was expected.
......

原因分析以及解决方案:

错误报告显示应该返回一条数据,但是却返回了多条数据。这就比较迷惑了,对于xyz类中的mns,我的期望就是返回多条数据。

网上找了很久都没找到解决办法,后来我自己又仔细检查了代码,发现是一个很小的问题

javaType = Mn.class

我的xyz类中的mns是ListMn类型,但是这里写的是Mn类型。
把这句代码删掉,运行测试类,成功!

Created connection 1541708640.
Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@5be49b60]
==>  Preparing: select * from xyz where x=2
==> Parameters: 
<==    Columns: x, y, z
<==        Row: 2, 1, 44
====>  Preparing: select * from mn where m=2
====> Parameters: 
<====    Columns: m, n
<====        Row: 2, 2222
<====        Row: 2, 3333
<====      Total: 2
<==      Total: 1
Xyz{x='2', y='1', z='44', mn=[Mn{m=2, n=2222}, Mn{m=2, n=3333}]}

Process finished with exit code 0

一些意外收获:
在检查代码过程中,我偶然发现,注解@One和@Many的功能其实是一样的,刚开始我以为是巧合,但是我查看了源码,发现@One和@Many的源码也是一样的。我猜测,出现@one和@Many两种注解只是为了增加代码可读性。
我查看了mybatis的文档,有了以下的发现:

不管是一对一关联查询还是一对多关联查询:

  • 都可以用@One或者@Many注解,二者效果一样。
  • 如果映射到一个 JavaBean,还可以省略javaType属性,因为mybatis可以推断类型。但如果映射到的是 HashMap,那么应该指定javaType的属性。
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值