近期在写系统报表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. 实现LAMP架构

    LAMP介绍 LAM(M)P: L: linux A: apache (httpd) M: mysql, mariadb M:memcached P: php, perl, python WEB资源类 ...

  2. sql注入原理,利用与防护

    一.sql注入原理 注入攻击的本质就是把用户输入的数据当作代码来执行.所以注入攻击有两个必要条件 1.用户能够控制的输入. 2.原本程序要执行的代码,拼接了用户输入的数据. 二.sql注入分类 按照请 ...

  3. jquery.js:9600 POST http://127.0.0.1:8000/news/1/comments/ 500 (Internal Server Error)

    什么情况? 代码报错了....查询 语句错误  看 编译提示. 数据 查询 语句的问题!!!!

  4. IE浏览器中使用js调用cmd命令行demo

    <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="C ...

  5. js之head请求,闪电般实现交互

    平时我们用到的请求一般为post和get,今天介绍一种新的请求方式,head请求,顾名思义,head请求就是请求头部信息的,也只能请求头部信息,所以相应速度非常快,可以快速的实现前后端的交互 $.aj ...

  6. PAT Advanced 1008 Elevator (20 分)

    The highest building in our city has only one elevator. A request list is made up with N positive nu ...

  7. Java字节码整体分析与总结

    上一次[https://www.cnblogs.com/webor2006/p/9508341.html]已经将编译器生成的默认构造方法的字节相关的分析完了,接下来则分析咱们自定义的方法啦,按照顺序来 ...

  8. Spring-HelloSpring-IOC创建对象的方式

    3.HelloSpring 思考 Hello 对象是谁创建的 ? [ hello 对象是由Spring创建的 ] Hello 对象的属性是怎么设置的 ? [hello 对象的属性是由Spring容器设 ...

  9. Spring MVC + freemarker实现半自动静态化

    这里对freemarker的代码进行了修改,效果:1,请求.do的URL时直接生成对应的.htm文件,并将请求转发到该htm文件2,自由控制某个页面是否需要静态化原理:对org.springframe ...

  10. python查看文件夹下所有文件

    实现查看所有文件,重点在于文件夹下又有文件夹时怎样处理,这里通过os模块来解决. 方法一 : 通过递归实现遍历所有文件夹 import os def func(path): for i in os.l ...