<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 122,  comments - 25,  trackbacks - 0
    一般業務系統中總會存在一些基礎數據,在其他的業務單據中會被套引用。因此,系統必須保證這些被業務單據引用的基礎數據不能任意的刪除。最常見的做法就是,在刪除基礎數據時,預先校驗該類數據是否在相關業務表中存在,若不存在才允許用戶刪除,否則給用戶以提示。

    但這樣的處理方法,有些缺點,就是需要編碼對每個業務類提供查詢方法,或在刪除邏輯中增加判斷邏輯。因此,每次引用關系變化,增加或減少時免不了要修改原來的邏輯,時間越長,系統的維護成本就越來越高了。因此,有必要對系統進行重構,將這類的處理邏輯進行抽象,單獨封裝成一個服務,當引用關系有變更時,不用再修改原有邏輯,通過配置就可以完成變更。

    通用引用關系查詢服務,主要就是通過db表或xml配置文件,對系統中每個基礎數據有引用的所有關系進行定義,定義屬性主要是引用的表及字段名稱。查詢時,從配置文件中讀取指定類別的引用關系,并逐一查詢這些表中的記錄,以確定數據是否被引用。這種處理方法的優點為,易擴展、可維護性強,引用關系變更時,僅通過維護配置文件,不必進行編碼,就能實現,這樣能大大的提高系統的穩定性。

    xml配置文件如下:
    <rule bizName='product' desc="產品關聯項定義">
        
    <item>
            
    <refTable>sale_item</refTable>
            
    <refField>product_id</refField>
            <!-- 用于查詢條件的擴展,允許為空 -->
            <extCondition>CORP_ID = #corpId#</extCondition>
        
    </item>
        
    <item>
            
    <refTable>sale_order_item</refTable>
            
    <refField>product_id</refField>
            
    <extCondition>CORP_ID = #corpId#</extCondition>
        
    </item>
    </rule>
    <rule bizName='customer' desc="客戶關聯項定義">
        
    <item>
            
    <refTable>sale_order</refTable>
            
    <refField>cust_id</refField>
            
    <extCondition>CORP_ID = #corpId#</extCondition>
        
    </item>
        
    <item>
            
    <refTable>sale_bill</refTable>
            
    <refField>cust_id</refField>
            
    <extCondition></extCondition>
        
    </item>
        ... ...

    </rule>

    通用業務引用查詢類代碼片段如下:
    public class BizReferenceService implements IBizReferenceService {

        
    private static Map<String,List<BizReferenceRule>> ruleMaps;
        
        
    private static final String PATTERN = "#[\\w]+#";
        
    private static final String CFG_FILE = "bizReferenceRule.xml";
        ... ...

      
        
    /**
         * 查詢指定業務數據是否被其他業務表關聯依賴.
         * 
    @param bizName 關聯業務名稱
         * 
    @param bizId 關聯業務ID.
         * 
    @param extParam 擴展條件
         * 
    @return true 被關聯/false 未被關聯.
         
    */
        
    public boolean isBizReference(String bizName,String bizId,Map<String,Object>extParam) throws ServiceException {
            Assert.notNull(bizName, 
    "業務名稱不能為空,bizName is NULL。");
            Assert.notNull(bizId, 
    "記錄ID不能為空,bizId is NULL。");

            
    try {
                
    //逐個檢查依賴項是否有數據關聯.
                List<BizReferenceRule> rules = getBizRelationRule(bizName);
                
    for(BizReferenceRule rule : rules){
                    StringBuilder sqlBuilder 
    = new StringBuilder();
                    sqlBuilder.append(
    "select count(*) from ").append(rule.getRelTable()).append(" where ")
                        .append(rule.getRelField()).append(
    "='").append(bizId).append("");
                    String extConditon 
    = rule.getExtCondition();
                    
    if(StringUtil.isNotBlank(extConditon)){
                        initTenantParam(extParam);
                        sqlBuilder.append(
    " and ").append(getExtParamSql(extConditon,extParam));
                    }
                    logger.debug(sqlBuilder);
                    
    int nCount = bizReferenceDao.getBizRelationCount(sqlBuilder.toString());
                    
    if (nCount != 0return true;
                }
                
    return false;
            }
            
    catch(Exception ex){
                logger.error(
    "調用業務關聯服務錯誤。"+bizName+",bizId:"+bizId+",extParam"+LogUtil.parserBean(extParam),ex);
                
    throw new ServiceException("調用業務關聯服務錯誤。");
            }
        }
        
        
    /**
         * 組裝擴展查詢條件的sql
         * 
    @param condition
         * 
    @param extParam
         * 
    @return
         * 
    @throws Exception
         
    */
        
    private String getExtParamSql(String condition,Map<String,Object>extParam) throws Exception {
            List
    <String> paramList = parseDyncParam(condition);
            
    for(String param : paramList){
                String simpleParam 
    = simpleName(param);
                
    if(!extParam.containsKey(simpleParam)){
                    
    throw new ServiceException("動態參數值未設置! param:"+param+",extParam:"+LogUtil.parserBean(extParam));
                }
                condition 
    = condition.replaceAll(param, "'"+String.valueOf(extParam.get(simpleParam))+"'");
            }
            
    return condition;
        }
        
        
    /**
         * 解析擴展查詢條件中的動態參數名.
         * 
    @param condition
         * 
    @return
         * 
    @throws Exception
         
    */
        
    private List<String> parseDyncParam(String condition) throws Exception {
            PatternCompiler compiler 
    = new Perl5Compiler();
            PatternMatcher matcher 
    = new Perl5Matcher();
            MatchResult result 
    = null;
            PatternMatcherInput input 
    = null;
            List
    <String> paramList = new ArrayList<String>();
            input 
    = new PatternMatcherInput(condition);
            Pattern pattern 
    = compiler.compile(PATTERN,Perl5Compiler.CASE_INSENSITIVE_MASK);
            
    while (matcher.contains(input, pattern)){
                result 
    = matcher.getMatch();
                input.setBeginOffset(result.length());
                paramList.add(result.group(
    0));
            }
            
    return paramList;
        }
        
        
    /**
         * 獲取業務關聯查詢規則.
         
    */
        
    private List<BizReferenceRule> getBizRelationRule(String bizName){
            Assert.notNull(bizName, 
    "業務名稱不能為空,bizName is NULL。");
            
            
    //配置定義未加載到內存時,讀取配置文件
            if(ruleMaps == null){
                parseRuleConfig();
                
    if(ruleMaps == nullreturn null;
            }
            
            
    return ruleMaps.get(bizName);
        }
        
        
    /**
         * 讀取業務關聯規則配置文件
         
    */
        @SuppressWarnings(
    "unchecked")
        
    private synchronized void parseRuleConfig(){
            
    if(ruleMaps != null){
                
    return;
            }
            
            
    //解析業務引用定義文件.
             
        }
        
        
    /**
         * 讀取Xml文檔
         * 
    @return
         
    */
        
    private Document getXmlDocument(){
            InputStream is 
    = null;
            
    try {
                ClassLoader loader 
    = Thread.currentThread().getContextClassLoader();
                is 
    = loader.getResourceAsStream(CFG_FILE);
                SAXBuilder sb 
    = new SAXBuilder();
                
    return sb.build(new BufferedInputStream(is));
            }
            
    catch(Exception ex) {
                logger.error(
    "讀取配置文件錯誤. file:"+CFG_FILE, ex);
                
    return null;
            }
            
    finally {
                
    try {
                    
    if(is != null){
                        is.close();
                        is 
    = null;
                    }
                }
                
    catch(Exception ex) {
                    logger.error(ex);
                }
            }
        }

         
    }

    其他的一些可選處理方法:
    b. 在客戶表增加引用計數字段;
    需額外維護引用計數字段,在引用的業務邏輯增加或刪除記錄時,需對該字段的數值進行更新。適用于需要直接查詢記錄被引用次數的場景,但在集群環境下,需注意并發問題。
    posted on 2009-07-14 14:42 josson 閱讀(384) 評論(0)  編輯  收藏 所屬分類: java 開發
    <2009年7月>
    2829301234
    567891011
    12131415161718
    19202122232425
    2627282930311
    2345678

    常用鏈接

    留言簿(3)

    隨筆分類

    隨筆檔案

    收藏夾

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 国产视频精品免费视频| 免费无码AV一区二区| 亚洲一区免费观看| 亚洲综合色自拍一区| 日韩一区二区三区免费播放| 国产精品久久免费视频| 鲁死你资源站亚洲av| 日本特黄特色aa大片免费| 亚洲国产AV一区二区三区四区 | 久久亚洲精品国产精品婷婷| 日韩版码免费福利视频| 亚洲a级成人片在线观看| 18禁成年无码免费网站无遮挡| 亚洲欧美日韩综合久久久| 国产在线19禁免费观看| 色多多A级毛片免费看| 亚洲一级片免费看| 大地影院MV在线观看视频免费| 亚洲AV综合色区无码另类小说| 99热在线免费观看| 亚洲AV一二三区成人影片| 日韩中文无码有码免费视频| 老外毛片免费视频播放| 亚洲中文久久精品无码| 最近免费中文字幕大全高清大全1| 亚洲国产中文在线二区三区免| 成人免费淫片在线费观看| 特a级免费高清黄色片| 久久精品7亚洲午夜a| 精品国产免费人成电影在线观看 | 亚洲一区二区无码偷拍| av无码东京热亚洲男人的天堂 | 91高清免费国产自产| 亚洲国产精品美女久久久久| 精品国产亚洲男女在线线电影| 无码人妻丰满熟妇区免费| 亚洲乱码中文字幕在线| 亚洲精品国偷自产在线| 国产精品久久久久久久久久免费| 野花视频在线官网免费1| 亚洲网站在线观看|