java - 使用多个参数过滤数据的最有效方法?

标签 java spring performance spring-mvc

所以我现在有这样的东西 http://codepen.io/anon/pen/bBgVOL

它获取一个位置,将其传递给 GET ajax 调用,该调用返回纬度/经度,然后将其传递给我的 Controller 。 (是的,我知道这很乱)

@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 )

我现在设置 Controller 的方式很可能不起作用,并且将来会非常令人头痛,因为我需要大量基于参数的 if/else 语句。我现在正在使用 SQL 查询过滤数据。返回所有数据并在内存中过滤它是否会更好,或者是否有更好/更有效的方法来设置此 Controller 响应?

谢谢!

最佳答案

您的数据库将针对搜索和过滤进行优化;这是它的主要用例。此外,数据库将能够访问 Java 无法访问的索引。此外,该数据库可能会实现比您在 Java 中尝试的任何搜索更快的搜索。例如,数据库的搜索实现可能会使用并发性。

但这并不是完全黑白分明的。也许数据库位于非常慢的硬件上;在这种情况下:也许 Java 应用程序服务器可以更快地进行过滤。也许数据库位于机械硬盘上,因此随机访问速度很慢(这会使其不善于利用索引……尽管 Java 根本没有任何索引)。

我仍然建议将工作推送到数据库,因为这就是它的用途

<小时/>

当然,也许您的搜索/过滤条件不太适合关系数据库模型。考虑具有数据依赖性的过滤条件 - 例如“查找存在旧车的每辆车”。这在 SQL 中有点笨拙(我认为很慢)。数据库仅在其设计的工作中才快。

如果性能实际上很重要,请对其进行基准测试。尝试两种方法,并进行测量。

如果性能并不重要:问问自己哪些代码更难维护。以动态、参数化的方式构建 SQL 查询可能会变得非常难看。但在 Java 中操作数据结构也可能变得非常难看。

关于java - 使用多个参数过滤数据的最有效方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40683033/

相关文章:

java - 在 JGIT 中创建分支时出现 RefNotFoundException

java - 从java中的RestController返回多种(xml和json)格式

java - 除非访问集合,否则 Hibernate OneToMany FetchType.LAZY 无法正常工作?

java - Hibernate 仅从数据库中检索第一条记录,其余为空

mysql - 在 left join vs. 中使用 Inner Join 的性能多个左连接

java - Hibernate 关系映射/加速批量插入

java - 循环内的数据库调用有其他选择吗?

java - 抑制 Java Ctrl+Break 行为

java - 如何使用连接池在 JM 中使用 activeMQ 创建发布者

java - 从包含字节数组图像的数据库获取对象