Java讀取解析sql文件,並使用netiler dao執行sql

最近在作系統數據初始化,採用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;    
    }

通過測試,亂碼問題獲得解決

相關文章
相關標籤/搜索