近期在写系统报表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——特殊传参问题小结的更多相关文章

  1. 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 ...

  2. MyBatis中传参时为什么要用#{}

    MyBatis中传参时为什么要用#{},这个问题和MyBatis如何防止SQL注入类似.不过在解释这个问题之前,先解释一下什么是SQL注入,还有些称作注入攻击这个问题. SQL注入就是SQL 对传入参 ...

  3. Mybatis的传参

    最近重新温习了遍Mybatis ,觉得还是汇总一下比较好,方便自己以后的快速开发 最终要的一点事,自己写的话,记忆更加深刻: 首先自己先写了个静态块,防止代码冗余: private static Sq ...

  4. MyBatis:传参

    MyBatis从入门到放弃二:传参 前言 我们在mapper.xml写sql,如果都是一个参数,则直接配置parameterType,那实际业务开发过程中多个参数如何处理呢? 从MyBatis API ...

  5. 180718-jar包执行传参使用小结

    jar包执行时传参的使用姿势 虽说我们现在大多不太直接使用jar包运行方式,目前比较主流的是将自己的服务丢在某个容器中(如tomcat,jetty等)运行,比如我之前所属的电商公司,就是将项目打包为w ...

  6. Mybatis获取传参

    取自  https://blog.csdn.net/weixin_38303684/article/details/78886375 mybatis中SQL接受的参数分为:(1)基本类型(2)对象(3 ...

  7. mybatis 复杂传参

    1基本传参数 Public User selectUserWithCon(@param(“userName”)String  name,@param(“userArea”)String area); ...

  8. mybatis参数传参、取值处理等

    单个参数:mybatis不会做特殊处理 取值方式:#{参数名} 这里参数名不必与方法的形参名称一致,可以用任意参数名来接受实参 例子:方法:update(Integer id) sql映射文件取值#{ ...

  9. (后端)Mybatis中#{}和${}传参的区别及#和$的区别小结(转)

    原文地址:https://www.cnblogs.com/zqr99/p/8094234.html 最近在用mybatis,之前用过ibatis,总体来说差不多,不过还是遇到了不少问题,再次记录下, ...

随机推荐

  1. Go 方法使用

    方法的定义 在 Go 语言里,方法和函数只差了一个,那就是方法在 func 和标识符之间多了一个参数. type user struct { name string, email string, } ...

  2. UITableView个人使用总结【前篇-增量加载】

    UITableView现在边整边总结. 预计分两个部分,第一个部分主要是对UITableView本身属性的学习.第二个部分可能会是加上一个编辑按钮以及对列表的操作. 今天先学习第一部分. 第一部分,我 ...

  3. 最全排序算法原理解析、java代码实现以及总结归纳

    算法分类 十种常见排序算法可以分为两大类: 非线性时间比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此称为非线性时间比较类排序. 线性时间非比较类排序:不通过 ...

  4. 基于OPENldap搭建postfix 虚拟用户

    本文首发: https://www.somata.work/2019/DependOPENldapBuildPostfixVirtualMailUser.html postfix + dovecot ...

  5. api的日志

    package cn.com.acxiom.coty.wechat.ws.bean.po; import java.util.Date; public class WebserviceLogWecha ...

  6. mongodb索引 单键索引

    单键索引是最普通的索引,比如一条记录,形式为{x:1,y:2,z:3},我们在x上建立索引,之后就可以以x为条件进行查询,与_id索引不同,单键索引不会自动创建 创建索引 > db.test2. ...

  7. 特殊方法 之 len __repr__ __str__

    关于len, 如果x是一个内置类型的实例,那么len(x)的速度回非常快,背后的原因是CPython会直接从一个C结构体里读取对象的长度,完全不用调用任何方法,获取一个集合中的元素的数量是一个很常见的 ...

  8. Jquery选择器小结

    1.基本选择器 $("#id") //ID选择器 $("div") //元素选择器 $(".classname") //类选择器 $(&qu ...

  9. nodejs,express链式反应

    链式反应--next() const myexpress = require('express'); const bodyparser = require('body-parser'); var se ...

  10. 2019HDU多校第六场1009 Three Investigators——杨表

    题意 给定一个 n 个元素的数列,从前 k 个元素中取5次不下降子序列,求取得的和的最大值(k从1至n) 分析 考虑将数字 a[i] 拆成 a[i] 个 a[i],比如 “4,1,2”→“4,4,4, ...