近期在写系统报表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. xposed获取context 的方法

    // 应用被加壳,采用这种方式加载类 try { XposedHelpers.findAndHookMethod(Application.class, "attach", Cont ...

  2. python 爬虫抓取 MOOC 中国课程的讨论区内容

    一:selenium 库 selenium 每次模拟浏览器打开页面,xpath 匹配需要抓取的内容.可以,但是特别慢,相当慢.作为一个对技术有追求的爬虫菜鸡,狂补了一些爬虫知识.甚至看了 scrapy ...

  3. GNS3

    什么是GNS? GNS Graphical Network Simulator Simulator or Emulator? 尽管GNS全拼包含simulator,但实际上是emulator.我们说其 ...

  4. nginx 重发机制导致的重复扣款问题

    问题:    nginx 重发机制导制重复提交(客户还款,被扣俩笔款,前端调用一次,后端执行2次) proxy_next_upstream 语法: proxy_next_upstream error ...

  5. 一个ball例程带你进入 Halcon 世界

    * 此例程来自halcon自带例程,请打开 halcon->ctrl+E 打开例程->搜索框中输入ball added by xiejl* ball.hdev: Inspection of ...

  6. 对Ajax的一些理解

    前言 在学习js的过程,我个人对于Ajax这项技术有着很深的印象,大概是因为它在我们网页开发过程中常见的交互里所发挥的作用太过于关键了吧,所以我想在这里好好地谈一些自己对它的理解. 概念理解 Ajax ...

  7. 关于webpack require.context() 的那点事

    先说 webpack里面有这么一招:使用require.context()方法来自动导入模块 官方文档有点深奥,老衲百度下拿了一段来直接使用,但是想看下它是如何运行的 本篇这里不会有太深入的研究,只是 ...

  8. 省选模拟赛 Problem 3. count (矩阵快速幂优化DP)

    Discription DarrellDarrellDarrell 在思考一道计算题. 给你一个尺寸为 1×N1 × N1×N 的长条,你可以在上面切很多刀,要求竖直地切并且且完后每块的长度都是整数. ...

  9. BZOJ 2145: 悄悄话 (打表)

    BZOJ 2145 题解 直接代词,所有格,常用副词,助动词,冠词,常用词打表 比较出现次数的多少来决定循环位移了几位. CODE #include <bits/stdc++.h> usi ...

  10. P2634 [国家集训队]聪聪可可 点分治

    思路:点分治 提交:1次 题解: 不需要什么容斥...接着板子题说: 还是基本思路:对于一颗子树,与之前的子树做贡献. 我们把路径的权值在\(\%3\)意义下分类,即开三个桶\(c[0],c[1],c ...