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" 导致得不到正确的分组结果.

posted @ 2016-11-08 13:56  笑叹词穷  阅读(400)  评论(0编辑  收藏  举报