记录Hibernate 增删改 执行的SQL语句

本文介绍如何利用Hibernate拦截器和事件监听器来记录执行的增删改SQL日志,确保日志能够直接用于数据库执行。适用于Hibernate 3.2.5.ga版本,对于级联操作和联合主键的支持有限,但基本满足一般需求。完整实现可能需要根据具体版本调整代码。
摘要由CSDN通过智能技术生成

今天发现了以前写的一个记录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
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值