[转]Java读取解析sql文件,并使用netiler dao执行sql

转至:
最近在做系统数据初始化,采用sql形式导入基础数据,这里记录下编码过程。
导出的sql文件已经放在dao目录下了。
先来写个方法读取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语句。
下面是action执行方法

/**
* 执行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)方法
netiler dao:

@Dao("Netiler.Install.Init.InitBasicData")
public interface InitBasicDataDao {
@Paramable("sql")
public void executeSql(String sql);
}
Netiler Dao dao文件写法:
<?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。
过程中遇到几个问题,一个是返回值的,另一个是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;
}
经过测试,乱码问题得到解决
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值