今天发现了以前写的一个记录Hibernate执行增删改的SQL日志的功能
即记录的sql日志可以直接拿到数据库中执行
想起来当初为了这个功能费了不少周折,网上也找了好多资料,但是都无法记录确切的SQL语句 如:insert into table (name,age) values('李刚',35);
思路: 通过Hibernate 拦截器 + hibernate事件监听器 完成此功能
要求:hibernate版本 3.2.5.ga 其他版本在方法调用上可能有些出入,需自行调整代码。 比如3.1中就没有getRootTableName()方法 ,至于hibernate4没有验证过
转载请注明:http://blog.csdn.net/zidasine/article/details/7242829
1、监听器
package com.sqllog;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.log4j.Logger;
import org.hibernate.EmptyInterceptor;
import org.hibernate.Transaction;
/**
* hibernate 拦截器
* @author Zidasine
*
*/
public class SQLInterceptor extends EmptyInterceptor {
/**
*
*/
private static final long serialVersionUID = 4147408208347438253L;
private final ThreadLocal<List<String>> content = new ThreadLocal<List<String>>();
private Logger logger = Logger.getLogger(SQLInterceptor.class);
public void add(String sql){
content.get().add(sql);
}
private List<String> get(){
return content.get();
}
private void set(List<String> value){
content.set(value);
}
private void clear(){
content.remove();
}
@Override
public void afterTransactionBegin(Transaction tx) {
set(new ArrayList<String>());
super.afterTransactionBegin(tx);
}
@Override
public void afterTransactionCompletion(Transaction tx) {
if(tx.wasCommitted()){
List<String> sqls = get();
DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
String logName = format.format(new Date());
StringBuffer buff = new StringBuffer();
for(int i = 0;i < sqls.size();i++){
buff.append(sqls.get(i));
buff.append("\r\n\r\n");
}
try {
SQLLogHandler.writeLog(logName, true, buff.toString());
} catch (IOException e) {
logger.error("记录sql日志错误", e);
}
}
clear();
super.afterTransactionCompletion(tx);
}
}
2、日志处理器
package com.sqllog;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
/**
* 日志处理类
* @author Zidasine
*
*/
public class SQLLogHandler {
// 日志输入目的目录
private static final File LOG_PARENT_DIR = new File("D:\\SQL_LOG");
private static final String LOG_SUFFIX = "log";
static {
if (!LOG_PARENT_DIR.exists()) {
LOG_PARENT_DIR.mkdirs();
}
}
private SQLLogHandler() {
}
public static void writeLog(String logName, boolean append, String message) throws IOException {
File log = getLog(logName);
if(log == null){
log = createLog(logName);
}
if(log == null){
throw new IOException("can't create log file: "+logName+"."+LOG_SUFFIX);
}
Writer writer = new FileWriter(log,append);
writer.write(message);
writer.flush();
writer.close();
}
private static File getLog(String logName) {
File log = new File(LOG_PARENT_DIR, logName + "." + LOG_SUFFIX);
return log.exists() && log.isFile() ? log : null;
}
private static File createLog