在本次关于GPS优化需求项目时,发现相关功能菜单查询页面共同一个DAO接口实现类,紧接着我看了一下listAll,pre,next,countAll方法业务代码高度相似,
此已说明该DAO扮演着非单一原则,其承担着 系统多个功能菜单的查询功能。
A.共同之处,就是查询共同表 ca_app_info,或者操作共同Hibernate对象VCaAppInfo。
B.不同之处体现如下方面:1、包含HQL和SQL查询 。2、where条件不同(为了过滤数据以及根据页面表单条件动态判断拼加成一个StringBuffer对象(即SQL/HQL))。
而涉及查询的四个方法中(listAll,pre,next,countAll方法业务代码高度相似),代码冗余,不利于维护。
因此,借此机遇,对涉及本期需求GPS查询 四个页面进行重构,提炼出四个单据的实现类,统一继承抽象类,内部维护相关SQL或者HQL查询逻辑,调用方只需构造上线文,
产生不同的实现类即可,提高可扩展,可维护性。重构前代码,点击链接,查看方法:listAll,pre,next,countAll,你就晓得了。
源代码片段:这代码多么。。。
@Override
public List<VCaAppInfo> pre(VCaAppInfoId ci, int pn, int defaultPageSize) {
// TODO Auto-generated method stub
StringBuffer sb = new StringBuffer();
sb.append("from VCaAppInfo v where 1=1");
List<Object> listParams = new ArrayList<Object>();
AbstractWhereExecutor<VCaAppInfoId> whereExecutor;
WhereContext whereContext = new WhereContext(ci,sb,listParams,WhereContext.Strategy.HQL);
String status = ci.getStatus();
if (StringUtil.checkStatus(status)) {
sb.append(" and v.id.status in (?)");
listParams.add(status);
sb.append(" and v.AUserId=? ");
listParams.add(ci.getUser().getUserId());
/*
* if("23".equals(status)){ //根据REFUSE_STATUS拒绝状态查询
* sb.append(" and v.refuseStatus in (?)");
* listParams.add(ci.getRefusestatus()); }else
* if("24".equals(status)){ sb.append(" and v.refuseStatus <> 3"); }
*/
if ("23".equals(status)) { // 根据REFUSE_STATUS拒绝状态查询
sb.append(" and v.refuseStatus in (?)");
listParams.add(ci.getRefusestatus());
} else if ("24".equals(status) && !"3".equals(ci.getRefusestatus())) { // refusestatus
// =
// 0
// 1
// 终审
sb.append(" and v.refuseStatus <> 3");
} else if ("3".equals(ci.getRefusestatus())) { // 3 复核拒绝
sb.append(" and v.refuseStatus = 3");
}
} else if ("80".equals(ci.getStatus())) { // 复审审批页面 显示自己审批的和信贷经理退回审批的
// 150123
sb.append(" and v.id.status in('23','30')");
sb.append(" and v.AUserId=? ");
listParams.add(ci.getUser().getUserId());
} else if ("-27".equals(status)) { // 经销商上传GPS安装单 150302
sb.append(" and (v.isGps ='0' or v.isGps ='2') and v.gpsFee<>0 and v.gpsFee !='' and v.gpsFee is not null and v.manageApprovalTime is not null and v.id.status not in('11','12') ");
// 经销商用户只能查看该门店单子 其他用户查看所有
Set<SyUserDealer> ds = ci.getUser().getSyUserDealers();
if (ds.size() != 0) {
sb.append(" and v.id.dealerCode in(");
Iterator<SyUserDealer> it = ci.getUser().getSyUserDealers()
.iterator();
while (it.hasNext()) {
SyUserDealer d = it.next();
int dealerCode = d.getId().getDealerCode();
sb.append(dealerCode + " ,");
}
String allhql = sb.substring(0, sb.length() - 1);
allhql += ") ";
sb.setLength(0);// 清空 后加上
sb.append(allhql);
}
} else if ("-28".equals(status)) { // GPS维护 已上传GPS安装
whereExecutor = new InstalledGpsQueryExecutor(whereContext);
whereExecutor.execute();
} else if ("-29".equals(status)) { // GPS维护
whereExecutor = new UnInstallGpsQueryExecutor(whereContext);
whereExecutor.execute();
} else if ("-30".equals(status)) { // 贷后资料维护
sb.append(" and (v.ALOANARRIVE is null or v.ALOANARRIVE!='1') and v.id.status='32' ");
if (ci.getIsOld() != null) {
sb.append(" and v.isOld=? ");
listParams.add(ci.getIsOld());
}
if (ci.getPostLoanStatus() != null) {// 新车贷后资料上传状态(包括花乡的二手车 即先放款后抵押)
if ("0".equals(ci.getPostLoanStatus())) {// 未上传
sb.append(" and (v.postLoanStatus is null or v.postLoanStatus='0' ) ");
} else if ("1".equals(ci.getPostLoanStatus())) {// 已上传
sb.append(" and v.postLoanStatus='1' ");
} else if ("2".equals(ci.getPostLoanStatus())) {// 审批退回
sb.append(" and v.postLoanStatus='2' ");
} else if ("3".equals(ci.getPostLoanStatus())) {// 审批通过
sb.append(" and v.postLoanStatus='3' ");
}
}
} else if ("-31".equals(status)) { // 贷后资料维护回退
sb.append(" and v.ALOANARRIVE='1' and v.id.status='32' ");
} else if ("-32".equals(status)) { // 新车等待上传贷后资料
sb.append(" and v.id.status='32' and ifnull(v.ALOANARRIVE,'')!='1' ");
if (ci.getIsOld() != null) {
sb.append(" and v.isOld=? ");
listParams.add(ci.getIsOld());
}
if (ci.getPostLoanStatus() != null) {
if ("0".equals(ci.getPostLoanStatus())) {// 未上传
sb.append(" and (v.postLoanStatus is null or v.postLoanStatus='0') ");
} else if ("1".equals(ci.getPostLoanStatus())) {// 已上传
sb.append(" and v.postLoanStatus='1' ");
} else if ("2".equals(ci.getPostLoanStatus())) {// 审批退回
sb.append(" and v.postLoanStatus='2' ");
} else if ("3".equals(ci.getPostLoanStatus())) {// 审批通过
sb.append(" and v.postLoanStatus='3' ");
}
} else {
sb.append(" and ifnull(v.postLoanStatus,'')!='1' and ifnull(v.postLoanStatus,'')!='3' ");// 所有,不显示已上传的申请单和审批通过的
}
// 经销商用户只能查看该门店单子 其他用户查看所有
Set<SyUserDealer> ds = ci.getUser().getSyUserDealers();
if (ds.size() != 0) {
sb.append(" and v.id.dealerCode in(");
Iterator<SyUserDealer> it = ci.getUser().getSyUserDealers()
.iterator();
while (it.hasNext()) {
SyUserDealer d = it.next();
int dealerCode = d.getId().getDealerCode();
sb.append(dealerCode + " ,");
}
String allhql = sb.substring(0, sb.length() - 1);
allhql += ") ";
sb.setLength(0);// 清空 后加上
sb.append(allhql);
}
} else if ("-33".equals(status)) {// 经销商GPS安装列表,TODO zhaozhaoxin
// 20170411 add
sb.append(" and v.gpsFee<>0 and v.gpsFee !='' and v.gpsFee is not null and v.manageApprovalTime is not null and status in('15','16','17','18','19','25','26','27','28','29','32') ");
// 经销商用户只能查看该门店单子 其他用户查看所有
Set<SyUserDealer> ds = ci.getUser().getSyUserDealers();
if (ds.size() != 0) {
sb.append(" and v.id.dealerCode in(");
Iterator<SyUserDealer> it = ci.getUser().getSyUserDealers()
.iterator();
while (it.hasNext()) {
SyUserDealer d = it.next();
int dealerCode = d.getId().getDealerCode();
sb.append(dealerCode + " ,");
}
String allhql = sb.substring(0, sb.length() - 1);
allhql += ") ";
sb.setLength(0);// 清空 后加上
sb.append(allhql);
}
} else {
sb.append(" and v.id.status in (?)");
listParams.add(status);
// TODO zhaozhaoxin 20170308 add 进行分组查询
if (isRoleQueryData(ci.getUser())) {
getUserGroupIds(sb, ci.getUser(), status, true);
} else {
return null;
}
}
if (ci.getFlowSeq() != null) {
sb.append(" and v.flowSeq= ?");
listParams.add(ci.getFlowSeq());
}
if (ci.getDealerName() != null) {
sb.append(" and v.id.dealerName like ?");
listParams.add("%" + ci.getDealerName() + "%");
}
if (ci.getAppCode() != null) {
sb.append(" and v.id.appCode = ?");
listParams.add(ci.getAppCode());
}
if (ci.getProppserName() != null) {
sb.append(" and v.id.proppserName like ?");
listParams.add("%" + ci.getProppserName() + "%");
}
if (ci.getIsLcv() != null) {
sb.append(" and v.isLcv = ?");
listParams.add(ci.getIsLcv());
}
if (ci.getAppTime() != null) {
sb.append(" and date_format(v.id.appTime,'%Y%m%d') >= ?");
listParams.add(DateUtil.getDateFormatE(ci.getAppTime()));
}
if (ci.getAppTime2() != null) {
sb.append(" and date_format(v.id.appTime,'%Y%m%d') <= ?");
listParams.add(DateUtil.getDateFormatE(ci.getAppTime2()));
}
if (ci.getUpdateTime1() != null) {
sb.append(" and date_format(v.updateTime,'%Y%m%d') >= ?");
listParams.add(DateUtil.getDateFormatE(ci.getUpdateTime1()));
}
if (ci.getUpdateTime2() != null) {
sb.append(" and date_format(v.updateTime,'%Y%m%d') <= ?");
listParams.add(DateUtil.getDateFormatE(ci.getUpdateTime2()));
}
if (ci.getLoanDate1() != null) {
sb.append(" and date_format(v.loanTime,'%Y%m%d') >= ?");
listParams.add(DateUtil.getDateFormatE(ci.getLoanDate1()));
}
if (ci.getLoanDate2() != null) {
sb.append(" and date_format(v.loanTime,'%Y%m%d') <= ?");
listParams.add(DateUtil.getDateFormatE(ci.getLoanDate2()));
}
sb.append(" order by v.updateTime asc");// 从小到大排序 先提交的在前面
List<VCaAppInfo> result = queryByHql(sb.toString(), pn,
defaultPageSize, listParams.toArray());
return result;
}
涉及四个系统功能菜单
1、车贷申请管理》待上传GPS安装单
2、车贷申请管理》GPS安装单列表
3、车贷审批管理》GPS安装单未上传
4、车贷审批管理》GPS安装单已上传
1、相关类图
1.1、executor类图
1.2、context类图
2、相关源码
2.1、抽象类:AbstractWhereExecutor
public abstract class AbstractWhereExecutor<T> implements Predicate<WhereContext> {
/**
* 上线文
*/
protected WhereContext<T> context;
/**
* 参数DTO
*/
protected T dto;
/**
* 查询条件
*/
protected StringBuffer queryWhere;
/**
* 构造函数
* @param context 上线文对象
*/
public AbstractWhereExecutor(WhereContext<T> context) {
this.context = context;
}
/**
* 处理接口
*/
public void execute() {
this.execute((e)->{});
}
/**
* 处理接口
* @param after
*/
public void execute(Consumer<WhereContext> after) {
// 初始化
this.prepare();
// 检查参数
this.check(context);
// 执行鉴定
if(this.test(context)){
switch (context.getStrategy()){
case SQL:
sql();
break;
case HQL:
hql();
break;
default:
break;
}
}
// 后置处理
after.accept(context);
}
/**
* 参数检查
* @param context
*/
protected void check(WhereContext context){
Assert.notNull(context.getDto(),"DTO对象为空");
Assert.notNull(context.getStrategy(),"strategy为空");
}
/**
* 初始化参数
*/
protected void prepare(){
this.dto = this.context.getDto();
this.queryWhere = this.context.getQueryWhere();
}
/**
* 由子类实现具体处理SQL条件
*/
protected abstract void sql();
/**
* 由子类实现具体处理HQL条件
*/
protected abstract void hql();
}
2.2、实现类:InstalledGpsQueryExecutor
public class InstalledGpsQueryExecutor extends AbstractWhereExecutor<VCaAppInfoId> {
/**
* 标示
*/
protected String gpsFlow;
/**
* 审批人
*/
protected Integer approvalUserId;
/**
* 构造函数
*
* @param context 上线文对象
*/
public InstalledGpsQueryExecutor(WhereContext context) {
super(context);
}
@Override
protected void check(WhereContext context) {
super.check(context);
SyUser sessionUser = dto.getUser();
Assert.notNull(sessionUser,"sessionUser为空");
}
@Override
protected void prepare() {
super.prepare();
this.gpsFlow = dto.getGpsFlow();
this.approvalUserId = dto.getUser().getUserId();
}
@Override
protected void sql() {
VCaAppInfoId dto = super.dto;
StringBuffer where = super.queryWhere;
if(this.isMine()){
where.append(" and exists(select 1 from ca_gps_flow f where f.app_code = v.app_code and f.flow_step = 0 and f.approval_user_id = "+this.approvalUserId+") ");
}
where.append(" and v.status not in (11,13) and v.is_Gps ='2' and v.gps_Fee<>0 and v.gps_Fee !='' and v.gps_Fee is not null and v.manage_Approval_Time is not null");
if(!StringUtil.isBlank(dto.getProvince())){
where.append(" and exists(select 1 from Sy_Dealer dr where dr.province = '"+dto.getProvince()+"' and dr.dealer_Code = v.dealer_Code) ");
}
if (!StringUtil.isBlank(dto.getPostLoanStatus())) {
//由于manual_audit_code多个时以";"分割,所以需要使用FIND_IN_SET函数处理 add by 石冬冬 on 2017/9/21
where.append(" and v.app_code IN (SELECT app_code FROM Ca_Car_Gps WHERE del_status=1 and FIND_IN_SET ("+dto.getPostLoanStatus()+",replace(manual_audit_code,';',','))>0 ");
where.append(" GROUP BY app_code) ");
}
}
@Override
protected void hql() {
VCaAppInfoId dto = super.dto;
StringBuffer where = super.queryWhere;
if(this.isMine()){
where.append(" and exists(select 1 from CaGpsFlow f where f.appCode = v.id.appCode and f.flowStep = 0 and f.approvalUserId = " + this.approvalUserId+")");
}
where.append(" and v.id.status not in (11,13) and v.isGps ='2' and v.gpsFee<>0 and v.gpsFee !='' and v.gpsFee is not null and v.manageApprovalTime is not null");
if(!StringUtil.isBlank(dto.getProvince())){
where.append(" and exists(select 1 from SyDealer dr where dr.province = '"+dto.getProvince()+"' and dr.dealerCode = v.id.dealerCode) ");
}
if (!StringUtil.isBlank(dto.getPostLoanStatus())) {
//由于manual_audit_code多个时以";"分割,所以需要使用FIND_IN_SET函数处理 add by 石冬冬 on 2017/9/21
where.append(" and v.id.appCode IN (SELECT appCode FROM CaCarGps WHERE delStatus=1 and find_in_set("+dto.getPostLoanStatus()+",replace(manualAuditCode,';',','))>0 ");
where.append(" GROUP BY appCode) ");
}
}
@Override
public boolean test(WhereContext context) {
VCaAppInfoId dto = (VCaAppInfoId)context.getDto();
return "-28".equals(dto.getStatus());
}
private boolean isMine(){
return "mine".equals(gpsFlow);
}
}
2.3、实现类:TobeUploadGpsQueryExecutor
public class TobeUploadGpsQueryExecutor extends AbstractWhereExecutor<VCaAppInfoId> {
/**
* 构造函数
*
* @param context 上线文对象
*/
public TobeUploadGpsQueryExecutor(WhereContext context) {
super(context);
}
@Override
protected void check(WhereContext context) {
super.check(context);
SyUser sessionUser = dto.getUser();
Assert.notNull(sessionUser,"sessionUser为空");
}
@Override
protected void sql() {
StringBuffer where = super.queryWhere;
SyUser sessionUser = dto.getUser();
where.append(" and (v.is_Gps ='0' or v.is_Gps ='2') and v.gps_Fee<>0 and v.gps_Fee !='' and v.gps_Fee is not null and v.manage_Approval_Time is not null and v.status not in('11','12') ");
GpsUtil.appendDealerCodes(sessionUser,(list) -> {
String condition = MessageFormat.format(" and v.dealer_Code in({0})", StringUtils.join(list,","));
where.append(condition);
});
}
@Override
protected void hql() {
StringBuffer where = super.queryWhere;
SyUser sessionUser = dto.getUser();
where.append(" and (v.isGps ='0' or v.isGps ='2') and v.gpsFee<>0 and v.gpsFee !='' and v.gpsFee is not null and v.manageApprovalTime is not null and v.id.status not in('11','12') ");
GpsUtil.appendDealerCodes(sessionUser,(list) -> {
String condition = MessageFormat.format(" and v.id.dealerCode in({0})", StringUtils.join(list,","));
where.append(condition);
});
}
@Override
public boolean test(WhereContext context) {
VCaAppInfoId dto = (VCaAppInfoId)context.getDto();
return "-27".equals(dto.getStatus());
}
}
2.4、实现类:UnInstalledGpsQueryExecutor
/**
* @description: 车贷审批管理》GPS安装单未上传
* @Date : 上午10:17 2017/11/17
* @Author : 石冬冬-Heil Hitler([email protected])
*/
public class UnInstalledGpsQueryExecutor extends AbstractWhereExecutor<VCaAppInfoId> {
/**
* 标示
*/
protected String gpsFlow;
/**
* 审批人
*/
protected Integer approvalUserId;
/**
* 构造函数
*
* @param context 上线文对象
*/
public UnInstalledGpsQueryExecutor(WhereContext context) {
super(context);
}
@Override
protected void check(WhereContext context) {
super.check(context);
SyUser sessionUser = dto.getUser();
Assert.notNull(sessionUser,"sessionUser为空");
}
@Override
protected void prepare() {
super.prepare();
this.gpsFlow = dto.getGpsFlow();
this.approvalUserId = dto.getUser().getUserId();
}
@Override
protected void sql() {
StringBuffer where = super.queryWhere;
if(this.isMine()){
where.append(" and exists(select 1 from ca_gps_flow f where f.app_code = v.app_code and f.flow_step = 0 and f.approval_user_id = "+this.approvalUserId+")");
}
where.append(" and v.status not in (11,13) and v.is_Gps ='0' and v.gps_Fee<>0 and v.gps_Fee !='' and v.gps_Fee is not null and v.manage_Approval_Time is not null");
if(!StringUtil.isBlank(dto.getProvince())){
where.append(" and exists(select 1 from Sy_Dealer dr where dr.province = '"+dto.getProvince()+"' and dr.dealer_Code = v.dealer_Code) ");
}
}
@Override
protected void hql() {
VCaAppInfoId dto = super.dto;
StringBuffer where = super.queryWhere;
if(this.isMine()){
where.append(" and exists(select 1 from CaGpsFlow f where f.appCode = v.id.appCode and f.flowStep = 0 and f.approvalUserId = "+this.approvalUserId+")");
}
where.append(" and v.id.status not in (11,13) and v.isGps ='0' and v.gpsFee<>0 and v.gpsFee !='' and v.gpsFee is not null and v.manageApprovalTime is not null");
if(!StringUtil.isBlank(dto.getProvince())){
where.append(" and exists(select 1 from SyDealer dr where dr.province = '"+dto.getProvince()+"' and dr.dealerCode = v.id.dealerCode) ");
}
}
@Override
public boolean test(WhereContext context) {
VCaAppInfoId dto = (VCaAppInfoId)context.getDto();
return "-29".equals(dto.getStatus());
}
private boolean isMine(){
return "mine".equals(gpsFlow);
}
}
2.5、实现类:UploadedGpsQueryExecutor
public class UploadedGpsQueryExecutor extends AbstractWhereExecutor<VCaAppInfoId> {
private final String STATUS_SCOPE = "'15','16','17','18','19','25','26','27','28','29','32'";
/**
* 构造函数
*
* @param context 上线文对象
*/
public UploadedGpsQueryExecutor(WhereContext context) {
super(context);
}
@Override
protected void check(WhereContext context) {
super.check(context);
SyUser sessionUser = dto.getUser();
Assert.notNull(sessionUser,"sessionUser为空");
}
@Override
protected void sql() {
VCaAppInfoId dto = super.dto;
StringBuffer where = super.queryWhere;
SyUser sessionUser = dto.getUser();
where.append(" and v.gps_Fee<>0 and v.gps_Fee !='' and v.gps_Fee is not null and v.manage_Approval_Time is not null and status in("+STATUS_SCOPE+") ");
GpsUtil.appendDealerCodes(sessionUser,(list) -> {
String condition = MessageFormat.format(" and v.dealer_Code in({0})", StringUtils.join(list,","));
where.append(condition);
});
}
@Override
protected void hql() {
VCaAppInfoId dto = super.dto;
StringBuffer where = super.queryWhere;
SyUser sessionUser = dto.getUser();
where.append(" and v.gpsFee<>0 and v.gpsFee !='' and v.gpsFee is not null and v.manageApprovalTime is not null and status in("+STATUS_SCOPE+") ");
GpsUtil.appendDealerCodes(sessionUser,(list) -> {
String condition = MessageFormat.format(" and v.id.dealerCode in({0})", StringUtils.join(list,","));
where.append(condition);
});
}
@Override
public boolean test(WhereContext context) {
VCaAppInfoId dto = (VCaAppInfoId)context.getDto();
return "-33".equals(dto.getStatus());
}
}