jdbc中PreparedStatement不定引數的小技巧
阿新 • • 發佈:2019-01-01
今天產品部需要幫忙弄個小專案,就只需建立一個數據表,頁面提供一些簡單的增刪改查,excel 匯出功能,由於時間緊,就不採取什麼SSH之類的重量級框架,直接用JSP+servlet+JDBC快速完成這個小專案。在查詢使用PreparedStatement時,發現如果查詢條件時不確定的條件下,需要很多if判斷,程式碼醜陋,如果突然再加多幾個不定條件,那就非常麻煩了,大量重複的程式碼。比如
public void queryPaging(Paging<Dealer> paging,String userName,String telephone){ try { connection = DbFactory.getConnection(); //查詢總記錄數 StringBuffer countSql = new StringBuffer( "select ifnull(count(*),0) from weixin_dealer where 1=1 "); if(StringUtils.isNotBlank(userName) || StringUtils.isNotBlank(telephone)){ if(StringUtils.isNotBlank(userName) && StringUtils.isNotBlank(telephone)){ countSql.append(" where user_name like ? and telephone=? "); preparedStatement = connection.prepareStatement(countSql.toString()); preparedStatement.setString(1,"%"+ userName.trim()+"%"); preparedStatement.setString(2, telephone); }else if(StringUtils.isNotBlank(userName)){ countSql.append(" where user_name=? "); preparedStatement = connection.prepareStatement(countSql.toString()); preparedStatement.setString(1, "%"+ userName.trim()+"%"); }else{ countSql.append(" where telephone=? "); preparedStatement = connection.prepareStatement(countSql.toString()); preparedStatement.setString(1, telephone); } }else{ preparedStatement = connection.prepareStatement(countSql.toString()); } resultSet = preparedStatement.executeQuery(); int count = 0; while(resultSet.next()){ count = resultSet.getInt(1); } paging.setTotalCount(count); DbFactory.close(resultSet,preparedStatement); //查詢記錄 StringBuffer querySql =new StringBuffer( "select id,user_name,telephone,add_time from weixin_dealer "); String querySql2= " order by add_time desc limit ?,? "; if(StringUtils.isNotBlank(userName) || StringUtils.isNotBlank(telephone)){ if(StringUtils.isNotBlank(userName) && StringUtils.isNotBlank(telephone)){ querySql.append(" where user_name=? and telephone=? ").append(querySql2); preparedStatement = connection.prepareStatement(querySql.toString()); preparedStatement.setString(1, "%"+ userName.trim()+"%"); preparedStatement.setString(2, telephone); preparedStatement.setInt(3,paging.getFirst()); preparedStatement.setInt(4, paging.getPageSize()); }else if(StringUtils.isNotBlank(userName)){ querySql.append(" where user_name=? ").append(querySql2); preparedStatement = connection.prepareStatement(querySql.toString()); preparedStatement.setString(1, "%"+ userName.trim()+"%"); preparedStatement.setInt(2,paging.getFirst()); preparedStatement.setInt(3, paging.getPageSize()); }else{ querySql.append(" where telephone=? ").append(querySql2); preparedStatement = connection.prepareStatement(querySql.toString()); preparedStatement.setString(1, telephone); preparedStatement.setInt(2,paging.getFirst()); preparedStatement.setInt(3, paging.getPageSize()); } }else{ querySql.append(querySql2); preparedStatement = connection.prepareStatement(querySql.toString()); preparedStatement.setInt(1,paging.getFirst()); preparedStatement.setInt(2, paging.getPageSize()); } resultSet = preparedStatement.executeQuery(); List<Dealer> list = new ArrayList<Dealer>(); Dealer dealer = null; while(resultSet.next()){ dealer = new Dealer(); dealer.setId(resultSet.getInt("id")); dealer.setUserName(resultSet.getString("user_name")); dealer.setTelephone(resultSet.getString("telephone")); dealer.setAddTime(resultSet.getTimestamp("add_time")); list.add(dealer); } paging.setResultList(list); } catch (Exception e) { logger.error("分頁查詢出錯.....",e); }finally{ DbFactory.close(resultSet,preparedStatement,connection); } }
程式碼非常醜陋,如果要再加多幾個查詢條件時,那程式碼量就寫死人了,百度了下,看到也有人提出過這問題,但是沒看到有什麼解決方法。想了想,還不如自己想辦法呢,稍微想了一分鐘,對程式碼重構了下
public void queryPaging(Paging<Dealer> paging,String userName,String telephone,String beginTime,String endTime){ try { connection = DbFactory.getConnection(); List<String> params = new ArrayList<String>(); //查詢總記錄數 StringBuffer countSql = new StringBuffer( "select ifnull(count(*),0) from weixin_dealer where 1=1 "); //查詢記錄 StringBuffer querySql =new StringBuffer( "select id,user_name,telephone,add_time from weixin_dealer where 1=1 "); if(StringUtils.isNotBlank(userName)){ countSql.append(" and user_name like ? "); querySql.append(" and user_name like ? "); params.add("%"+userName.trim()+"%"); } if(StringUtils.isNotBlank(telephone)){ countSql.append(" and telephone=? "); querySql.append(" and telephone=? "); params.add(telephone.trim()); } if(StringUtils.isNotBlank(beginTime)){ countSql.append(" and add_time >= STR_TO_DATE(?,'%Y-%m-%d') "); querySql.append(" and add_time >= STR_TO_DATE(?,'%Y-%m-%d') "); params.add(beginTime); } if(StringUtils.isNotBlank(endTime)){ countSql.append(" and add_time <= STR_TO_DATE(?,'%Y-%m-%d') "); querySql.append(" and add_time <= STR_TO_DATE(?,'%Y-%m-%d') "); params.add(endTime); } logger.info("分頁查詢,總記錄 sql,countSql="+countSql.toString()); preparedStatement = connection.prepareStatement(countSql.toString()); for(int i=0;i<params.size();i++){ preparedStatement.setString(i+1, params.get(i)); } resultSet = preparedStatement.executeQuery(); int count = 0; while(resultSet.next()){ count = resultSet.getInt(1); } paging.setTotalCount(count); DbFactory.close(resultSet,preparedStatement); querySql.append(" order by add_time desc limit ?,? "); logger.info("分頁查詢,查詢 sql,querySql="+querySql.toString()); preparedStatement = connection.prepareStatement(querySql.toString()); int j=1; for(String param : params){ preparedStatement.setString(j,param); j++; } preparedStatement.setInt(j,paging.getFirst()); preparedStatement.setInt(j+1, paging.getPageSize()); resultSet = preparedStatement.executeQuery(); List<Dealer> list = new ArrayList<Dealer>(); Dealer dealer = null; while(resultSet.next()){ dealer = new Dealer(); dealer.setId(resultSet.getInt("id")); dealer.setUserName(resultSet.getString("user_name")); dealer.setTelephone(resultSet.getString("telephone")); dealer.setAddTime(resultSet.getTimestamp("add_time")); list.add(dealer); } paging.setResultList(list); } catch (Exception e) { logger.error("分頁查詢出錯.....",e); }finally{ DbFactory.close(resultSet,preparedStatement,connection); } }
現在程式碼就好多了,哪怕再增加查詢條件也不怕。
也許有人說,你上面preparedStatement.setString(j,param);都是String型的,那如果還有int,double等一些型別呢。這也好辦,其實可以寫個共有方法的,我就不詳細寫了,稍微提供個思路
只是提供個思路,功能不完整。public void setParameter(List<Object> params,PreparedStatement preparedStatement) throws SQLException{ for(int i=0;i<params.size();i++){ Object p = params.get(i); if(p instanceof Integer){ preparedStatement.setInt(i+1, (Integer)p); }else if(p instanceof String){ preparedStatement.setString(i+1, (String)p); } } }