最近在作系统数据初始化,采用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; }
通过测试,乱码问题获得解决