我所关注的问题如下:
Set是获得产品的好选择吗?为此目的,Set有哪些缺点?common.retainAll()的事情,还是通过WHERE请求将产品发送到数据库。现在,我用三个请求:getProductsByCategory、getProductsByManufacturer、getProductsByPrice。因此,最好只制作一个?@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(返回“产品”;}发布于 2015-10-16 23:30:33
好的,我假设这是来自您的@Controller的代码,它调用了一个@Service,服务进一步调用了一个@Repository ( DAO层)。此外,我假设您使用的是最新版本的Java,即Java 8。
最终,我发现这一切都取决于你拥有的产品数量。考虑到不太多,您可以使用Java进行所有的过滤。考虑到成千上万,你最好在数据库里做。
中的一种方法
在任何情况下,一个数据库调用肯定要比三个好得多,所以您只需创建一个足够通用的数据库搜索方法,就可以将所有搜索参数传递给它。创建该方法时,还可以创建一个名为SearchParameters的数据传输对象,该对象包含所有搜索参数。这样,即使使用多个参数进行搜索,您的方法签名也不会增长到可笑的长度。接口也很容易更改,因为为了添加新的搜索参数,方法签名无需更改,只需更改数据传输对象。
我解决了一个类似的问题,只有几十个产品,我的DAO层有一个普通的public List<Product> findAll()方法和一个@Cacheable注释,所以在第一次调用DB之后,进一步的调用只能访问内存中的一个快速缓存。
然后,服务将得到您描述的方法:getProductsByCategory、getProductsByManufacturer和getProductsByPrice,但是它们都只是调用DAO的findAll()方法(快速获取缓存的响应),并根据它们的参数过滤结果。
例如(假设Product类有一个返回String的getManufacturer()方法:
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层进行访问,或者在服务层中这样做。;)
因此,您的业务代码可以归结为这样的内容:
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);
}
}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时才允许产品通过。
为了回答你的问题..。
Sets基本上可以保存您的产品。如果这很重要,您需要使用一些List来代替。但是这并不是您所要求或想知道的,所以:代码中Sets的问题是,您复制或三份三份的大量数据,并操作比您需要的更多的对象来实现您的目标。与简单的Strings或其他类似的参数相比,比较大的产品对象也更昂贵(就CPU周期而言),这对您来说就足够了。您可以将所有对象(Products)都放在一个集合中,只需对其进行筛选。另外,当您在Sets中比较对象时,您需要确保equals和Products的hashCode方法始终是最新的--如果您忘记在添加新字段时更新它们,则会得到错误的结果。Sets,因为(就像我说的)它们会乘以您拥有的对象的数量,也因为我觉得.retainAll(...)的代码很难读。https://codereview.stackexchange.com/questions/106842
复制相似问题