输入参数个数不确定时如何写SQL语句


         以查询货币汇率的应用为例,用户在前端页面选择查询参数后,传到后端的参数有起始日期、结束日期和若干币种(以数组形式),币种的数量是不确定的,要求查询在起始日期和结束日期之间,用户所选币种的汇率信息。
         在数据库里,有两张表,一张表是汇率表(表名称bgt_rate),字段有id、date、currency、rate四个字段分别表示编号、日期、币种代号、汇率,另一张表是币种信息表(表名称bgt_currency),有currency、name两个字段,分别表示币种代号、币种的中文名称。
         后端的Controller接收前端发来的参数:

@RequestMapping(value = {"rate/searchCurrency"}, method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
public JSONArray searchCurrency(@RequestBody Map<String,Object> data, HttpServletRequest request, HttpServletResponse response) throws Exception {
   ArrayList<String> currency = (ArrayList<String>) data.get("listOfCurrency"); //币种数组
   String startDate=(String)data.get("startDate");  //起始日期
   String endDate=(String)data.get("endDate");  //结束日期
   List<com.entity.Rate> rates=rateInterface.getRates(startDate,endDate,currency);  //通过自定义接口函数查询
   JSONArray array= JSONArray.parseArray(JSON.toJSONString(rates));
   return array;
}

  查询的自定义接口函数:

public List<Rate> getRates(String startDate,String endDate,@Param("currency") ArrayList<String> currency);

  Mapper文件中的SQL语句如下,主要是通过foreach来获得币种数组中的每个币种,并用concat函数拼接成最终的SQL语句。

<select id="getRates" resultType="com.entity.Rate">
  select r.*, c.name as name from bgt_rate r left join bgt_currency c on r.`currency`=c.`currency`
     where (r.`date` between #{startDate} and #{endDate}) and
        (<foreach collection="currency" item="item" index="index" separator="OR">c.`name` like CONCAT('%',#{item},'%')
         </foreach>)
</select>

  上面的SQL语句在正常情况下运行没有问题,但是当用户没有选择任何币种时,currency数组为空,这时候会发生错误,为避免出错,需要修改一下SQL语句,变成下面的样子。增加了<choose>标签,1=1表示当currency为空或长度为0时,保证SQL语句里的and后面仍有语句,不致于报错。这里的currency是ArrayList类型,所以判断语句里是用currency.size() !=0,如果currency是数组类型,则应改成currency.length !=0。

<select id="getRates" resultType="com.entity.Rate">
   select r.*, c.name as name from bgt_rate r left join bgt_currency c on r.`currency`=c.`currency`
   where (r.`date` between #{startDate} and #{endDate}) and (
      <choose>
         <when test="currency != null and currency.size() !=0">
            <foreach collection="currency" item="item" index="index" separator="OR">c.`name` like CONCAT('%',#{item},'%')
            </foreach>
          </when>
          <otherwise>
             1 = 1
          </otherwise>
      </choose>
      )
</select>

  

原创文章,作者:kirin,如若转载,请注明出处:https://blog.ytso.com/tech/database/267447.html

(0)
上一篇 2022年6月15日 07:37
下一篇 2022年6月15日 07:37

相关推荐

发表回复

登录后才能评论