標籤:blog io ar os 使用 sp for java on
在項目中,可能會遇到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+"無法通過Regex擷取參數個數:\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();}}
該代碼對預存程序的感知,是利用Regex的,所以在匹配的時候,可能遇到一些極端的情況,如 注釋中包含了符合規則的 語句,不過一般來說,這種情況極少發生。
Java 感知Mysql預存程序變數數量