Java tutorial
/* * Copyright 2014 guilin. All rights reserved. * Support: guilin * License: guilin */ package gov.guilin.dao.impl; import gov.guilin.Filter; import gov.guilin.Order; import gov.guilin.Page; import gov.guilin.Pageable; import gov.guilin.Setting; import gov.guilin.dao.GoodsDao; import gov.guilin.dao.ProductDao; import gov.guilin.dao.SnDao; import gov.guilin.entity.Attribute; import gov.guilin.entity.Brand; import gov.guilin.entity.Goods; import gov.guilin.entity.Member; import gov.guilin.entity.Order.OrderStatus; import gov.guilin.entity.Order.PaymentStatus; import gov.guilin.entity.OrderItem; import gov.guilin.entity.Product; import gov.guilin.entity.Product.OrderType; import gov.guilin.entity.ProductCategory; import gov.guilin.entity.Promotion; import gov.guilin.entity.Sn.Type; import gov.guilin.entity.SpecificationValue; import gov.guilin.entity.Supplier; import gov.guilin.entity.Tag; import gov.guilin.util.SettingUtils; import java.math.BigDecimal; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.regex.Pattern; import javax.annotation.Resource; import javax.persistence.FlushModeType; import javax.persistence.NoResultException; import javax.persistence.TypedQuery; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Expression; import javax.persistence.criteria.Join; import javax.persistence.criteria.Path; import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; import javax.persistence.criteria.Subquery; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.builder.CompareToBuilder; import org.springframework.stereotype.Repository; import org.springframework.util.Assert; /** * Dao - ? * * @author guilin * @version */ @Repository("productDaoImpl") public class ProductDaoImpl extends BaseDaoImpl<Product, Long> implements ProductDao { private static final Pattern pattern = Pattern.compile("\\d*"); @Resource(name = "goodsDaoImpl") private GoodsDao goodsDao; @Resource(name = "snDaoImpl") private SnDao snDao; public boolean snExists(String sn) { if (sn == null) { return false; } String jpql = "select count(*) from Product product where lower(product.sn) = lower(:sn)"; Long count = entityManager.createQuery(jpql, Long.class).setFlushMode(FlushModeType.COMMIT) .setParameter("sn", sn).getSingleResult(); return count > 0; } public Product findBySn(String sn) { if (sn == null) { return null; } String jpql = "select product from Product product where lower(product.sn) = lower(:sn)"; try { return entityManager.createQuery(jpql, Product.class).setFlushMode(FlushModeType.COMMIT) .setParameter("sn", sn).getSingleResult(); } catch (NoResultException e) { return null; } } public List<Product> search(String keyword, Boolean isGift, Integer count) { if (StringUtils.isEmpty(keyword)) { return Collections.<Product>emptyList(); } CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); CriteriaQuery<Product> criteriaQuery = criteriaBuilder.createQuery(Product.class); Root<Product> root = criteriaQuery.from(Product.class); criteriaQuery.select(root); Predicate restrictions = criteriaBuilder.conjunction(); if (pattern.matcher(keyword).matches()) { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.or(criteriaBuilder.equal(root.get("id"), Long.valueOf(keyword)), criteriaBuilder.like(root.<String>get("sn"), "%" + keyword + "%"), criteriaBuilder.like(root.<String>get("fullName"), "%" + keyword + "%"))); } else { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.or(criteriaBuilder.like(root.<String>get("sn"), "%" + keyword + "%"), criteriaBuilder.like(root.<String>get("fullName"), "%" + keyword + "%"))); } if (isGift != null) { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("isGift"), isGift)); } criteriaQuery.where(restrictions); criteriaQuery.orderBy(criteriaBuilder.desc(root.get("isTop"))); return super.findList(criteriaQuery, null, count, null, null); } public List<Product> findList(ProductCategory productCategory, Brand brand, Promotion promotion, List<Tag> tags, Map<Attribute, String> attributeValue, BigDecimal startPrice, BigDecimal endPrice, Boolean isMarketable, Boolean isList, Boolean isTop, Boolean isGift, Boolean isOutOfStock, Boolean isStockAlert, OrderType orderType, Integer count, List<Filter> filters, List<Order> orders) { CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); CriteriaQuery<Product> criteriaQuery = criteriaBuilder.createQuery(Product.class); Root<Product> root = criteriaQuery.from(Product.class); criteriaQuery.select(root); Predicate restrictions = criteriaBuilder.conjunction(); if (productCategory != null) { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.or(criteriaBuilder.equal(root.get("productCategory"), productCategory), criteriaBuilder.like(root.get("productCategory").<String>get("treePath"), "%" + ProductCategory.TREE_PATH_SEPARATOR + productCategory.getId() + ProductCategory.TREE_PATH_SEPARATOR + "%"))); } if (brand != null) { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("brand"), brand)); } if (promotion != null) { Subquery<Product> subquery1 = criteriaQuery.subquery(Product.class); Root<Product> subqueryRoot1 = subquery1.from(Product.class); subquery1.select(subqueryRoot1); subquery1.where(criteriaBuilder.equal(subqueryRoot1, root), criteriaBuilder.equal(subqueryRoot1.join("promotions"), promotion)); Subquery<Product> subquery2 = criteriaQuery.subquery(Product.class); Root<Product> subqueryRoot2 = subquery2.from(Product.class); subquery2.select(subqueryRoot2); subquery2.where(criteriaBuilder.equal(subqueryRoot2, root), criteriaBuilder.equal(subqueryRoot2.join("productCategory").join("promotions"), promotion)); Subquery<Product> subquery3 = criteriaQuery.subquery(Product.class); Root<Product> subqueryRoot3 = subquery3.from(Product.class); subquery3.select(subqueryRoot3); subquery3.where(criteriaBuilder.equal(subqueryRoot3, root), criteriaBuilder.equal(subqueryRoot3.join("brand").join("promotions"), promotion)); restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.or(criteriaBuilder.exists(subquery1), criteriaBuilder.exists(subquery2), criteriaBuilder.exists(subquery3))); } if (tags != null && !tags.isEmpty()) { Subquery<Product> subquery = criteriaQuery.subquery(Product.class); Root<Product> subqueryRoot = subquery.from(Product.class); subquery.select(subqueryRoot); subquery.where(criteriaBuilder.equal(subqueryRoot, root), subqueryRoot.join("tags").in(tags)); restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.exists(subquery)); } if (attributeValue != null) { for (Entry<Attribute, String> entry : attributeValue.entrySet()) { String propertyName = Product.ATTRIBUTE_VALUE_PROPERTY_NAME_PREFIX + entry.getKey().getPropertyIndex(); restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get(propertyName), entry.getValue())); } } if (startPrice != null && endPrice != null && startPrice.compareTo(endPrice) > 0) { BigDecimal temp = startPrice; startPrice = endPrice; endPrice = temp; } if (startPrice != null && startPrice.compareTo(new BigDecimal(0)) >= 0) { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.ge(root.<Number>get("price"), startPrice)); } if (endPrice != null && endPrice.compareTo(new BigDecimal(0)) >= 0) { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.le(root.<Number>get("price"), endPrice)); } if (isMarketable != null) { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("isMarketable"), isMarketable)); } if (isList != null) { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("isList"), isList)); } if (isTop != null) { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("isTop"), isTop)); } if (isGift != null) { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("isGift"), isGift)); } Path<Integer> stock = root.get("stock"); Path<Integer> allocatedStock = root.get("allocatedStock"); if (isOutOfStock != null) { if (isOutOfStock) { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.isNotNull(stock), criteriaBuilder.lessThanOrEqualTo(stock, allocatedStock)); } else { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.or(criteriaBuilder.isNull(stock), criteriaBuilder.greaterThan(stock, allocatedStock))); } } if (isStockAlert != null) { Setting setting = SettingUtils.get(); if (isStockAlert) { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.isNotNull(stock), criteriaBuilder.lessThanOrEqualTo(stock, criteriaBuilder.sum(allocatedStock, setting.getStockAlertCount()))); } else { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.or(criteriaBuilder.isNull(stock), criteriaBuilder.greaterThan(stock, criteriaBuilder.sum(allocatedStock, setting.getStockAlertCount())))); } } criteriaQuery.where(restrictions); if (orderType == OrderType.priceAsc) { orders.add(Order.asc("price")); orders.add(Order.desc("createDate")); } else if (orderType == OrderType.priceDesc) { orders.add(Order.desc("price")); orders.add(Order.desc("createDate")); } else if (orderType == OrderType.salesDesc) { orders.add(Order.desc("sales")); orders.add(Order.desc("createDate")); } else if (orderType == OrderType.scoreDesc) { orders.add(Order.desc("score")); orders.add(Order.desc("createDate")); } else if (orderType == OrderType.dateDesc) { orders.add(Order.desc("createDate")); } else { orders.add(Order.desc("isTop")); orders.add(Order.desc("modifyDate")); } return super.findList(criteriaQuery, null, count, filters, orders); } public List<Product> findList(ProductCategory productCategory, Date beginDate, Date endDate, Integer first, Integer count) { CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); CriteriaQuery<Product> criteriaQuery = criteriaBuilder.createQuery(Product.class); Root<Product> root = criteriaQuery.from(Product.class); criteriaQuery.select(root); Predicate restrictions = criteriaBuilder.conjunction(); restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("isMarketable"), true)); if (productCategory != null) { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.or(criteriaBuilder.equal(root.get("productCategory"), productCategory), criteriaBuilder.like(root.get("productCategory").<String>get("treePath"), "%" + ProductCategory.TREE_PATH_SEPARATOR + productCategory.getId() + ProductCategory.TREE_PATH_SEPARATOR + "%"))); } if (beginDate != null) { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.greaterThanOrEqualTo(root.<Date>get("createDate"), beginDate)); } if (endDate != null) { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.lessThanOrEqualTo(root.<Date>get("createDate"), endDate)); } criteriaQuery.where(restrictions); criteriaQuery.orderBy(criteriaBuilder.desc(root.get("isTop"))); return super.findList(criteriaQuery, first, count, null, null); } public List<Product> findList(Goods goods, Set<Product> excludes) { CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); CriteriaQuery<Product> criteriaQuery = criteriaBuilder.createQuery(Product.class); Root<Product> root = criteriaQuery.from(Product.class); criteriaQuery.select(root); Predicate restrictions = criteriaBuilder.conjunction(); if (goods != null) { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("goods"), goods)); } if (excludes != null && !excludes.isEmpty()) { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.not(root.in(excludes))); } criteriaQuery.where(restrictions); return entityManager.createQuery(criteriaQuery).setFlushMode(FlushModeType.COMMIT).getResultList(); } public List<Object[]> findSalesList(Date beginDate, Date endDate, Integer count) { CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); CriteriaQuery<Object[]> criteriaQuery = criteriaBuilder.createQuery(Object[].class); Root<Product> product = criteriaQuery.from(Product.class); Join<Product, OrderItem> orderItems = product.join("orderItems"); Join<Product, gov.guilin.entity.Order> order = orderItems.join("order"); criteriaQuery.multiselect(product.get("id"), product.get("sn"), product.get("name"), product.get("fullName"), product.get("price"), criteriaBuilder.sum(orderItems.<Integer>get("quantity")), criteriaBuilder.sum(criteriaBuilder .prod(orderItems.<Integer>get("quantity"), orderItems.<BigDecimal>get("price")))); Predicate restrictions = criteriaBuilder.conjunction(); if (beginDate != null) { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.greaterThanOrEqualTo(order.<Date>get("createDate"), beginDate)); } if (endDate != null) { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.lessThanOrEqualTo(order.<Date>get("createDate"), endDate)); } restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(order.get("orderStatus"), OrderStatus.completed), criteriaBuilder.equal(order.get("paymentStatus"), PaymentStatus.paid)); criteriaQuery.where(restrictions); criteriaQuery.groupBy(product.get("id"), product.get("sn"), product.get("name"), product.get("fullName"), product.get("price")); criteriaQuery.orderBy(criteriaBuilder.desc(criteriaBuilder.sum( criteriaBuilder.prod(orderItems.<Integer>get("quantity"), orderItems.<BigDecimal>get("price"))))); TypedQuery<Object[]> query = entityManager.createQuery(criteriaQuery).setFlushMode(FlushModeType.COMMIT); if (count != null && count >= 0) { query.setMaxResults(count); } return query.getResultList(); } public Page<Product> findPage(ProductCategory productCategory, Brand brand, Promotion promotion, List<Tag> tags, Map<Attribute, String> attributeValue, BigDecimal startPrice, BigDecimal endPrice, Boolean isMarketable, Boolean isList, Boolean isTop, Boolean isGift, Boolean isOutOfStock, Boolean isStockAlert, OrderType orderType, Pageable pageable) { CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); CriteriaQuery<Product> criteriaQuery = criteriaBuilder.createQuery(Product.class); Root<Product> root = criteriaQuery.from(Product.class); criteriaQuery.select(root); Predicate restrictions = criteriaBuilder.conjunction(); if (productCategory != null) { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.or(criteriaBuilder.equal(root.get("productCategory"), productCategory), criteriaBuilder.like(root.get("productCategory").<String>get("treePath"), "%" + ProductCategory.TREE_PATH_SEPARATOR + productCategory.getId() + ProductCategory.TREE_PATH_SEPARATOR + "%"))); } if (brand != null) { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("brand"), brand)); } if (promotion != null) { Subquery<Product> subquery1 = criteriaQuery.subquery(Product.class); Root<Product> subqueryRoot1 = subquery1.from(Product.class); subquery1.select(subqueryRoot1); subquery1.where(criteriaBuilder.equal(subqueryRoot1, root), criteriaBuilder.equal(subqueryRoot1.join("promotions"), promotion)); Subquery<Product> subquery2 = criteriaQuery.subquery(Product.class); Root<Product> subqueryRoot2 = subquery2.from(Product.class); subquery2.select(subqueryRoot2); subquery2.where(criteriaBuilder.equal(subqueryRoot2, root), criteriaBuilder.equal(subqueryRoot2.join("productCategory").join("promotions"), promotion)); Subquery<Product> subquery3 = criteriaQuery.subquery(Product.class); Root<Product> subqueryRoot3 = subquery3.from(Product.class); subquery3.select(subqueryRoot3); subquery3.where(criteriaBuilder.equal(subqueryRoot3, root), criteriaBuilder.equal(subqueryRoot3.join("brand").join("promotions"), promotion)); restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.or(criteriaBuilder.exists(subquery1), criteriaBuilder.exists(subquery2), criteriaBuilder.exists(subquery3))); } if (tags != null && !tags.isEmpty()) { Subquery<Product> subquery = criteriaQuery.subquery(Product.class); Root<Product> subqueryRoot = subquery.from(Product.class); subquery.select(subqueryRoot); subquery.where(criteriaBuilder.equal(subqueryRoot, root), subqueryRoot.join("tags").in(tags)); restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.exists(subquery)); } if (attributeValue != null) { for (Entry<Attribute, String> entry : attributeValue.entrySet()) { String propertyName = Product.ATTRIBUTE_VALUE_PROPERTY_NAME_PREFIX + entry.getKey().getPropertyIndex(); restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get(propertyName), entry.getValue())); } } if (startPrice != null && endPrice != null && startPrice.compareTo(endPrice) > 0) { BigDecimal temp = startPrice; startPrice = endPrice; endPrice = temp; } if (startPrice != null && startPrice.compareTo(new BigDecimal(0)) >= 0) { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.ge(root.<Number>get("price"), startPrice)); } if (endPrice != null && endPrice.compareTo(new BigDecimal(0)) >= 0) { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.le(root.<Number>get("price"), endPrice)); } if (isMarketable != null) { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("isMarketable"), isMarketable)); } if (isList != null) { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("isList"), isList)); } if (isTop != null) { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("isTop"), isTop)); } if (isGift != null) { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("isGift"), isGift)); } Path<Integer> stock = root.get("stock"); Path<Integer> allocatedStock = root.get("allocatedStock"); if (isOutOfStock != null) { if (isOutOfStock) { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.isNotNull(stock), criteriaBuilder.lessThanOrEqualTo(stock, allocatedStock)); } else { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.or(criteriaBuilder.isNull(stock), criteriaBuilder.greaterThan(stock, allocatedStock))); } } if (isStockAlert != null) { Setting setting = SettingUtils.get(); if (isStockAlert) { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.isNotNull(stock), criteriaBuilder.lessThanOrEqualTo(stock, criteriaBuilder.sum(allocatedStock, setting.getStockAlertCount()))); } else { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.or(criteriaBuilder.isNull(stock), criteriaBuilder.greaterThan(stock, criteriaBuilder.sum(allocatedStock, setting.getStockAlertCount())))); } } criteriaQuery.where(restrictions); List<Order> orders = pageable.getOrders(); if (orderType == OrderType.priceAsc) { orders.add(Order.asc("price")); orders.add(Order.desc("createDate")); } else if (orderType == OrderType.priceDesc) { orders.add(Order.desc("price")); orders.add(Order.desc("createDate")); } else if (orderType == OrderType.salesDesc) { orders.add(Order.desc("sales")); orders.add(Order.desc("createDate")); } else if (orderType == OrderType.scoreDesc) { orders.add(Order.desc("score")); orders.add(Order.desc("createDate")); } else if (orderType == OrderType.dateDesc) { orders.add(Order.desc("createDate")); } else { orders.add(Order.desc("isTop")); orders.add(Order.desc("modifyDate")); } return super.findPage(criteriaQuery, pageable); } public Page<Product> findPage(Member member, Pageable pageable) { if (member == null) { return new Page<Product>(Collections.<Product>emptyList(), 0, pageable); } CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); CriteriaQuery<Product> criteriaQuery = criteriaBuilder.createQuery(Product.class); Root<Product> root = criteriaQuery.from(Product.class); criteriaQuery.select(root); criteriaQuery.where(criteriaBuilder.equal(root.join("favoriteMembers"), member)); return super.findPage(criteriaQuery, pageable); } public Long count(Member favoriteMember, Boolean isMarketable, Boolean isList, Boolean isTop, Boolean isGift, Boolean isOutOfStock, Boolean isStockAlert) { CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); CriteriaQuery<Product> criteriaQuery = criteriaBuilder.createQuery(Product.class); Root<Product> root = criteriaQuery.from(Product.class); criteriaQuery.select(root); Predicate restrictions = criteriaBuilder.conjunction(); if (favoriteMember != null) { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.join("favoriteMembers"), favoriteMember)); } if (isMarketable != null) { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("isMarketable"), isMarketable)); } if (isList != null) { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("isList"), isList)); } if (isTop != null) { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("isTop"), isTop)); } if (isGift != null) { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("isGift"), isGift)); } Path<Integer> stock = root.get("stock"); Path<Integer> allocatedStock = root.get("allocatedStock"); if (isOutOfStock != null) { if (isOutOfStock) { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.isNotNull(stock), criteriaBuilder.lessThanOrEqualTo(stock, allocatedStock)); } else { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.or(criteriaBuilder.isNull(stock), criteriaBuilder.greaterThan(stock, allocatedStock))); } } if (isStockAlert != null) { Setting setting = SettingUtils.get(); if (isStockAlert) { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.isNotNull(stock), criteriaBuilder.lessThanOrEqualTo(stock, criteriaBuilder.sum(allocatedStock, setting.getStockAlertCount()))); } else { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.or(criteriaBuilder.isNull(stock), criteriaBuilder.greaterThan(stock, criteriaBuilder.sum(allocatedStock, setting.getStockAlertCount())))); } } criteriaQuery.where(restrictions); return super.count(criteriaQuery, null); } public boolean isPurchased(Member member, Product product) { if (member == null || product == null) { return false; } String jqpl = "select count(*) from OrderItem orderItem where orderItem.product = :product and orderItem.order.member = :member and orderItem.order.orderStatus = :orderStatus"; Long count = entityManager.createQuery(jqpl, Long.class).setFlushMode(FlushModeType.COMMIT) .setParameter("product", product).setParameter("member", member) .setParameter("orderStatus", OrderStatus.completed).getSingleResult(); return count > 0; } /** * ? * * @param product * ? */ @Override public void persist(Product product) { Assert.notNull(product); setValue(product); super.persist(product); } /** * * * @param product * ? * @return ? */ @Override public Product merge(Product product) { Assert.notNull(product); if (!product.getIsGift()) { String jpql = "delete from GiftItem giftItem where giftItem.gift = :product"; entityManager.createQuery(jpql).setFlushMode(FlushModeType.COMMIT).setParameter("product", product) .executeUpdate(); } if (!product.getIsMarketable() || product.getIsGift()) { String jpql = "delete from CartItem cartItem where cartItem.product = :product"; entityManager.createQuery(jpql).setFlushMode(FlushModeType.COMMIT).setParameter("product", product) .executeUpdate(); } setValue(product); return super.merge(product); } @Override public void remove(Product product) { if (product != null) { Goods goods = product.getGoods(); if (goods != null && goods.getProducts() != null) { goods.getProducts().remove(product); if (goods.getProducts().isEmpty()) { goodsDao.remove(goods); } } } super.remove(product); } /** * * * @param product * ? */ private void setValue(Product product) { if (product == null) { return; } if (StringUtils.isEmpty(product.getSn())) { String sn; do { sn = snDao.generate(Type.product); } while (snExists(sn)); product.setSn(sn); } StringBuffer fullName = new StringBuffer(product.getName()); if (product.getSpecificationValues() != null && !product.getSpecificationValues().isEmpty()) { List<SpecificationValue> specificationValues = new ArrayList<SpecificationValue>( product.getSpecificationValues()); Collections.sort(specificationValues, new Comparator<SpecificationValue>() { public int compare(SpecificationValue a1, SpecificationValue a2) { return new CompareToBuilder().append(a1.getSpecification(), a2.getSpecification()) .toComparison(); } }); fullName.append(Product.FULL_NAME_SPECIFICATION_PREFIX); int i = 0; for (Iterator<SpecificationValue> iterator = specificationValues.iterator(); iterator.hasNext(); i++) { if (i != 0) { fullName.append(Product.FULL_NAME_SPECIFICATION_SEPARATOR); } fullName.append(iterator.next().getName()); } fullName.append(Product.FULL_NAME_SPECIFICATION_SUFFIX); } product.setFullName(fullName.toString()); } public Page<Product> findPage(ProductCategory productCategory, Brand brand, Promotion promotion, List<Tag> tags, Map<Attribute, String> attributeValue, BigDecimal startPrice, BigDecimal endPrice, Boolean isMarketable, Boolean isList, Boolean isTop, Boolean isGift, Boolean isOutOfStock, Boolean isStockAlert, OrderType orderType, Pageable pageable, Set<Supplier> suppliers) { CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); CriteriaQuery<Product> criteriaQuery = criteriaBuilder.createQuery(Product.class); Root<Product> root = criteriaQuery.from(Product.class); criteriaQuery.select(root); Predicate restrictions = criteriaBuilder.conjunction(); if (productCategory != null) { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.or(criteriaBuilder.equal(root.get("productCategory"), productCategory), criteriaBuilder.like(root.get("productCategory").<String>get("treePath"), "%" + ProductCategory.TREE_PATH_SEPARATOR + productCategory.getId() + ProductCategory.TREE_PATH_SEPARATOR + "%"))); } if (brand != null) { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("brand"), brand)); } if (promotion != null) { Subquery<Product> subquery1 = criteriaQuery.subquery(Product.class); Root<Product> subqueryRoot1 = subquery1.from(Product.class); subquery1.select(subqueryRoot1); subquery1.where(criteriaBuilder.equal(subqueryRoot1, root), criteriaBuilder.equal(subqueryRoot1.join("promotions"), promotion)); Subquery<Product> subquery2 = criteriaQuery.subquery(Product.class); Root<Product> subqueryRoot2 = subquery2.from(Product.class); subquery2.select(subqueryRoot2); subquery2.where(criteriaBuilder.equal(subqueryRoot2, root), criteriaBuilder.equal(subqueryRoot2.join("productCategory").join("promotions"), promotion)); Subquery<Product> subquery3 = criteriaQuery.subquery(Product.class); Root<Product> subqueryRoot3 = subquery3.from(Product.class); subquery3.select(subqueryRoot3); subquery3.where(criteriaBuilder.equal(subqueryRoot3, root), criteriaBuilder.equal(subqueryRoot3.join("brand").join("promotions"), promotion)); restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.or(criteriaBuilder.exists(subquery1), criteriaBuilder.exists(subquery2), criteriaBuilder.exists(subquery3))); } if (tags != null && !tags.isEmpty()) { Subquery<Product> subquery = criteriaQuery.subquery(Product.class); Root<Product> subqueryRoot = subquery.from(Product.class); subquery.select(subqueryRoot); subquery.where(criteriaBuilder.equal(subqueryRoot, root), subqueryRoot.join("tags").in(tags)); restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.exists(subquery)); } if (attributeValue != null) { for (Entry<Attribute, String> entry : attributeValue.entrySet()) { String propertyName = Product.ATTRIBUTE_VALUE_PROPERTY_NAME_PREFIX + entry.getKey().getPropertyIndex(); restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get(propertyName), entry.getValue())); } } if (startPrice != null && endPrice != null && startPrice.compareTo(endPrice) > 0) { BigDecimal temp = startPrice; startPrice = endPrice; endPrice = temp; } if (startPrice != null && startPrice.compareTo(new BigDecimal(0)) >= 0) { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.ge(root.<Number>get("price"), startPrice)); } if (endPrice != null && endPrice.compareTo(new BigDecimal(0)) >= 0) { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.le(root.<Number>get("price"), endPrice)); } if (isMarketable != null) { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("isMarketable"), isMarketable)); } if (isList != null) { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("isList"), isList)); } if (isTop != null) { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("isTop"), isTop)); } if (isGift != null) { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(root.get("isGift"), isGift)); } Path<Integer> stock = root.get("stock"); Path<Integer> allocatedStock = root.get("allocatedStock"); if (isOutOfStock != null) { if (isOutOfStock) { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.isNotNull(stock), criteriaBuilder.lessThanOrEqualTo(stock, allocatedStock)); } else { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.or(criteriaBuilder.isNull(stock), criteriaBuilder.greaterThan(stock, allocatedStock))); } } if (isStockAlert != null) { Setting setting = SettingUtils.get(); if (isStockAlert) { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.isNotNull(stock), criteriaBuilder.lessThanOrEqualTo(stock, criteriaBuilder.sum(allocatedStock, setting.getStockAlertCount()))); } else { restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.or(criteriaBuilder.isNull(stock), criteriaBuilder.greaterThan(stock, criteriaBuilder.sum(allocatedStock, setting.getStockAlertCount())))); } } //??ADDbyDanielChen 20140502 if ((suppliers != null) && !(suppliers.isEmpty())) { Expression<Supplier> exp = root.get("supplier"); restrictions = criteriaBuilder.and(restrictions, exp.in(suppliers)); } criteriaQuery.where(restrictions); List<Order> orders = pageable.getOrders(); if (orderType == OrderType.priceAsc) { orders.add(Order.asc("price")); orders.add(Order.desc("createDate")); } else if (orderType == OrderType.priceDesc) { orders.add(Order.desc("price")); orders.add(Order.desc("createDate")); } else if (orderType == OrderType.salesDesc) { orders.add(Order.desc("sales")); orders.add(Order.desc("createDate")); } else if (orderType == OrderType.scoreDesc) { orders.add(Order.desc("score")); orders.add(Order.desc("createDate")); } else if (orderType == OrderType.dateDesc) { orders.add(Order.desc("createDate")); } else { orders.add(Order.desc("isTop")); orders.add(Order.desc("modifyDate")); } return super.findPage(criteriaQuery, pageable); } }