首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >按类别、价格等获取产品

按类别、价格等获取产品
EN

Code Review用户
提问于 2015-10-07 15:06:14
回答 1查看 5.5K关注 0票数 4

我所关注的问题如下:

  1. Set是获得产品的好选择吗?为此目的,Set有哪些缺点?
  2. 更好的做法是做一些类似common.retainAll()的事情,还是通过WHERE请求将产品发送到数据库。现在,我用三个请求:getProductsByCategorygetProductsByManufacturergetProductsByPrice。因此,最好只制作一个?@RequestParam(“/{类别}/{price}”)、公共字符串filterProducts(@PathVariable(“类别”)字符串productCategory、@MatrixVariable(pathVar = "price") Map> priceParams、@RequestParam(“制造商”)字符串制造商、模型模型){ Set productsByCategory = service.getProductsByManufacturer(manufacturer);Set productsByManufacturer =service.getProductsByManufacturer(manufacturer);BigDecimal low;BigDecimal high;低=新BigDecimal(priceParams.get(“低”).get(0));System.out.println(低);高=新BigDecimal(priceParams.get(“高”).get(0));System.out.println(高);Set productsByPrice =service.getProductsByPrice(低,高);Set公用=新HashSet(productsByCategory);common.retainAll(productsByManufacturer);common.retainAll(ProductsByCategory);priceParams.get(“高”).get(0);System.out.println(高);SetproductsByPrice=service.getProductsByPrice(低,高);Set公用=新HashSet(ProductsByCategory);common.retainAll(ProductsByManufacturer);common.retainAll(ProductsByCategory);priceParams.get(“高”).get(0);System.out.println(高);SetproductsByPrice=service.getProductsByPrice(低,高);Set公用=新HashSet(ProductsByCategory);common.retainAll(ProductsByManufacturer);common.retainAll(common.retainAll);priceParams.get(“高”).get(0);System.out.println(高);SetproductsByPrice=service.getProductsByPrice(低,高);Set公用=新HashSet(ProductsByCategory);common.retainAll(返回“产品”;}
EN

回答 1

Code Review用户

回答已采纳

发布于 2015-10-16 23:30:33

好的,我假设这是来自您的@Controller的代码,它调用了一个@Service,服务进一步调用了一个@Repository ( DAO层)。此外,我假设您使用的是最新版本的Java,即Java 8。

最终,我发现这一切都取决于你拥有的产品数量。考虑到不太多,您可以使用Java进行所有的过滤。考虑到成千上万,你最好在数据库里做。

数据库层

中的一种方法

在任何情况下,一个数据库调用肯定要比三个好得多,所以您只需创建一个足够通用的数据库搜索方法,就可以将所有搜索参数传递给它。创建该方法时,还可以创建一个名为SearchParameters的数据传输对象,该对象包含所有搜索参数。这样,即使使用多个参数进行搜索,您的方法签名也不会增长到可笑的长度。接口也很容易更改,因为为了添加新的搜索参数,方法签名无需更改,只需更改数据传输对象。

个人经历

我解决了一个类似的问题,只有几十个产品,我的DAO层有一个普通的public List<Product> findAll()方法和一个@Cacheable注释,所以在第一次调用DB之后,进一步的调用只能访问内存中的一个快速缓存。

然后,服务将得到您描述的方法:getProductsByCategorygetProductsByManufacturergetProductsByPrice,但是它们都只是调用DAO的findAll()方法(快速获取缓存的响应),并根据它们的参数过滤结果。

例如(假设Product类有一个返回StringgetManufacturer()方法:

代码语言:javascript
复制
public Set<Product> getProductsByManufacturer(final String manufacturer) {
    return dao.findAll().stream()
        .filter(product -> Objects.equals(product.getManufacturer(), manufacturer)
        .collect(Collectors.toSet());
}

这就是使用Java 8's流。filter只包括制造商与给定参数匹配的产品。

服务层

中的一种方法

但是,由于您需要三个集合的交集,所以最好创建一个方法来完成所有的筛选。如果数据量不太大,或者数据库不是您的强项,那么您可以像我在一开始建议的那样对DAO层进行访问,或者在服务层中这样做。;)

因此,您的业务代码可以归结为这样的内容:

新SearchParameters类:

代码语言:javascript
复制
import java.util.Optional;

public class SearchParameters {
    // Here with just one search parameter for brevity, but you'll get the idea
    String manufacturer;

    public boolean manufacturerMatches(final Product product) {
        return Optional.ofNullable(manufacturer).map(m -> m.equals(product.getManufacturer())).orElse(false);
    }
}

服务类中的一个方法:

代码语言:javascript
复制
public Set<Product> getProducts(final SearchParameters params) {
    return dao.findAll().stream()
        .filter(params::manufacturerMatches)
        .collect(Collectors.toSet());
}

然后将更多的匹配器方法添加到SearchParameters类中,并将它们作为filter行部署到您的服务中--您可以使用链式过滤器,这样就很简单了。

如果您不熟悉Java8‘S流,.filter(params::manufacturerMatches).filter(product -> params.manufacturerMatches(product))的一个简短的表示法,它反过来将所有产品与manufacturerMatches方法进行比较,并且只有当该方法返回true时才允许产品通过。

应答

为了回答你的问题..。

  1. 如果您对产品的顺序不感兴趣,Sets基本上可以保存您的产品。如果这很重要,您需要使用一些List来代替。但是这并不是您所要求或想知道的,所以:代码中Sets的问题是,您复制或三份三份的大量数据,并操作比您需要的更多的对象来实现您的目标。与简单的Strings或其他类似的参数相比,比较大的产品对象也更昂贵(就CPU周期而言),这对您来说就足够了。您可以将所有对象(Products)都放在一个集合中,只需对其进行筛选。另外,当您在Sets中比较对象时,您需要确保equalsProductshashCode方法始终是最新的--如果您忘记在添加新字段时更新它们,则会得到错误的结果。
  2. 是的,最好只执行一个DB调用--甚至这个调用也可以通过使用缓存来省略。您可以通过创建一个更复杂的DB查询来解释所有的搜索参数,或者通过在Java中处理搜索(筛选)来实现“一次调用”。你应该怎么做,取决于我上面列出的因素,主要是关于你数据库中的产品数量和你的个人喜好。但是我不会真的使用Sets,因为(就像我说的)它们会乘以您拥有的对象的数量,也因为我觉得.retainAll(...)的代码很难读。
票数 4
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/106842

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档