?在項目中,可能會遇到sybase 移植到 mysql的情況,因為sybase 支持存儲過程的可變參數,而mysql不能支持,所以,在調用mysql的時候,需要感知存儲過程到底有幾個參數,來合理的配置參數數量:
如下是代碼
package com.xxx.util; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; import java.util.Hashtable; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; public class ProcedureHelper { /*是否是開發模式*/ static boolean DEV = false; static Map<String,Integer> CACHE = new Hashtable<String,Integer>(100); static Pattern PATTERN_ARGS = Pattern.compile("`\\s*\\((.*)\\)\\s*begin",Pattern.DOTALL|Pattern.CASE_INSENSITIVE); static Pattern PATTERN_ARG = Pattern.compile("(in|out|inout)[^-,]*(,|$)",Pattern.DOTALL|Pattern.CASE_INSENSITIVE); private static int doWork(Connection con,String proc) throws Exception { Statement stmt = null; stmt = con.createStatement(); //3、Statement 接口需要通過Connection 接口進行實例化操作 ResultSet rs = stmt.executeQuery("show create procedure "+proc); if(rs.next()){ //第三列為 存儲過程的代碼 String code = rs.getString(3); Matcher m = PATTERN_ARGS.matcher(code); if(m.find()){ String args = m.group(1); if(args.matches("\\s*")) return 0; else{ Matcher m2 = PATTERN_ARG.matcher(args); int num = 0; while(m2.find()){ //System.out.println(m2.group()); num++; } return num; } }else{ throw new RuntimeException("存儲過程: "+proc+"無法通過正則表達式獲取參數個數:\n"+code); } } rs.close(); stmt.close(); throw new RuntimeException("沒有該存儲過程"); } /** * 注意, 在存儲過程的參數中,不能寫注釋,特別是 in xxx, 格式的注釋,不然會被錯誤的識別 * @param con JDBC連接, 且不在函數內釋放資源 * @param proc 調用的存儲過程 * @param args 傳遞給存儲過程的參數 * @throws 解析失敗 * */ public static int getProcedureArgsNumber(Connection con,String proc) throws Exception { if(con == null || proc == null|| proc.equals("")){ throw new RuntimeException("proc, con 參數不能為空"); } //這里可以做緩存 return doWork(con,proc); } public static void main(String arg[]) throws Exception{ Connection con = null; //表示數據庫的連接對象 Class.forName("com.mysql.jdbc.Driver"); //1、使用CLASS 類加載驅動程序 con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8","root","root"); //2、連接數據庫 System.out.println(getProcedureArgsNumber(con,"my_procedure")); con.close(); } }
該代碼對存儲過程的感知,是利用正則表達式的,所以在匹配的時候,可能遇到一些極端的情況,如 注釋中包含了符合規則的 語句,不過一般來說,這種情況極少發生。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
