最近在作系統數據初始化,採用sql形式導入基礎數據,這裏記錄下編碼過程。java
導出的sql文件已經放在dao目錄下了。web
先來寫個方法讀取sql文件:sql
/** * 加載解析sql文件 * @param sqlFile * @return * @throws Exception */ private static List<String> loadSql(String sqlFile) throws Exception { List<String> sqlList = new ArrayList<String>(); try { InputStream sqlFileIn = new FileInputStream(sqlFile); StringBuffer sqlSb = new StringBuffer(); byte[] buff = new byte[1024]; int byteRead = 0; while ((byteRead = sqlFileIn.read(buff)) != -1) { sqlSb.append(new String(buff, 0, byteRead,"utf-8")); } sqlFileIn.close(); // Windows 下換行是 \r\n, Linux 下是 \n String[] sqlArr = sqlSb.toString() .split("(;\\s*\\r\\n)|(;\\s*\\n)"); for (int i = 0; i < sqlArr.length; i++) { String sql = sqlArr[i].replaceAll("--.*", "").trim(); if (!sql.equals("")) { sqlList.add(sql); } } return sqlList; } catch (Exception ex) { throw new Exception(ex.getMessage()); } }
即把sql文件讀取出來,解析成單條sql語句。app
下面是action執行方法ide
/** * 執行sql,初始化系統基礎數據 * @return */ public Object init(){ List<String> list = new ArrayList<String>(); try { list = loadSql("D:\\workspace\\com.leadal.netiler.install\\web\\data\\dao\\newclips.sql"); int i=0; service.setProgess(0); service.setExecute(true); int size = list.size(); for(String sql:list){ if(!service.getExecute()){ service.setProgess(100); break; } service.executeSql(sql); i++; service.setProgess(100*i/size); } ActionMessage.info("基礎數據初始化成功!"); } catch (Exception e) { e.printStackTrace(); ActionMessage.error("初始化失敗!"); } return this; }
因爲是測試,sql文件直接寫了個絕對路徑。測試
service調用dao的executeSql(String sql)方法this
netiler dao:編碼
@Dao("Netiler.Install.Init.InitBasicData") public interface InitBasicDataDao { @Paramable("sql") public void executeSql(String sql); }
Netiler Dao dao文件寫法:spa
<?xml version="1.0" encoding="UTF-8" ?> <sql> <result id="result" auto="true"> </result> <statement id="executeSql" result="result"> <![CDATA[ #parse($sql) ]]> </statement> </sql>
這裏使用statement,定義了個自動類型的result。.net
過程當中遇到幾個問題,一個是返回值的,另外一個是sql文件包含指令如#if()時,#if()括號裏爲空字符,解析時有點問題,最後把#if()換成#if(1==1)
2013/5/31 10:35 補充與修改:
在數據插入後,發現部分中文數據是亂碼的,通過初步分析,亂碼的位置都頗有規律,即老是固定的位置出現中文亂碼了。這裏獲得結果是,字節流解析的時候沒有處理中文的問題,由於漢字是佔兩個字節的,當一個漢字恰好佔1024-1025字節時,漢字就被拆開了。
解決的方法有兩種,一種是繼續使用字節流解析,可是對漢字須要進行特殊處理,即經過對比ASCII碼大小來肯定是不是漢字而進行拼接操做。這樣顯然是比較麻煩的,固然確定能夠實現。
這裏筆者採用字符流行讀取形式進行讀取解析,貼上代碼
/** * 加載解析sql 讀取方式字符流 行讀取 * @param sqlFile * @return * @throws Exception */ private List<String> loadSql2(String sqlFile) throws Exception{ List<String> sqlList = new ArrayList<String>(); try { FileReader fr = new FileReader(sqlFile); BufferedReader br = new BufferedReader(fr); String s=""; StringBuffer sb = new StringBuffer(); while ((s = br.readLine()) != null) { if(s.startsWith("/*")||s.startsWith("--")){ } else if(s.endsWith(";")){ sb.append(s); sqlList.add(sb.toString()); sb.delete(0, sb.length()); } else{ sb.append(s); } } fr.close(); br.close(); // for(String sql : sqlList){ // System.out.println("sql:"+sql); // } } catch (Exception e) { throw new Exception(e.getMessage()); } return sqlList; }
通過測試,亂碼問題獲得解決