一、思路
通过链式操作和有序集合实现。
二、分页关键实现摘抄
/**
* mongo操作 各项目需配置bean mongoCommonTemplate
*
* @author 漂泊者及其影子
* @date 2016年6月28日
*/
public class MongoOperator {
private static final Logger log = LoggerFactory.getLogger(MongoOperator.class);
protected static MongoTemplate mongoTemplate;
static {
init();
}
public static void init() {
if (ApplicationContextHelper.containsBean("mongoCommonTemplate")) {
mongoTemplate = (MongoTemplate) ApplicationContextHelper.getBean("mongoCommonTemplate");
log.info("mongoTemplate初始化完毕");
} else {
throw new RuntimeException("请在spring中引入mongotemplate,bean名称为mongoCommonTemplate");
}
}
public MongoOperator() {
}
public static <T> List<T> findByQuery(Query query, Class<T> clazz) {
return mongoTemplate.find(query, clazz);
}
/***
* mongo分页查询
*
* @param proNames
* @param operates
* @param values
* @param pageable
* @param clazz
* @return
* @date 2016年6月28日
*/
public static <T> Pagination<T> findByProperty(QueryProperty queryProperty, Pageable pageable, Class<T> clazz) {
Pagination<T> pagination = new Pagination<T>();
PaginationCondition pc = new PaginationCondition(pageable.getPageNumber(), pageable.getPageSize());
int page = pageable.getPageNumber();
int pageSize = pageable.getPageSize();
Query query = new Query();
if (CollectionUtil.isNotEmpty(queryProperty.getProNames())) {
Criteria criteria = createCriteria(queryProperty);
query.addCriteria(criteria);
}
long totalCount = mongoTemplate.count(query, clazz);
query.skip(pc.getOffset());// skip相当于从那条记录开始
query.limit(pc.getPageSize());// 从skip开始,取多少条记录
Sort sort = pageable.getSort();
if (sort != null) {
query.with(sort);
}
List<T> items = mongoTemplate.find(query, clazz);
pagination.setTotal(NumberUtils.toInt(totalCount + "", 0));
int maxPage = 0;
if (totalCount == 0) {
maxPage = 0;
} else if (totalCount <= pageSize) {
maxPage = 1;
} else {
if (pageSize == 0)
pageSize = 10;
maxPage = NumberUtils.toInt(totalCount + "", 0) / pageSize + 1;
}
pagination.setMaxPage(maxPage);
pagination.setItems(items);
pagination.setPage(page);
pagination.setPageSize(pageSize);
return pagination;
}
public static Criteria createCriteria(QueryProperty queryProperty) {
LinkedList<String> proNames = queryProperty.getProNames();
LinkedList<OperateEnum> operates = queryProperty.getOperates();
LinkedList<Object> values = queryProperty.getValues();
Criteria criteria = null;
String proName = null;
OperateEnum operate = null;
Object value = null;
for (int i = 0; i < proNames.size(); i++) {
proName = proNames.get(i);
operate = operates.get(i);
value = values.get(i);
if (i == 0) {
criteria = new Criteria(proName);
} else {
criteria = criteria.and(proName);
}
switch (operate) {
case GT:
criteria.gt(value);
break;
case LT:
criteria.lt(value);
break;
case GTE:
criteria.gte(value);
break;
case LTE:
criteria.lte(value);
break;
case EQ:
criteria.is(value);
break;
case NE:
criteria.ne(value);
break;
case IN:
criteria.in(value);
break;
case NIN:
criteria.nin(value);
break;
case NOT:
criteria.not();
break;
case ALL:
criteria.all(value);
break;
case REGEX:
criteria.regex(escapeRegexString(String.valueOf(value)), "i");
break;
case BETWEENLONG:
String val = String.valueOf(value);
long from = NumberUtils.toLong(val.split(",")[0]);
long to = NumberUtils.toLong(val.split(",")[1]);
criteria.gte(from).lte(to);
break;
default:
criteria.is(value);
break;
}
}
return criteria;
}
/**
* 把字符串中含有正则表达式特殊意义的字符转义
* @param value
* @return
*/
public static String escapeRegexString(String value){
final char[] reserved={'.','$','^','{','}','[',']','(',')','|','*','+','?','\\'};
char c;
boolean bingo=false;
StringBuilder sb=new StringBuilder(value);
for(int i=0; i<sb.length(); i++){
bingo=false;
c=sb.charAt(i);
for(int j=0; j<reserved.length; j++){
if(c==reserved[j]){
bingo=true;
break;
}
}
if(bingo){
sb.insert(i, '\\');
i++;
}
}
return sb.toString();
}
/**
* @param proName
* @param operat
* @param value
* @return
*/
public static Criteria createCriteria(String proName, OperateEnum operat, Object value) {
Criteria criteria = Criteria.where(proName);
switch (operat) {
case GT:
criteria.gt(value);
break;
case LT:
criteria.lt(value);
break;
case GTE:
criteria.gte(value);
break;
case LTE:
criteria.lte(value);
break;
case EQ:
criteria.is(value);
break;
case NE:
criteria.ne(value);
break;
case IN:
if (value instanceof Collection) {
criteria.in((Collection<?>) value);
} else if (value.getClass().isArray()) {
Object[] array = (Object[]) value;
criteria.in(Arrays.asList(array));
} else {
criteria.in(value);
}
break;
case NIN:
if (value instanceof Collection) {
criteria.nin((Collection<?>) value);
} else if (value.getClass().isArray()) {
Object[] array = (Object[]) value;
criteria.nin(Arrays.asList(array));
} else {
criteria.nin(value);
}
break;
case NOT:
criteria.not();
break;
case ALL:
criteria.all(value);
break;
case REGEX:
criteria.regex(escapeRegexString(String.valueOf(value)), "i");
break;
case BETWEENLONG:
String val = String.valueOf(value);
long from = NumberUtils.toLong(val.split(",")[0]);
long to = NumberUtils.toLong(val.split(",")[1]);
criteria.gte(from).lte(to);
break;
default:
criteria.is(value);
break;
}
return criteria;
}
}
操作枚举
package com.iflashbuy.base.repository.mongo;
/**
* mongo分页查询封装
*
* @author 漂泊者及其影子
* @date 2016年6月28日
*/
public enum OperateEnum {
GT("$gt"), LT("$lt"), GTE("$gte"), LTE("$lte"), EQ("$eq"), NE("$ne"), IN("$in"), NIN("$nin"), ALL("$all"), NOT(
"$not"), REGEX("$lte"), BETWEENLONG("此操作mongoTemplate中没有自己封装,依照betweenlong可以类推betweenDate,betweenint等between的比较");
private String op;
OperateEnum(String op) {
this.op = op;
}
@Override
public String toString() {
return op;
}
public String getValue() {
return op;
}
}
支持链式操作的QueryProperty类设计,对象里面放置容器对象,从而实现链式操作,mongoTemplate的源码中有很多类似的设计。
public class QueryProperty {
private LinkedList<String> proNames = new LinkedList<String>();
private LinkedList<OperateEnum> operates = new LinkedList<OperateEnum>();
private LinkedList<Object> values = new LinkedList<Object>();
public LinkedList<String> getProNames() {
return proNames;
}
public LinkedList<OperateEnum> getOperates() {
return operates;
}
public LinkedList<Object> getValues() {
return values;
}
public QueryProperty addQueryProperties(String proName, OperateEnum operate, Object value) {
if (StringUtil.isNotEmpty(proName)) {
proNames.add(proName);
operates.add(operate);
values.add(value);
}
return this;
}
}
三、调用例子
String batchNum = codeUseParam.getBatchNum();
int page = codeUseParam.getPage();
int pageSize = codeUseParam.getPageSize();
String entId = codeUseParam.getEntId();
String remark = codeUseParam.getRemark();
String businessId = codeUseParam.getBusinessId();
String dateFrom = codeUseParam.getDateFrom();
String dateTo = codeUseParam.getDateTo();
Pagination<ZcodeAssignInfo> pagination = new Pagination<ZcodeAssignInfo>();
List<ZcodeAssignInfo> zcodeAssignInfos = null;
QueryProperty queryProperty = new QueryProperty();
if(StringUtil.isNotEmpty(entId)) {
queryProperty.addQueryProperties("entId", OperateEnum.EQ, NumberUtils.toInt(entId, -1));
}
if(StringUtil.isNotEmpty(businessId)) {
queryProperty.addQueryProperties("businessId", OperateEnum.EQ, NumberUtils.toInt(businessId, -1));
}
if(StringUtil.isNotEmpty(remark)) {
queryProperty.addQueryProperties("activateRemark", OperateEnum.EQ, remark);
}
queryProperty.addQueryProperties("batchOrderNum", OperateEnum.EQ, batchNum);
queryProperty.addQueryProperties("activateStatus", OperateEnum.EQ, 1);
if (StringUtil.isNotEmpty(dateFrom) && StringUtil.isNotEmpty(dateTo)) {
queryProperty.addQueryProperties("activateTime", OperateEnum.BETWEENLONG,DateUtil.getLongTypedTimeFromTimeStr(dateFrom + " 00:00:00", DateUtil.DATETIME_FORMAT) + "," + DateUtil.getLongTypedTimeFromTimeStr(dateTo + " 23:59:59", DateUtil.DATETIME_FORMAT));
} else if (StringUtil.isNotEmpty(dateFrom)) {
queryProperty.addQueryProperties("activateTime", OperateEnum.GTE, DateUtil.getLongTypedTimeFromTimeStr(dateFrom + " 00:00:00", DateUtil.DATETIME_FORMAT));
} else if (StringUtil.isNotEmpty(dateTo)) {
queryProperty.addQueryProperties("activateTime", OperateEnum.LTE, DateUtil.getLongTypedTimeFromTimeStr(dateTo + " 23:59:59", DateUtil.DATETIME_FORMAT));
}
Pageable pageable = new PageRequest(page, pageSize, new Sort(new Sort.Order(Sort.Direction.DESC, "createTime")));
Pagination<CodeDeactive> codeDeactivatePage = MongoOperator.findByProperty(queryProperty, pageable, CodeDeactive.class);
四、亮点
1、通过mongoTemplate实现
2、关于QueryProperty容器对象的设计
3、实现between的功能
4、操作枚举的设计
5、like的实现
来源:oschina
链接:https://my.oschina.net/u/1265394/blog/702311