自製xml實現SQL動態參數配置

来源:http://www.cnblogs.com/Mr-kevin/archive/2016/12/09/6151099.html
-Advertisement-
Play Games

此文章是基於 搭建SpringMVC+Spring+Hibernate平臺 一. 準備工作 1. 點擊此找到並下載 commons-digester3-3.2.jar 2. 點擊此找到並下載 commons-beanutils-1.9.3.jar 目前最高版本 3. 將得到的jar包放到工程的 li ...


此文章是基於 搭建SpringMVC+Spring+Hibernate平臺

 

一. 準備工作

  1. 點擊此找到並下載 commons-digester3-3.2.jar

  2. 點擊此找到並下載 commons-beanutils-1.9.3.jar

    目前最高版本

  3. 將得到的jar包放到工程的 lib 目錄下

 

二. 相關代碼

  1. xml 解析器:SqlXmlParser.java

package com.ims.persistence.base;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.digester3.Digester;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

public class SqlXmlParser {
    private String sqlXml;
    private static Digester digester;
    
    private static String webrootPath = System.getProperty("webapp.root")+"sql/";
    private static Logger logger = Logger.getLogger(SqlXmlParser.class);
    
    static{
        digester = new Digester();
        digester.setValidating(false);
        
        digester.addObjectCreate("set", SqlSet.class);
        
        digester.addObjectCreate("set/sql", Sql.class);
        digester.addSetProperties("set/sql");
        digester.addBeanPropertySetter("set/sql/pattern");  
        digester.addSetNext("set/sql", "addSql");
        
        digester.addObjectCreate("set/sql/param", SqlParam.class);
        digester.addSetProperties("set/sql/param");
        digester.addSetNext("set/sql/param", "addParam"); 
    }
    
    public SqlXmlParser(String sqlXml){
        this.sqlXml = sqlXml; 
    }
    
    public String parse(String sqlName, Map<String, String> params){    
        InputStream is = null;
        String result = null;
        try{
            is = new FileInputStream(new File(webrootPath+sqlXml));
            SqlSet sqlSet = (SqlSet)digester.parse(is);
            Sql sql = sqlSet.getSqls().get(sqlName);
            List<String> paramList = new ArrayList<String>(); 
            for(SqlParam param : sql.getCondition()){
                String value = params.get(param.getName());
                paramList.add(param.getPosition(), StringUtils.isBlank(value)?"":value);
            }
            result = MessageFormat.format(sql.getPattern(), paramList.toArray());
        }catch(Exception e1){
            logger.error("sql文件解析異常:"+e1);
        }finally {
            if(is != null) {
                try {
                    is.close();
                }catch (Exception e2) {
                    logger.error("sql文件流關閉異常:"+e2);
                }    
                
                is = null;
                digester.clear();
            }
        }
        
        return result;
    }
}
View Code

  

  2. SqlSet.java

package com.ims.persistence.base;

import java.util.HashMap;
import java.util.Map;

public class SqlSet {
    private Map<String, Sql> sqls = new HashMap<String, Sql>();

    public void addSql(Sql sql){
        sqls.put(sql.getName(), sql);
    }
    
    public Map<String, Sql> getSqls() {
        return sqls;
    }
    public void setSqls(Map<String, Sql> sqls) {
        this.sqls = sqls;
    }
}
View Code

  

  3. Sql.java

package com.ims.persistence.base;

import java.util.ArrayList;
import java.util.List;

public class Sql{
    private String name;
    private String pattern;
    private List<SqlParam> condition = new ArrayList<SqlParam>();
    
    public void addParam(SqlParam param){
        condition.add(param);
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

    public String getPattern() {
        return pattern;
    }
    public void setPattern(String pattern) {
        this.pattern = pattern;
    }

    public List<SqlParam> getCondition() {
        return condition;
    }
    public void setCondition(List<SqlParam> condition) {
        this.condition = condition;
    }
}
View Code

  

  4. SqlParam.java

package com.ims.persistence.base;

public class SqlParam {
    private String name;
    private Integer position;
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    
    public Integer getPosition() {
        return position;
    }
    public void setPosition(Integer position) {
        this.position = position;
    }
}
View Code

  

