2016-11-18 78 views
0

所以我有這樣的事情,現在http://codepen.io/anon/pen/bBgVOL使用多個參數篩選數據的最有效方法?

它需要的位置,並將其傳遞給GET AJAX調用,它返回我的緯度/經度然後傳遞,爲我的控制器。 (是的,我知道這是凌亂)

@RequestMapping(value = "/rentals", method = RequestMethod.GET) 
    public String rentResults(@RequestParam(value = "page", required = false) Integer pageNumber, @RequestParam(value = "lat", required = false) String lat, @RequestParam(value = "lng", required = false) String lng, @RequestParam(value = "rad", required = false) String rad, Map model) { 
     int total = 25; 

     if (pageNumber == null) { 
      pageNumber = 1; 
     } else { 
      pageNumber = (pageNumber - 1) * total + 1; 
     } 

     List<ForRent> rentals = new ArrayList(); 

     int count; 
     if (lat == null && lng == null && rad == null) { 
      rentals = forRentDao.getRentalsByPage(pageNumber, total); 
      count = forRentDao.getNumOfRentals(); 
     } else { 
      count = forRentDao.RentalRadiusCount(lat, lng, rad); 
      rentals = forRentDao.RentalRadius(lat, lng, rad, pageNumber, total); 

      String latParam = "&lat=" + lat; 
      String lngParam = "&lng=" + lng; 
      String radParam = "&rad=" + rad; 

      model.put("latParam", latParam); 
      model.put("lngParam", lngParam); 
      model.put("radParam", radParam); 
     } 

     int page; 

     if (count % total == 0) { 
      page = (count/total); 
     } else { 
      page = 1 + (count/total); 
     } 

     List<Integer> pages = new ArrayList(); 
     for (int i = 1; i <= page; i++) { 
      pages.add(i); 
     } 

     model.put("pages", pages); 

     model.put("rentals", rentals); 
     boolean rent = true; 
     model.put("rent", rent); 

     return "rent"; 

    } 

JS

function initMap() { 

       var input = /** @type {!HTMLInputElement} */(
         document.getElementById('address')); 


       var autocomplete = new google.maps.places.Autocomplete(input); 

        }; 


    $('#searchRadius').on('click', function (e) { 

     var lati; 
     var lng; 
     var address = $('#address').val(); 
     var rad = $('#radius').val(); 
     var select = document.getElementById('sel'); 
     var choice = select.value; 



     e.preventDefault(); 


     $.ajax({ 
      type: "GET", 
      url: "http://www.mapquestapi.com/geocoding/v1/address?key=&location=" + address, 
      beforeSend: function (xhr) { 
       xhr.setRequestHeader("Accept", "application/json"); 
       xhr.setRequestHeader("Content-type", "application/json"); 
      }, 
      success: function postForm(response) { 
       lati = response.results[0].locations[0].latLng.lat; 
       lng = response.results[0].locations[0].latLng.lng; 

       if (rad == null) { 
        rad = '10'; 
       } 

       console.log(lati, lng, rad); 

       var data = JSON.stringify({ 
        lat: lati, 
        lng: lng, 
        rad: rad 
       }); 

       if (choice == 1) { 

        $.ajax({ 
         url: contextRoot + "/map/radius", 
         type: "POST", 
         data: data, 
         dataType: 'json', 
         beforeSend: function (xhr) { 
          xhr.setRequestHeader("Accept", "application/json"); 
          xhr.setRequestHeader("Content-type", "application/json"); 
         }, 
         success: function (data, status) { 
          console.log(data); 
          window.location = contextRoot + "/rent/rentals?lat=" + data.lat + "&lng=" + data.lng + "&rad=" + data.rad; 

         }, 
         error: function (data, status) { 
          alert("bad api call"); 
          console.log(status); 
         } 
        }); 
       } 
      }, 
      error: function (data, status) { 
       console.log(data.errors); 
      }} 
     ); 
    }); 

所以現在它要麼返回租金的列表,而緯度/經度/半徑參數,否則將返回與應用的參數列表。

我需要大約5-10多個參數添加到這個(例如http://codepen.io/anon/pen/QGdjoB

我有我的控制器設置,現在最有可能不會工作,將是一個巨大的頭痛前進,因爲我要的方式需要大量基於參數的if/else語句。我正在使用SQL查詢過濾數據。返回所有數據並將其過濾到內存中還是更好/更有效的方法來設置此控制器響應?

謝謝!

回答

0

您的數據庫將針對搜索和過濾進行優化;這是它的主要用例。另外,數據庫可以訪問Java不具有的索引。而且,數據庫可能會比在Java中嘗試的任何方式都實現更快的搜索。例如,數據庫的搜索實現可能使用併發性。

雖然它不完全是黑色和白色。也許數據庫的硬件速度非常慢;在這種情況下:也許Java應用程序服務器可以更快地完成過濾。也許數據庫在機械硬盤驅動器上,所以在隨機訪問時速度很慢(這會使其利用它的索引變得糟糕......儘管Java根本沒有任何索引)。

我仍然建議將工作推向數據庫,因爲這就是


當然,也許您的搜索/過濾條件不適合關係數據庫模型。考慮具有數據依賴性的過濾標準 - 比如「找到一輛舊車存在的每輛車」。這在SQL中有點不合理(我假設很慢)。數據庫只在其設計的工作中很快。

如果性能實際上事情,基準它。嘗試兩種方式,並進行測量。

如果性能不是問題:問問自己哪些代碼更難維護。以動態,參數化的方式構建SQL查詢會變得非常難看。但是在Java數據結構上運行也會變得非常糟糕。

0

現在我的控制器設置的方式很可能不會工作,並且將會非常頭痛,因爲我需要很多基於參數的if/else語句。

你當然不知道。這就是我做了搜索與五個標準:

  .addInUnlessNull("supplier.id", idList) 
      .addEqUnlessNull("id", input.templateId) 
      .addEqIf(!request.includeDeleted(), "isDeleted", false) 
      .addEqUnlessNull("branch.id", input.branchId) 
      .addEqUnlessNull("supplier.id", input.supplierId) 

我使用休眠,但是這並不重要,因爲這是我自己簡單的界面,它可能被製成普通的SQL,太。就像

MyQuery addEqUnlessNull(String path, @Nullable Object value) { 
    if (value != null) { 
     sql.append(" AND " + path + " = ?"); 
     args.append(value); 
    } 
    return this; 
} 

應該做的。謹防SQL注入。查詢中使用的部分不應該來自用戶。每個不安全的輸入都必須用作SQL參數,或者至少要妥善轉義。

但不是重新發明輪子,請看querydsl或類似的東西。 Java中的純SQL非常過時。我的主要觀點是,如果你寫一個方法,對於每一次重複操作,你只需要一行。


在數據庫中做所有事情通常是最簡單的,也可能是最快的。您可以輕鬆加快速度,以便在重要標準上添加索引。請注意,索引會使寫入速度變慢,並且每個表最多隻能使用一個索引。

在運行之前,我不打擾優化更多,並獲取一些使用情況統計信息。沒有他們,你可以浪費你的時間在罕見的情況下。

如果整個列表不太長,您可能需要改變它: - 在數據庫中過濾。 - 應用程序中沒有任何內容。 - 在客戶端進行排序和分頁(即將結果減少到頁面上的內容)。

(可選)您可以在客戶端中執行一些其他過濾功能。

相關問題