zoukankan      html  css  js  c++  java
  • sql优化:当无法判断查询条件是否为空时也可以使用的sql语句

    最近,使用java+mybatis开发时,遇到了一个情况:想执行一条sql语句从数据库查询数据,但是无法确定传入的参数是否为空。通过百度,发现了以下几种解决方法,在此整理如下。

    其中,第3种解决办法最简洁高效

    1.根据参数是否为空,进行sql拼接。

       例如,可以根据ID从数据库中查询数据,但是ID可能为空,此时则返回表中所有的数据。

       代码大致如下:

       String id = (String)req.getParameter("id");//从页面获得id

       String sql = "select * from User where 1=1";//sql语句,方便拼接

       //如果id不为空

       if(!StringUtils.isBlank(id)){

            sql=sql+"and id="+id;

       }

       之后如果有多个条件,也可以这样判断并拼接,最后执行该sql语句即可。

    2.使用多条sql语句实现

       由于项目中使用了注解的方式编写sql,因此不适用第一种解决方法,无法拼接sql。此时可以使用笨办法,使用多条sql语句实现功能。

      例如,可以根据ID从数据库中查询数据,但是ID可能为空,此时则返回表中所有的数据。

      代码大致如下:

    UserMapper.java:
    //注解1,查找表中所有数据
    @Select("select * from User")
    ArrayList<User> selectFromUser();
    
    //注解2,根据id查找表中数据
    @Select("select * from User where id=#{id}")
    ArrayList<User> selectFromUserById(String id);
    
    ///
    Service.java:
    //java代码,根据id是否为空决定调用哪个方法
    @Autowired
    private UserMapper mapper;//注入mapper对象
    public ArrayList<User> selectFromUser(String id){
      if(StringUtils.isBlank(id)){
        return mapper.selectFromUser();
      }else{
        return mapper.selectFromUserById(id);
      }
    }

    3.对sql语句进行优化,使用sql语句实现

       实际使用中,我发现前2种方法都不是很方便,当无法判断是否为空的参数变多时,都会导致代码量增多,给阅读与编写带来难度。后来,我在网上寻找更好的方法时,终于找到了只用1条sql语句就可以解决这个问题的方法,因此将整个代码记录如下,亲测可用。

      使用第3种方法需要注意3点:

      (1)我使用的是java+springboot+mybatis,注解方式的sql,因此只测试了注解方式可以实现,其它环境并没有测试。

      (2)注解方式中,如果传入的参数过多,会导致"Mybatis错误:Parameter 'XXX' not found.",此时需要使用@Param注解指明参数与sql语句的对应关系。(代码中已使用)

      (3)代码的第二个sql方法中,包含了使用between查询时间范围内数据的方法,在java中调用时对参数进行了一些修改,例如当时间范围为空时设置开始时间为"1999年",结束时间为"2999年"等类似的方法,因此sql可能不是很完善。

      整个代码如下(Mapper.java):

    import OrderBean;
    import org.apache.ibatis.annotations.Mapper;
    import org.apache.ibatis.annotations.Param;
    import org.apache.ibatis.annotations.Select;
    import org.springframework.stereotype.Component;
    
    import java.util.ArrayList;
    import java.util.Date;
    
    @Mapper
    @Component
    public interface CompleteOrderMapper {
        @Select("select * from completeOrder where (order_id = #{order_id} or #{order_id}='')" +
                "and (prod_id = #{prod_id} or #{prod_id}='')" +
                "and (amt = #{amt} or #{amt}='')" +
                "and (buy_time like #{buyTime} or #{buyTime}='')")
        ArrayList<OrderBean> selectBuyCompleteOrderWithBuyTime(@Param("order_id")String order_id, @Param("prod_id")String prod_id,@Param("amt")String amt, @Param("buyTime")String buyTime);
    
        @Select("select * from completeOrder where (order_id = #{order_id} or #{order_id}='')" +
                "and (prod_id = #{prod_id} or #{prod_id}='')" +
                "and (amt = #{amt} or #{amt}='')" +
                "and ((buy_time between #{beginTime} and #{endTime}) or #{beginTime} Is Null)")
        ArrayList<OrderBean> selectBuyCompleteOrderWithRangeTime(@Param("order_id")String order_id,@Param("prod_id")String prod_id,@Param("amt")String amt,@Param("beginTime")Date beginTime, @Param("endTime")Date endTime);
    }
    

      说明:

      这是个mapper接口,使用之前需要spring注入。

      OrderBean是JavaBean对象,自己创建的。

      

      原理:

      1.select * from 表 where (字段=条件 or 条件=' ');

        当条件不为空时:select * from 表 where 字段=条件;

        当条件为空时:select * from 表 where ' '=' ';

        具体原理可查看:https://blog.csdn.net/qq_39651858/article/details/81738199

      2.使用@Param注解,解决Mybatis错误:Parameter 'XXX' not found. 

        具体细节可查看:https://blog.csdn.net/w86440044/article/details/29363067/  ,在这个网址的末尾位置有正确的用法。

       

      在此感谢以上作者的文章。

      本文到此结束,如有错误,欢迎各位读者批评指正,谢谢!

  • 相关阅读:
    数据仓库系列之维度建模
    为什么数据分析中要建数据仓库?
    C1WPF制作OLAP Cube浏览工具
    WPF自学入门(十二)WPF MVVM模式提取函数
    WPF自学入门(十一)WPF MVVM模式Command命令
    WPF自学入门(十)WPF MVVM简单介绍
    WPF自学入门(九)WPF自定义窗口基类
    大话Git系列之初识版本控制系统(1)
    C#(1)运用C#实现一键从Word文档转换TXT文本的功能
    arcgis api for javascript 学习(六) 地图打印
  • 原文地址:https://www.cnblogs.com/codeToSuccess/p/13906257.html
Copyright © 2011-2022 走看看