  5. 放在 WebContent/sql 目錄下的包含sql語句的xml文件,如:

<?xml version="1.0" encoding="utf-8" ?>
<set>
    <sql name="codeType">
        <pattern>
            <![CDATA[
                select A.id, A.value, A.text 
                from sys.code A 
                left join sys.codeType B on A.codeTypeId = B.id 
                where (case when "{0}"="" then 1=1 else B.codeType = "{0}" end)
                    and (case when "{1}"="" then 1=1 else A.isEnable = "{1}" end)
                    and (case when "{2}"="" then 1=1 else A.isDefault = "{2}" end)
            ]]>
        </pattern>
    
        <param name="codeType" position="0" />
        <param name="isEnable" position="1" />
        <param name="isDefault" position="2" />
        
    </sql>
</set>
View Code

  

  6. 使用方法例如:

package com.ims.service.xxx.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ims.persistence.base.SqlXmlParser;
import com.ims.persistence.dao.xxx.CodeDao;
import com.ims.service.xxx.CodeBS;

@Service("codeBS")
public class CodeBSImpl implements CodeBS{
    private static final String sqlXml = "xxx/code.xml";
    @Autowired
    private CodeDao codeDao;
    
    @Override
    public List<Map<String, Object>> getValueTextListByType(String codeType) {
        Map<String, String> paramMap = new HashMap<String, String>();
        paramMap.put("codeType", codeType);
        List<Map<String, Object>> list = codeDao.findBySql(new SqlXmlParser(sqlXml).parse("codeType", paramMap));
        List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
        for(Map<String, Object> map:list){
            Map<String, Object> temp = new HashMap<String, Object>();
            temp.put("value", map.get("value"));
            temp.put("text", map.get("text"));
            result.add(temp);
        }
        return result;
    }

}
View Code

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 受到Unix時間戳的啟發,我發現時間轉成秒數後會非常好處理,在程式當中不再是以字元串的形式處理,不管時間的加減還是獲取隨機的時間點都變得非常方便, 如果有需要,也很容易轉換成需要的時間格式。 一:時間轉成秒數 stackoverflow.com上還有更多的寫法,有興趣可以自己去看。當然方法一最簡單明 ...
  • (譯者註:本人目前在杭州某家互聯網公司工作,崗位是測試研發,非常喜歡python,目前已經使用Django為公司內部搭建了幾個自動化平臺,因為沒人教沒人帶,基本靠野路子自學,走過好多彎路,磕磕碰碰一路過來,前段時間偶爾看到《Django By Example》這本書,瞬間淚流滿面,當初怎麼沒有找到這 ...
  • 屬實C++不會。 目前幫朋友弄個小項目需要小折騰一下。 c# 一直採用 log4net ,c++的呢,找找有個log4cplus 知識有限,做個通用類吧。別把精力放在這裡。 動手創建個靜態類。 為了保持一致性,由於好幾年前還有一些BCL的動態庫。 所以命名規則還採用原來的風格。 BCLLogHelp ...
  • (本文圖片量非常大,網速不好的話,載入可能比較慢,手機黨慎入!!!)IntelliJ在業界被公認為最好的java開發工具之一,尤其在智能代碼助手、代碼自動提示、重構、J2EE支持、Ant、JUnit、CVS整合、代碼審查、 創新的GUI設計等方面的功能可以說是超常的。IDEA是JetBrains公司... ...
  • 程式講究拆解和構造,根據需求拆解實現的步驟,一個步驟一個步驟的來實現,不斷測試,碰到問題可以百度查詢(順便提升一下自己的搜索技術[需求越清楚,搜索的耗時也越少])和交流。 ...
  • 首先,我想說,雖然我是個學java的。。。 其實我的java也很爛。但是我覺得python挺好玩,想學習下。之前用python做了簡單的爬蟲,也算是對python入門了。不過自己要學的地方還有很多。 我學習的資料都是網上找的,阮一峰老師的教程和菜鳥教程,都很不錯。剛開始學習,沒有必要買厚厚一本書去看 ...
  • Inner Classes ___ It allows you to group classes that logically belong together and to control the visibility of one within the other. It knows about ...
  • 生成公鑰的私鑰: 執行結果: 使用公鑰和私鑰來加密和解密: 執行結果: PS: 某些RSA模塊生成的公鑰的頭為“ BEGIN PUBLIC KEY ”, 這種RSA頭無法正常導入生成public key,需要標準的“ BEGIN RSA PUBLIC KEY ”。 通過RSA加密後的密文通常很難使用 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...