MyBatisPlus使用LambdaQueryWrapper时要注意防止出现“Didn‘t start with ‘is‘, ‘get‘ or ‘set‘“错误

在使用LambdaQueryWrapper的条件方法时,里面的函数式接口SFunction参数不能使用Lambda表达式而必需使用方法引用.否则会报
Error parsing property name 'lambda$1'. Didn't start with 'is', 'get' or 'set'. 的错误!

请先看下面的测试,原因后面会讲.

错误代码(传入了Lambda表达式):

  @Test
  public void testSelectUseLamda2() {
    LambdaQueryWrapper<BfsNota1001> wrapper=new LambdaQueryWrapper<>();
    wrapper.eq(it -> {
      return it.getfMsgtype();
    }, "1001");
    
    BfsNota1001 b1001 = b1001Mapper.selectOne(wrapper);
    System.out.println(b1001);
  }

会报错:

org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.builder.BuilderException: Error evaluating expression 'ew.sqlSegment != null and ew.sqlSegment != '' and ew.nonEmptyOfWhere'. Cause: org.apache.ibatis.ognl.OgnlException: sqlSegment [org.apache.ibatis.reflection.ReflectionException: Error parsing property name 'lambda$1'.  Didn't start with 'is', 'get' or 'set'.]
	at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:96)
	at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:441)
	at com.sun.proxy.$Proxy59.selectList(Unknown Source)
	at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:224)
	at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.executeForMany(MybatisMapperMethod.java:166)
	at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.execute(MybatisMapperMethod.java:77)
	at com.baomidou.mybatisplus.core.override.MybatisMapperProxy$PlainMethodInvoker.invoke(MybatisMapperProxy.java:148)
	at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.invoke(MybatisMapperProxy.java:89)
	at com.sun.proxy.$Proxy74.selectList(Unknown Source)
	at com.baomidou.mybatisplus.core.mapper.BaseMapper.selectOne(BaseMapper.java:173)
	at java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:627)
	at com.baomidou.mybatisplus.core.override.MybatisMapperProxy$DefaultMethodInvoker.invoke(MybatisMapperProxy.java:162)
	at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.invoke(MybatisMapperProxy.java:89)
	at com.sun.proxy.$Proxy74.selectOne(Unknown Source)
	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)
    ......

正确的代码(传入了方法引用):

  @Test
  public void testSelectUseLamda2() {
    LambdaQueryWrapper<BfsNota1001> wrapper=new LambdaQueryWrapper<>();
    wrapper.eq(BfsNota1001::getfMsgtype, "1001");
    
    BfsNota1001 b1001 = b1001Mapper.selectOne(wrapper);
    System.out.println(b1001);
  }

原因解析:

MyBatisPlus的条件构造器不会真的去调用SFunction这个函数式接口而是只解析实际的方法名.如果解析的是Lambbda表达式,那么方法名跟数据库的列名匹配不上就会报错; 如果是方法引用那么方法名通过is/gey/set规则就能找到相应的字段名然后在根据规则转换成数据库表的列名.

💊注意: 如果字段名和列名不符合缺省的转换规则,那么必需在字段名上加上@TableField("列名")注解来明确表明实际的列名.

LambdaMeta的小测试:

可以查看com.baomidou.mybatisplus.core.toolkit.LambdaUtils 类和 com.baomidou.mybatisplus.core.toolkit.support.LambdaMeta 接口

方法引用

SFunction<FileEntity, String> getAppId = FileEntity::getAppId;
LambdaMeta extract = LambdaUtils.extract(getAppId);
System.out.println(extract.getImplMethodName());

输出: getAppId

Lambbda表达式

 LambdaMeta extract2 = LambdaUtils.extract((SFunction<FileEntity, String>) fileEntity -> fileEntity.getAppId());
 System.out.println(extract2.getImplMethodName());

输出: lambda$contextLoads$7d1c9855$1

匿名类

LambdaMeta extract23= LambdaUtils.extract(new SFunction<FileEntity, String>() {
    @Override
    public String apply(FileEntity object) {
      return object.getAppId();
    }
});
System.out.println(extract2.getImplMethodName());  

输出: 报错信息

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

爱游泳的老白

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

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

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

打赏作者

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

抵扣说明:

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

余额充值