最近做了这样一个需求:
确定某一个模板上需要签哪几个章、名(不同步到对方),必须完成所有配置的签章、签名后才能发送
注释:在凭证库中即将发送的签名、签章里面含有发送与不发送的签名签章:需要做的是在发送的时候,检验一下该签章是否为必检查,这个必检查与否是在模板里面配置的,如果在模板里面设置凭证为发送即可选择是否必检查,如果设置必检查就要在即将发送中查找,如果即将发送的凭证对应的模板凭证为必检查:检查是否模板凭证每一个位置号在即将发送的位置号中,在就发送,不在就是异常。
也可以这样理解:发送时候可以配置模板对应该凭证是否为必检查。如果必检查,那么该位置对应的就是必检查,那么必检查的凭证对应的肯定有个位置号,这个位置号一定对应与可以发送成功的凭证 。
String SQL_QUERY_SEND_CHECK_STAMPNO ="SELECT AVMS.STAMP_NO, AVM.ADMDIVCODE || '#' || AVM.VT_CODE AS UNIONKEY"
+" FROM ASSP_VOUCHER_MODEL AVM ,ASSP_VOUCHER_MODEL_STAMP AVMS"
+" WHERE AVM.START_DATE <= TO_CHAR(CURRENT_TIMESTAMP, 'YYYY-MM-DD')"
+" AND AVM.END_DATE >= TO_CHAR(CURRENT_TIMESTAMP, 'YYYY-MM-DD')"
+" AND AVM.VM_ID=AVMS.VM_ID"
+" AND AVMS.CHECK_SEND_STATUS=1";
@SuppressWarnings("unchecked")
public List<String> getSignStampList(String admDivCode, //List<Map<String, String>>
String vtCode) {
List<Map<String, String>> vouchermodelno = null;
// 区划码#凭证类型的联合主键
String unionKey = admDivCode + "#" + vtCode;
//缓存
Cache cachevoucherModel = CacheManager.getCacheInfo("vouchermodelCache");
HashMap<String,List<String>> vouchermodelstamplist = (HashMap<String,List<String>>) cachevoucherModel.getValue();
if(cachevoucherModel.isRefreshFlag()){
vouchermodelstamplist = new HashMap<String,List<String>>();
try {
// 读取全部签章签名模板的位置stamp_no,和联合主键
vouchermodelno=this.queryForList(SQL_QUERY_SEND_CHECK_STAMPNO);
} catch (Exception ex) {
throw new EVoucherException("SQL语句出错");
}
// 遍历结果集
for (Map<String, String> vouchermodelmap : vouchermodelno) {
String key = vouchermodelmap.get("unionKey");
if (vouchermodelstamplist.containsKey(key)) {
vouchermodelstamplist.get(key).add(vouchermodelmap.get("stamp_no"));
}else{
List<String> stampNoList = new ArrayList<String>();
stampNoList.add(vouchermodelmap.get("stamp_no"));
vouchermodelstamplist.put(key, stampNoList);
}
}
cachevoucherModel.setValue(vouchermodelstamplist);
cachevoucherModel.setRefreshFlag(false);
}
return vouchermodelstamplist.get(unionKey);
}
这段代码非常适合自己学习,下面一行一行剖析:
对于这行代码:
String SQL_QUERY_SEND_CHECK_STAMPNO ="SELECT AVMS.STAMP_NO, AVM.ADMDIVCODE || '#' || AVM.VT_CODE AS UNIONKEY"
+" FROM ASSP_VOUCHER_MODEL AVM ,ASSP_VOUCHER_MODEL_STAMP AVMS"
+" WHERE AVM.START_DATE <= TO_CHAR(CURRENT_TIMESTAMP, 'YYYY-MM-DD')"
+" AND AVM.END_DATE >= TO_CHAR(CURRENT_TIMESTAMP, 'YYYY-MM-DD')"
+" AND AVM.VM_ID=AVMS.VM_ID"
+" AND AVMS.CHECK_SEND_STATUS=1";
1)用了Oracle库中的连接符 || '#' ||
2)用了函数TO_CHAR
3)将区划和类型作为联合主键列名
查询结果如下:
我最终的目的是取出所有的位置号:从数据库里面查xunlei的本身就是一个List,List里面装的是map,所以定义定义List<Map<String, String>> vouchermodelno = null;
看看vouchermodelno=this.queryForList(SQL_QUERY_SEND_CHECK_STAMPNO);查询出来的结果:
设定联合主键,这里用到传递过来的参数,待会用到缓存:String unionKey = admDivCode + "#" + vtCode;
下面是取缓存中的数据:
Cache cachevoucherModel = CacheManager.getCacheInfo("vouchermodelCache");
HashMap<String,List<String>> vouchermodelstamplist = (HashMap<String,List<String>>) cachevoucherModel.getValue();
为什么将位置号在缓存中用HashMap<String,List<String>>,这里肯定需要得到的位置号肯定是房子List里面,通过HashMap的key取出List即可
如果第一次访问,缓存中是没有的,所以执行:vouchermodelstamplist = new HashMap<String,List<String>>(); 重新创建一个HashMap
下面就是遍历取出来的map结果,得到位置号的List
/ 遍历结果集
for (Map<String, String> vouchermodelmap : vouchermodelno) {
String key = vouchermodelmap.get("unionKey");
if (vouchermodelstamplist.containsKey(key)) {
vouchermodelstamplist.get(key).add(vouchermodelmap.get("stamp_no"));
}else{
List<String> stampNoList = new ArrayList<String>();
stampNoList.add(vouchermodelmap.get("stamp_no"));
vouchermodelstamplist.put(key, stampNoList);
}
}
vouchermodelno是一个List,遍历的时候,每一个遍历的元素是一个map,对应的就是{stamp_no=cz_jb,unionkey=110000#1101},{......,.....}
首先得到联合主键key :也就是位置号的列名,第一次vouchermodelstamplist是个空的,上面已经定义:vouchermodelstamplist = new HashMap<String,List<String>>();
所以,执行else部分:创建一个List,里面存储位置号。
List<String> stampNoList = new ArrayList<String>();
stampNoList.add(vouchermodelmap.get("stamp_no"));
然后用map将key和list放进去:这样就可以实现联合主键作为key,位置号作为value的map
第二次循环的时候,已经含有了该key【联合主键】,那么就在map中对应同一个key的多个list。
要是key不一样就再次循环创建另外一个key对应的list的map
然后加入缓存,将取出来的HashMap<String,List<String>> vouchermodelstamplist 中的vouchermodelstamplist放入缓存中即可
cachevoucherModel.setValue(vouchermodelstamplist);
cachevoucherModel.setRefreshFlag(false);
下次取调用该方法的时候直接从缓存中取值:
HashMap<String,List<String>> vouchermodelstamplist = (HashMap<String,List<String>>) cachevoucherModel.getValue();
缓存也好,放入的是一个map,取值返回的就是map中的list,通过key来取值:vouchermodelstamplist.get(unionKey)
这样返回的就是一个List
进行比对的时候:理解思想,不要用for循环。
private void issign_stamp(List<String> vouchermodelstamplist,List<VoucherStampDTO> vouStampList) {
List<String> checkList = new ArrayList<String>();
//得到所有即将发送的凭证中签名签章的位置号
for(int i=0;i<vouStampList.size();i++){
<strong>checkList.add(vouStampList.get(i).getStamp_no());</strong>
}
if(vouchermodelstamplist.size()>0){
for(int i=0;i<vouchermodelstamplist.size();i++){
String stampNO = vouchermodelstamplist.get(i);
<strong>checkList.contains(stampNO);</strong>
if(!checkList.contains(stampNO)){
throw new EVoucherException("模板签名、签章位置"+stampNO+"不在凭证签名、签章位置中");
}
}
}
}
}
首先通过一个for循环将即将发送凭证的位置放在一个List中去
然后对于模板凭证位置号的遍历for循环,检查每个位置号是否在即将放松凭证的位置号List中即可:if(!checkList.contains(stampNO))