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

  • Post author:
  • Post category:其他


在使用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());  

输出:

报错信息



版权声明:本文为wjw465150原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。