一、组装参数的学习
首先是查询条件,对于查询条件,需要判断是否从前端传递空值?——怎么处理查询空值?
当然可以一个一个进行判断,但是这样代码会导致很多,可以统一处理,形成一个公共方法。
1、 单个处理的方式:
调用工具方法判空(底层:判断是否是null 和空)
/** UtilValidate类. */
/** Check whether string s is NOT empty. */
public static boolean isNotEmpty(String s) {
return (s != null) && s.length() > 0;
}
/** Check whether collection c is NOT empty. */
public static <E> boolean isNotEmpty(Collection<E> c) {
return (c != null) && !c.isEmpty();
}
/** Check whether charsequence c is NOT empty. */
public static <E> boolean isNotEmpty(CharSequence c) {
return ((c != null) && (c.length() > 0));
}
if (UtilValidate.isNotEmpty(startDate)) { condList.add(EntityCondition.makeCondition(PackagePrepayFields.REPAY_APP_DATE, EntityOperator.GREATER_THAN_EQUAL_TO, startDate)); }
2、多个处理:
多个处理需要知道最终需要的是什么数据结构。反向推导
/** Set a list of EntityCondition objects to be ANDed together as the WHERE clause for the query * * NOTE: Each successive call to any of the where(...) methods will replace the currently set condition for the query. * @param fieldMap - A list of EntityCondition objects to be ANDed together as the WHERE clause for the query * @return this EntityQuery object, to enable chaining */ public <T extends EntityCondition> EntityQuery where(List<T> andConditions) { this.whereEntityCondition = EntityCondition.makeCondition(andConditions); return this; }
从上面的API中,可以看到需要的是List<T>,T必须是EntityCondition的子类或者其本身,暂时先使用EntityCondition,所以返回是List<EntityCondition>。
/** * 封装查询条件列表 * * @param arr * @param context 入参上下文 * @author */ public static List<EntityCondition> setConditions(String[] arr, Map<String, ? extends Object> context) { if (arr == null || arr.length <= 0) { return null; } List<EntityCondition> conditionList = new LinkedList<EntityCondition>(); for (int i = 0; i < arr.length; i++) { if (context.get(arr[i]) != null && !context.get(arr[i]).equals("")) { conditionList.add(EntityCondition.makeCondition(arr[i], context.get(arr[i]))); } } return conditionList; }
上述方法中EntityCondition.makeCondition(arr[i],context.get(arr[i]))调用的API如下:
public static <R> EntityExpr makeCondition(String fieldName, R value) { return new EntityExpr(fieldName, EntityOperator.EQUALS, value); }
但是针对非EntityOperator.EQUALS的查询条件,需要自己写。
public static <L,R,LL,RR> EntityExpr makeCondition(L lhs, EntityComparisonOperator<LL,RR> operator, R rhs) { return new EntityExpr(lhs, operator, rhs); }
3、分页处理
Integer viewIndex = ToolsUtil.paraseObjToInteger(context.get(PackagePrepayFields.VIEW_INDEX), 1);
Integer viewSize = ToolsUtil.paraseObjToInteger(context.get(PackagePrepayFields.VIEW_SIZE), 20);
/** * 将Object对象转换为Integer * * @param obj * @param def * @return * @author */ public static Integer paraseObjToInteger(Object obj, Integer def) { if (obj == null || "null".equals(obj)) { return def; } try { return Integer.parseInt(obj.toString()); } catch (Exception e) { throw new RuntimeException("Object{" + obj.toString() + "} parase to Decimal exception!", e); } }
再次,是查询要展示的列,查看API,提供两种方式
/** Set the fields to be returned when the query is executed. * * Note that the select methods are not additive, if a subsequent * call is made to select then the existing fields for selection * will be replaced. * @param fieldsToSelect - A Set of Strings containing the field names to be selected * @return this EntityQuery object, to enable chaining */ public EntityQuery select(Set<String> fieldsToSelect) { this.fieldsToSelect = fieldsToSelect; return this; } /** Set the fields to be returned when the query is executed. * * Note that the select methods are not additive, if a subsequent * call is made to select then the existing fields for selection * will be replaced. * @param fieldsToSelect - Strings containing the field names to be selected * @return this EntityQuery object, to enable chaining */ public EntityQuery select(String...fields) { this.fieldsToSelect = UtilMisc.toSetArray(fields); return this; }
鉴于此代码,包装的更多,使用更简单,public EntityQuery select(String...fields)
String[] columns =
{PackagePrepayFields.CUST_NO, PackagePrepayFields.CUST_NAME, PackagePrepayFields.VEHICLE_NO,
PackagePrepayFields.PLATE_NO, PackagePrepayFields.DOC_NO, PackagePrepayFields.SALE_NAME,
PackagePrepayFields.PENTY_AMT, PackagePrepayFields.PENTY_DEDUCT, PackagePrepayFields.PRIN_AMT,
PackagePrepayFields.AHEAD_AMT, PackagePrepayFields.PAY_MODE, PackagePrepayFields.MAIL_ADDRESS,
PackagePrepayFields.REPAY_APP_DATE, PackagePrepayFields.REPAY_APP_STATUS,
PackagePrepayFields.OPER_NO, PackagePrepayFields.RET_MSG, PackagePrepayFields.REMARK};
当然,我们如果开发过程中,需要再多个地方使用,这块可以提取出来,作为公共方法。
最后我们看一下查询的方法
PagedList<GenericValue> pagedList = EntityQuery.use(delegator) .select(columns) .from(PackagePrepayFields.COM_MESSAGE_INFO_TEXT_THREE) .where(condList) .cursorScrollInsensitive() .queryPagedList(viewIndex - 1, viewSize); result.put("list", pagedList.getData()); result.put("totalSize", pagedList.getSize());
比较一下不分页的
// 不带分页 List<GenericValue> list =EntityQuery.use(delegator) .select(columns) .from(PackagePrepayFields.COM_MESSAGE_INFO_TEXT_THREE) .where(condList) .queryList();
顺便看一下服务(方法名称)对应XML的配置
入参
<attribute name="viewSize" type="Integer" mode="IN" optional="true" description="条数" /> <attribute name="viewIndex" type="Integer" mode="IN" optional="true" description="页码" />
出参
<attribute name="returnCode" type="Map" mode="OUT" optional="true" description="标准返回状态数据"/> <attribute name="totalSize" type="Integer" mode="OUT" optional="true" description="返回总条数" /> <--此处注意出参的大小写 -->