在使用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());
输出: 报错信息
|