2016-11-18 70 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非常过时。我的主要观点是,如果你写一个方法,对于每一次重复操作,你只需要一行。


在数据库中做所有事情通常是最简单的,也可能是最快的。您可以轻松加快速度,以便在重要标准上添加索引。请注意,索引会使写入速度变慢,并且每个表最多只能使用一个索引。

在运行之前,我不打扰优化更多,并获取一些使用情况统计信息。没有他们,你可以浪费你的时间在罕见的情况下。

如果整个列表不太长,您可能需要改变它: - 在数据库中过滤。 - 应用程序中没有任何内容。 - 在客户端进行排序和分页(即将结果减少到页面上的内容)。

(可选)您可以在客户端中执行一些其他过滤功能。