1.异常背景
使用了mybatis-plus的Wrapper进行查询条件构造,确实很爽,但这次需要自己写sql,为了复用Wrapper,我做了如下操作
- mapper类里增加方法,对应自定义sql,参数使用QueryWrapper
@Mapper
public interface OrderMapper extends BaseMapper<OrderEntity> {
OrderStatisticsDto statistics(QueryWrapper<OrderEntity> queryWrapper);
}
- mapper.xml加入${ew.customSqlSegment},即使用了QueryWrapper构造出来的条件
<select id="statistics" resultType="com.example.mybatisplusdemo.dto.OrderStatisticsDto">
select count(id) as orderCount, sum(price) as totalPrice
from mpd_order
${ew.customSqlSegment}
</select>
然后执行查询就报了下面的异常
org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'ew' in 'class com.baomidou.mybatisplus.core.conditions.query.QueryWrapper'
at org.apache.ibatis.reflection.Reflector.getGetInvoker(Reflector.java:395) ~[mybatis-3.5.0.jar:3.5.0]
at org.apache.ibatis.reflection.MetaClass.getGetInvoker(MetaClass.java:163) ~[mybatis-3.5.0.jar:3.5.0]
......
2.解决方法
在mapper的方法参数指定参数名字 @Param(Constants.WRAPPER)
Constants.WRAPPER = " ew "
@Mapper
public interface OrderMapper extends BaseMapper<OrderEntity> {
OrderStatisticsDto statistics(@Param(Constants.WRAPPER) QueryWrapper<OrderEntity> queryWrapper);
}
3.原因探究
异常说的是在QueryWrapper里没有【ew】这个参数的getter方法
- 在mapper对象的方法中如果参数QueryWrapper没有使用@Param注解
那么mybatis会把xml文件中的参数名当作是QueryWrapper里的属性名- 如果有加@Param注解,指定参数别名
那么mybatis会把xml文件中的参数名当作是QueryWrapper的别名
而我们是想在xml中要得到QueryWrapper的属性【customSqlSegment】
3.1.尝试1
既然是要customSqlSegment属性,那直接改成
<select id="statistics" resultType="com.example.mybatisplusdemo.dto.OrderStatisticsDto">
select count(id) as orderCount, sum(price) as totalPrice
from mpd_order
${customSqlSegment}
</select>
把customSqlSegment前的ew去掉
结果还是报上面一样的错
3.2.尝试2
那就加上@Param吧,不过参数别名不用" ew " ,用 " query "
@Mapper
public interface OrderMapper extends BaseMapper<OrderEntity> {
OrderStatisticsDto statistics(@Param("query") QueryWrapper<OrderEntity> queryWrapper);
}
<select id="statistics" resultType="com.example.mybatisplusdemo.dto.OrderStatisticsDto">
select count(id) as orderCount, sum(price) as totalPrice
from mpd_order
${query.customSqlSegment}
</select>
结果报了另外一个错
org.apache.ibatis.binding.BindingException: Parameter 'ew' not found. Available parameters are [query, param1]
at org.apache.ibatis.binding.MapperMethod$ParamMap.get(MapperMethod.java:209) ~[mybatis-3.5.0.jar:3.5.0]
at org.apache.ibatis.reflection.wrapper.MapWrapper.get(MapWrapper.java:45) ~[mybatis-3.5.0.jar:3.5.0]
...
说的还是关于ew这参数的错
3.3.结论
如果使用QueryWrapper与xml自定义sql相结合,那么一定要加@Param,且参数别名只能指定 " ew "
- 因为在QueryWrapper构造【customSqlSegment】的过程中,自动使用了 " ew " 作为它的参数别名
所以只能顺势而为
至于为什么尝试1和尝试2报的异常不一样
那是因为mybatis在做入参映射的时候,使用的wrapper不同,具体本文不深究了
- 尝试1没有@Param注解,使用了BeanWrapper
- 尝试2有@Param注解,使用了MapWrapper