MyBatis——特殊传参问题小结
近期在写系统报表API的时候遇到MyBatis中的一些特殊写法:
1. 传入两个参数(一般情况下我们更多的是传入一个对象或者map)
public List<MarketVehicleModel> selectVehicleByMarketAndDealer(String marketActivityId,String dealerId);
其对应的xml写法不能想当然地写成:
<select id="selectVehicleByMarketAndDealer" parameterType="java.lang.String" resultType="bz.sunlight.entity.MarketVehicleModel">
SELECT DISTINCT mvm.vehicle_model_id as vehicleModelId,mvm.vehicle_model_code as vehicleModelCode,mvm.vehicle_model_name as vehicleModelName
from vehicle v,vehicle_model vm,Market_Vehicle_Model mvm where v.vehicle_model_id = vm.id and mvm.vehicle_model_id = vm.id
and mvm.market_activity_id = #{marketActivityId} and v.dealer_id=#{dealerId}
</select>
这样写,在编译打包期间不会报什么错,但到正式运行的时候会报告匹配不到 marketActivityId 和 dealerId .
正确的写法应该是:
<select id="selectVehicleByMarketAndDealer" parameterType="java.lang.String" resultType="bz.sunlight.entity.MarketVehicleModel">
SELECT DISTINCT mvm.vehicle_model_id as vehicleModelId,mvm.vehicle_model_code as vehicleModelCode,mvm.vehicle_model_name as vehicleModelName
from vehicle v,vehicle_model vm,Market_Vehicle_Model mvm where v.vehicle_model_id = vm.id and mvm.vehicle_model_id = vm.id
and mvm.market_activity_id = #{0} and v.dealer_id=#{1}
</select>
2. 上面的修改虽然暂时解决了可行性的问题,但这种写法并不可靠,如果遇到对两个参数进行条件判断的情况,还是会有问题,比如:
<select id="getSalesVolumeRanking" parameterType="java.lang.String"
resultType="java.util.HashMap">
SELECT sale_consultant_id AS consultantId,sale_consultant_name AS consultantName,COUNT(*) AS salesVolume
FROM sales_record
<where>
<if test="0 != null">
vehicle_model_id = #{0}
</if>
<if test="1 != null">
AND dealer_id = #{1}
</if>
</where>
GROUP BY sale_consultant_id
ORDER BY salesVolume DESC
</select>
这样的写法显然是不对的,这里有两种解决方案:
(1) 将多个参数组合成map后传入
List<HashMap<String,Object>> getSalesVolumeRanking(HashMap<String, String> map);
<select id="getSalesVolumeRanking" parameterType="java.util.HashMap"
resultType="java.util.HashMap">
SELECT sale_consultant_id AS consultantId,sale_consultant_name AS consultantName,COUNT(*) AS salesVolume
FROM sales_record
<where>
<if test="vehicleModelId != null">
vehicle_model_id = #{vehicleModelId}
</if>
<if test="dealerId != null">
AND dealer_id = #{dealerId}
</if>
</where>
GROUP BY sale_consultant_id
ORDER BY salesVolume DESC
</select>
(2) 给参数加@Param注解
List<HashMap<String,Object>> getSalesVolumeRanking(@Param("vehicleModelId") String vehicleModelId,@Param("dealerId") String dealerId);
<select id="getSalesVolumeRanking" parameterType="java.lang.String"
resultType="java.util.HashMap">
SELECT sale_consultant_id AS consultantId,sale_consultant_name AS consultantName,COUNT(*) AS salesVolume
FROM sales_record
<where>
<if test="vehicleModelId != null">
vehicle_model_id = #{vehicleModelId}
</if>
<if test="dealerId != null">
AND dealer_id = #{dealerId}
</if>
</where>
GROUP BY sale_consultant_id
ORDER BY salesVolume DESC
</select>
3. 传入单个参数,但涉及到对该参数的条件判断:
List<HashMap<String,Object>> getSatisfactionDegree(String vehicleModelId);
<select id="getSatisfactionDegree" parameterType="java.lang.String"
resultType="java.util.HashMap">
SELECT sale_consultant_id AS consultantId,ROUND(AVG(score)) satisfactionDegree
FROM reward_record
<if test="vehicleModelId != null and vehicleModelId != ''">
where vehicle_model_id = #{vehicleModelId}
</if>
GROUP BY sale_consultant_id
</select>
这种写法在运行时会报告There is no getter for property named 'vehicleModelId' 这时可将vehicleModelId换成关键字_parameter:
<select id="getSatisfactionDegree" parameterType="java.lang.String"
resultType="java.util.HashMap">
SELECT sale_consultant_id AS consultantId,ROUND(AVG(score)) satisfactionDegree
FROM reward_record
<if test="_parameter != null and _parameter != ''">
where vehicle_model_id = #{_parameter}
</if>
GROUP BY sale_consultant_id
</select>
4. 自定义order/group by clause或者传入int型参数时需将#{parameterName}引用改为${parameterName} :
HashMap<String, String> parameterMap = new HashMap<String, String>();
parameterMap.put("marketActivityCode", marketActivity.getCode());
parameterMap.put("dealerId", dealer.getId());
parameterMap.put("groupByClause","level_of_intent");
List<HashMap<String,Object>> currentIntentionCustomers = intentionCustomerMapper.getIntentionCustomerNumWithVehicle(parameterMap);
<select id="getIntentionCustomerNumWithVehicle" parameterType="java.util.HashMap"
resultType="java.util.HashMap">
SELECT c.level_of_intent,c.Level_Of_Intent_First,m.vehicle_model_id,m.vehicle_model_code,m.vehicle_model_name,COUNT(*) AS num
FROM intention_customer c,intention_models m
WHERE c.id = m.intention_customer_id
AND c.dealer_id = #{dealerId}
AND m.market_activity_code = #{marketActivityCode}
<if test="groupByClause != null">
GROUP BY ${groupByClause},vehicle_model_id
</if>
</select>
如果继续使用#{groupByClause}会使得执行的sql变成GROUP BY "level_of_intent" 导致得不到正确的分组结果.
MyBatis——特殊传参问题小结的更多相关文章
- Mybatis中传参包There is no getter for property named 'XXX' in 'class java.lang.String'
Mybatis中传参包There is no getter for property named 'XXX' in 'class java.lang.String' 一.发现问题 <select ...
- MyBatis中传参时为什么要用#{}
MyBatis中传参时为什么要用#{},这个问题和MyBatis如何防止SQL注入类似.不过在解释这个问题之前,先解释一下什么是SQL注入,还有些称作注入攻击这个问题. SQL注入就是SQL 对传入参 ...
- Mybatis的传参
最近重新温习了遍Mybatis ,觉得还是汇总一下比较好,方便自己以后的快速开发 最终要的一点事,自己写的话,记忆更加深刻: 首先自己先写了个静态块,防止代码冗余: private static Sq ...
- MyBatis:传参
MyBatis从入门到放弃二:传参 前言 我们在mapper.xml写sql,如果都是一个参数,则直接配置parameterType,那实际业务开发过程中多个参数如何处理呢? 从MyBatis API ...
- 180718-jar包执行传参使用小结
jar包执行时传参的使用姿势 虽说我们现在大多不太直接使用jar包运行方式,目前比较主流的是将自己的服务丢在某个容器中(如tomcat,jetty等)运行,比如我之前所属的电商公司,就是将项目打包为w ...
- Mybatis获取传参
取自 https://blog.csdn.net/weixin_38303684/article/details/78886375 mybatis中SQL接受的参数分为:(1)基本类型(2)对象(3 ...
- mybatis 复杂传参
1基本传参数 Public User selectUserWithCon(@param(“userName”)String name,@param(“userArea”)String area); ...
- mybatis参数传参、取值处理等
单个参数:mybatis不会做特殊处理 取值方式:#{参数名} 这里参数名不必与方法的形参名称一致,可以用任意参数名来接受实参 例子:方法:update(Integer id) sql映射文件取值#{ ...
- (后端)Mybatis中#{}和${}传参的区别及#和$的区别小结(转)
原文地址:https://www.cnblogs.com/zqr99/p/8094234.html 最近在用mybatis,之前用过ibatis,总体来说差不多,不过还是遇到了不少问题,再次记录下, ...
随机推荐
- Go 方法使用
方法的定义 在 Go 语言里,方法和函数只差了一个,那就是方法在 func 和标识符之间多了一个参数. type user struct { name string, email string, } ...
- UITableView个人使用总结【前篇-增量加载】
UITableView现在边整边总结. 预计分两个部分,第一个部分主要是对UITableView本身属性的学习.第二个部分可能会是加上一个编辑按钮以及对列表的操作. 今天先学习第一部分. 第一部分,我 ...
- 最全排序算法原理解析、java代码实现以及总结归纳
算法分类 十种常见排序算法可以分为两大类: 非线性时间比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此称为非线性时间比较类排序. 线性时间非比较类排序:不通过 ...
- 基于OPENldap搭建postfix 虚拟用户
本文首发: https://www.somata.work/2019/DependOPENldapBuildPostfixVirtualMailUser.html postfix + dovecot ...
- api的日志
package cn.com.acxiom.coty.wechat.ws.bean.po; import java.util.Date; public class WebserviceLogWecha ...
- mongodb索引 单键索引
单键索引是最普通的索引,比如一条记录,形式为{x:1,y:2,z:3},我们在x上建立索引,之后就可以以x为条件进行查询,与_id索引不同,单键索引不会自动创建 创建索引 > db.test2. ...
- 特殊方法 之 len __repr__ __str__
关于len, 如果x是一个内置类型的实例,那么len(x)的速度回非常快,背后的原因是CPython会直接从一个C结构体里读取对象的长度,完全不用调用任何方法,获取一个集合中的元素的数量是一个很常见的 ...
- Jquery选择器小结
1.基本选择器 $("#id") //ID选择器 $("div") //元素选择器 $(".classname") //类选择器 $(&qu ...
- nodejs,express链式反应
链式反应--next() const myexpress = require('express'); const bodyparser = require('body-parser'); var se ...
- 2019HDU多校第六场1009 Three Investigators——杨表
题意 给定一个 n 个元素的数列,从前 k 个元素中取5次不下降子序列,求取得的和的最大值(k从1至n) 分析 考虑将数字 a[i] 拆成 a[i] 个 a[i],比如 “4,1,2”→“4,4,4, ...