MyBatis多参数传递之@Param究竟加还是不加? | 您所在的位置:网站首页 › mybatis接受多个参数 › MyBatis多参数传递之@Param究竟加还是不加? |
List getDeviceListTest(@Param("deviceId")String deviceId,@Param("deviceName")String deviceName);
3.XML 中的 SQL 使用了 $ ,那么参数中也需要 @Param 注解,$ 会有注入漏洞的问题,但是有的时候你必须要 $ 符号,例如要传入列名或者表名的时候,这个时候必须要 //mapper 接口 List getDeviceListTest(@Param("columnName") String columnName); select * from t_device order by ${columnName} desc4.动态 SQL ,如果在动态 SQL 中使用了参数作为变量,那么也需要 @Param 注解,即使你只有一个参数。 //mapper 接口 List getDeviceListTest(@Param("deviceId") String deviceId); select * from t_device device_id=#{deviceId} 二 、为啥平时写代码有些时候不加可以正常运行 ,谁在搞鬼?测试 多参数时,不写 @Param List getDeviceListTest(String deviceId,String deviceName);得到结果如下图所示: 历史原因: 在Java8之前,可以说你无法做到(你是不可能读取这个 id) 的,因为Java在编译的时候会将 String deviceId编译为 String arg0,然而Java8中新增了这样的一个特性,你可以在编译的时候设定保留参数名称.详见源码分析 错误总结: 注: 使用jdk1.7得到的是: [1, 0, param1, param2] 使用1.8得到的则是: [arg1, arg0, param1, param2] 例如 xml 可以这样写,但这种方法不建议使用,sql层表达不直观,且一旦顺序调整容易出错。 为了证明上述解释是对的:以下sql语句可以完美运行 select * from t_device where device_id = #{arg0} and device_name != #{arg1}idea有时可以不加@Param,那么它 对我的代码做了什么? 但是 你如使用的是idea ,即时不写@Param 也能成功,原因是 IDEA编译时采取了强制保持方法参数变量名,但需要满足如下 1. 必须是jdk8或以上 2. 编译器参数-parameters 三、错误源码分析debug断点进入service实现类 deviceMapper.getDeviceListTest(device.getDeviceId(),device.getDeviceName());进入后,见下图,怎么样熟悉的感觉吧 JDK动态代理,我们写的mapper 接口,MyBatis 通过动态代理,自动添加了实现类,主要看invoke() 方法,参数变成了数组args 动态代理会在原有方法上实现增强,而增强的逻辑就写在InvocationHandler类的invoke方法上, 所以接下来看 cachedMapperMethod,如果不存在就实例化一个 MapperMethod,然后 put。 当然,第一次调用肯定是不存在的。 进来后,看 method 进行了实例化下面对 paramAnnotations 的遍历,如果没有设置 @Param,那么 name 也不会有值,那么将会通过 getActualParamName 来获取参数值。获取实体或者map 里的参数名,或者直接得到参数名arg0 补充:getActualParamName 使用了 JDK 1.8 新增特性,反射获取参数名
|
CopyRight 2018-2019 实验室设备网 版权所有 |