public class ProductQueryDTO extends PagedQueryParam { private String queryKey; private int classifyId; private int regionId; private String startTime; private String endTime; //最小价格 private int minValue; //最大價格 private int maxValue; private Map<String, FilterRule[]> attibuteFilters; public ProductQueryDTO() { attibuteFilters = new HashMap<>(); } }
public class FilterRule { private String key; private String operate; private String value; public FilterRule(){} public FilterRule(String key,String operate,String value) { this.key = key; this.operate = operate; this.value = value; } public FilterRule(String key,String value) { this(key, FilterOperate.EQUAL, value); } }
public interface FilterOperate { String AND = "and"; String OR = "or"; String EQUAL = "equal"; String NOTEQUAL = "notequal"; String LESS = "less"; String LESSOREQUAL = "lessorequal"; String GREATER = "greater"; String GREATEROREQUAL = "greaterorequal"; String STARTWITH = "startswith"; String ENDWITH = "endwith"; String CONTAINS = "contains"; }
public class PagedQueryParam { private String sortField; private int sortDirection;//0:正序;1:倒序 private int pageIndex; private int pageSize; public PagedQueryParam(){} public PagedQueryParam(int pageIndex,int pageSize) { this(pageIndex, pageSize, "id"); } public PagedQueryParam(int pageIndex,int pageSize,String sortField) { this(pageIndex, pageSize, sortField, 1); } public PagedQueryParam(int pageIndex,int pageSize,String sortField,int sortDirection) { this.pageIndex = pageIndex; this.pageSize = pageSize; this.sortField = sortField; this.sortDirection = sortDirection; } }
public class ProductResultDTO { private Long id; private String name; private String cover; private String pcCover; private float price; private float originPrice; private int browseNo; private int praiseNo; private int commentNo; private int classifyId; private Map<String,String> attribute; private List<String> assets; public ProductResultDTO() { attribute = new HashMap<>(); } }
public class QueryProductProvider { private static final Map<String, String> OperateMap; static { OperateMap = new HashMap<>(); OperateMap.put(FilterOperate.EQUAL, "="); OperateMap.put(FilterOperate.NOTEQUAL, "!="); OperateMap.put(FilterOperate.LESS, "<"); OperateMap.put(FilterOperate.LESSOREQUAL, "<="); OperateMap.put(FilterOperate.GREATER, ">"); OperateMap.put(FilterOperate.GREATEROREQUAL, ">="); } public String QueryProductBriefList(ProductQueryDTO query) { StringBuilder sql = new StringBuilder(); sql.append("SELECT Id AS id,Name AS name,Cover AS cover,PcCover as pcCover, Price AS price,[OriginPrice] AS originPrice,BrowsingNumber AS browseNo," + "PointOfPraise AS priseNo,CommentNo AS commentNo,CommodityScore as commodityScore," + "TotalScore as totalScore,ClassifyId as classifyId " + "FROM Product_Product AS P"); sql.append(where(query)); String sortField = "OrderNo"; int sortDirection = ListSortDirection.ASC;//默認正序 if (!StringHelper.isNullOrWhiteSpace(query.getSortField())) { sortField = StringHelper.toPascalCase(query.getSortField()); sortDirection = query.getSortDirection(); } sql.append(" ORDER BY " + sortField + ""); if (sortDirection == ListSortDirection.DESC) { sql.append(" DESC"); } int pageIndex = query.getPageIndex(); int pageSize = query.getPageSize(); if (pageIndex <= 0) pageIndex = 1; if (pageSize <= 0 || pageSize > 50) pageSize = 15;//一次查詢最多獲取50條數據,15爲默認每頁數量。 sql.append(" OFFSET " + (pageIndex - 1) * pageSize + " ROWS FETCH NEXT " + pageSize + " ROWS ONLY"); return sql.toString(); } private String where(ProductQueryDTO query) { StringBuilder sql = new StringBuilder(); sql.append(" WHERE IsOnShelf=1 AND IsDeleted=0"); int classifyId = query.getClassifyId(); if (classifyId > 0) { sql.append(" AND ClassifyId = #{classifyId}"); } String queryKey = query.getQueryKey(); if (!StringHelper.isNullOrWhiteSpace(queryKey)) { sql.append(" AND Name LIKE '%'+#{queryKey}+'%'"); } Integer minValue=query.getMinValue(); if(minValue>0){ sql.append(" AND Price>= #{minValue}"); } Integer maxValue=query.getMaxValue(); if(maxValue>0){ sql.append(" AND Price<= #{maxValue}"); } Integer regionId=query.getRegionId(); if(regionId>0){ sql.append(" AND Id in (select productId from Product_RegionMap where RegionId= #{regionId})"); } String startTime = query.getStartTime(); String endTime = query.getEndTime(); //若是開始時間與結束時間全都爲空,則設置爲當前時間 if (StringHelper.isNullOrWhiteSpace(startTime) && StringHelper.isNullOrWhiteSpace(endTime)) { String currentTime = DateHelper.getCurrentDateString(null); startTime = currentTime; endTime = currentTime; } if (!StringHelper.isNullOrWhiteSpace(startTime)) { sql.append(" AND OnShelfTime <= '" + startTime + "'"); } if (!StringHelper.isNullOrWhiteSpace(endTime)) { sql.append(" AND OffShelfTime >= '" + endTime + "'"); } Map<String, FilterRule[]> attributeMap = query.getAttibuteFilters(); for (String key : attributeMap.keySet()) { String ruleSql = ""; FilterRule[] rules = attributeMap.get(key); for (FilterRule rule : rules) { String value = rule.getValue(); if (StringHelper.isNullOrWhiteSpace(value)) continue; if (!OperateMap.containsKey(rule.getOperate())) { rule.setOperate(FilterOperate.EQUAL); } //以逗號包裹的值查詢選項Id if (value.startsWith(",") && value.endsWith(",")) { ruleSql += " AND AttributeOptionIds like '%" + value + "%'"; } else { ruleSql += " AND value " + OperateMap.get(rule.getOperate()) + " '" + value + "'"; } } if (!StringHelper.isNullOrWhiteSpace(ruleSql)) { sql.append(" AND EXISTS (SELECT 1 FROM Product_ProductAttribute WHERE AttributeId IN (SELECT Id FROM Product_Attribute WHERE [Key] = '" + key + "') " + ruleSql + " AND ProductId = P.Id )"); } } return sql.toString(); } }
再根據查詢出的id集合查詢所需的屬性集合:html
public class QueryProductAttributeProvider extends AbstractMybatisProvider { public String QueryProductAttributes(long[] ids, String[] keys) { StringBuilder sql = new StringBuilder(); sql.append("SELECT PA.[ProductId] AS id,A.[Key] AS [key],PA.[Value] AS value\n" + "FROM [dbo].[Product_ProductAttribute] AS PA \n" + "LEFT JOIN [dbo].[Product_Attribute] AS A ON PA.[AttributeId]=A.[Id]\n" + "WHERE PA.ProductId IN (" + ExpandIdAndToString(ids) + ") AND A.[Key] IN (" + ExpandKeysAndToString(keys) + ")"); return sql.toString(); } }
組裝:java
/** * 通用的商品查詢,支持屬性自動組裝 * * @param query 篩選條件 * @param attributeKeys 須要查詢並自動組裝的屬性Key * @return */ public List<ProductResultDTO> queryProductList(ProductQueryDTO query, String[] attributeKeys) { List<ProductResultDTO> result = productMapper.QueryProductBriefList(query); Collection<Long> idList = CollectionHelper.init(result).select(p -> p.getId()); long[] ids = idList.stream().mapToLong(t -> t.longValue()).toArray(); if (ids.length > 0 && attributeKeys != null && attributeKeys.length > 0) { Map<Long, Map<String, String>> productAttributeMap = new HashMap<>(); List<AttributeValueDTO> attributes = productAttributeMapMapper.getProductAttributeValues(ids, attributeKeys); for (AttributeValueDTO attribute : attributes) { if (!productAttributeMap.containsKey(attribute.getId())) { productAttributeMap.put(attribute.getId(), getEmptyAttributeKeyMap(attributeKeys)); } productAttributeMap.get(attribute.getId()).put(StringHelper.toCamelCase(attribute.getKey()), StringHelper.trim(attribute.getValue(), ',')); } for (ProductResultDTO product : result) { Map<String, String> attributeMap = productAttributeMap.containsKey(product.getId()) ? productAttributeMap.get(product.getId()) : getEmptyAttributeKeyMap(attributeKeys); product.setAttribute(attributeMap); } } return result; }