在mybatis-3.2.2.jar中,ScriptRunner提供执行sql文件脚本的类,
ScriptRunner runner = new ScriptRunner(Connection conn);
ScriptRunner 实例可以执行sql脚本。
在mybatis应用中,不想自己去实现getConnection逻辑,因为mybatis已经配置了可以连接数据库,获取mybatis中配置的Connection方法如下:
SqlSession sqlSession = MyBatisSqlSessionFactory.openSession();
Connection conn = sqlSession.getConnection();
其中MyBatisSqlSessionFactory获取对应的sqlSession 类如下:
public class MyBatisSqlSessionFactory {
private static SqlSessionFactory sqlSessionFactory;
public static SqlSessionFactory getSqlSessionFactory() {
if (sqlSessionFactory == null) {
InputStream inputStream;
try {
inputStream = Resources.getResourceAsStream("mybatis-config.xml");//mybatis-config.xml中配置了数据库连接信息等
sqlSessionFactory = new SqlSessionFactoryBuilder()
.build(inputStream);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e.getCause());
}
}
return sqlSessionFactory;
}
public static SqlSession openSession() {
return getSqlSessionFactory().openSession();
}
}
取得了连接设置ScriptRunner :
ScriptRunner runner = new ScriptRunner(Connection conn);
runner.setEscapeProcessing(false);// 使得能够识别pl/sql代码块
runner.setSendFullScript(true);// true执行所有代码,否则按行识别代码
runner.setAutoCommit(false);
注意以上设置:
1、unner.setEscapeProcessing(false),这个设置为false是为了能够识别plsql的代码块,否则无法执行pl/sql的脚本,只能执行正常的sql语句。
2、runner.setSendFullScript(true);这个是为了读取脚本所有语句,否则会按行读取进行执行,导致脚本解析错误,无法正常执行分行的begin end代码块。
3、runner.setAutoCommit(false);由于我在脚本里有commit语句,不想调用自动commit,将其禁用。
最后调用执行语句:new FileInputStream("src/sql/" + fileName[i] 这个是根据自己需要取得自己对应的sql文件,封装成Reader或其子类。
runner.runScript(new InputStreamReader(new FileInputStream("src/sql/" + fileName[i]),"UTF-8"));
以上便可以完成带有pl/sql执行快的sql脚本的执行。
另外,由于想把错误信息打印到log4g的日志里,发现ScriptRunner 只实现了PrintWriter对提示信息,或错误信息的打印,默认是system.out,为了把日志信息打印到log4j配置的日志文件里,通过获取log4j日志文件,来实现PrintWriter对日志文件的追加。
通过Appender转换
org.apache.log4j.Logger.getRootLogger().getAppender("LogFile")来取得Appender实例,LogFile是日志对象名称,如在配置文件中有一下配置:
log4j.appender.LogFile=org.apache.log4j.DailyRollingFileAppender
其中LogFile便是appender的日志名称,DailyRollingFileAppender 便是append的实体对象类型,具体做法如下:
PrintWriter writer = null;
FileWriter fw = null;
if (org.apache.log4j.Logger.getRootLogger().getAppender("LogFile") instanceof DailyRollingFileAppender) {
DailyRollingFileAppender apen = (DailyRollingFileAppender) org.apache.log4j.Logger
.getRootLogger().getAppender("LogFile");
try {
fw = new FileWriter(apen.getFile(), true);//apen.getFile()取得文件路径,封装成FileWriter是为了日志信息不被覆盖,而是追加写入
writer = new PrintWriter(fw);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
取得了log4j文件路径的writer后便可以将其实例提供给ScriptRunner ,实现执行sql脚本时将解析信息,执行错误信息输出到log4j配置的日志文件中:
if (writer != null) {
// runner.setLogWriter(writer);//普通信息
runner.setErrorLogWriter(writer);// 只记录错误信息
}
注意:setErrorLogWriter的调用一定要在runScript之前,否则就闹笑话了。