P6Spy 实现完整 SQL 打印,不是占位符 SQL,而是实际 SQL

P6Spy 是 SQL 打印的解决方案之一,以下展示如何与 JFinal 配置使用。

依赖

    <dependency>
        <groupId>p6spy</groupId>
        <artifactId>p6spy</artifactId>
        <version>3.8.2</version>
    </dependency>

配置

spy.properties

## 指定 Log 的 appender
appender=com.p6spy.engine.spy.appender.Slf4JLogger
## 消息格式化类
logMessageFormat=cc.zios.osrd.log.p6spy.P6SpyLogger
## 日期格式
databaseDialectDateFormat=yyyy-MM-dd hh:mm:ss
## 显示指定过滤 Log 时排队的分类列表
excludecategories=info,debug,result,resultset

编写类代理数据源插件

public class P6SpyDataSource extends DruidPlugin {
	
	private Logger log = LoggerFactory.getLogger(P6SpyDataSource.class);

	private P6DataSource p6spy = null;

	public P6SpyDataSource(String url, String username, String password) {
		super(url, username, password);
	}

	@Override
	public boolean start() {
		boolean start = super.start();
		p6spy = new P6DataSource(super.getDataSource());
		log.info("p6spy 数据源已装载");
		return start;
	}

	@Override
	public DataSource getDataSource() {
		return this.p6spy;
	}

}

配置 JFinal(configPlugin)

		// 数据源
		DruidPlugin ds = new P6SpyDataSource(PropKit.get("jdbc.url"), PropKit.get("jdbc.user"),
				PropKit.get("jdbc.password"));
		/* 
		 * DruidPlugin ds = new DruidPlugin(PropKit.get("jdbc.url"), PropKit.get("jdbc.user"),
		 * 		PropKit.get("jdbc.password"));
		 */
		ds.setInitialSize(PropKit.getInt("jdbc.initialSize")).setMinIdle(PropKit.getInt("jdbc.minIdle"))
				.setMaxActive(PropKit.getInt("jdbc.maxActive"));
		me.add(ds);

		ActiveRecordPlugin arp = new ActiveRecordPlugin("ds", ds);
		arp.setContainerFactory(new CaseInsensitiveContainerFactory(true));
		arp.setDialect(new Sqlite3Dialect());

		// 显示sql语句
		arp.setShowSql(false);

		me.add(arp);

编写类实现 SQL 过滤

public class P6SpyLogger implements MessageFormattingStrategy {

	@Override
	public String formatMessage(int connectionId, String now, long elapsed, String category, String prepared,
			String sql, String url) {
		StringBuilder result = new StringBuilder();
		if (StrKit.notBlank(sql)) {
			result.append("> use ").append(elapsed).append("ms [").append(category)
					.append("]\n").append("> ").append(sql);
			// 保存日志
		}
		return result.toString();
	}

}

效果

image.png

评论区

l745230

2021-12-31 09:36

看起来感觉还是log4jdbc 方便

山东小木

2021-12-31 10:25

druid自身就带着这个功能 没必要用第三方了

llyai

2022-01-04 10:25

@山东小木 我需要将SQL执行存到数据库的,druid不改源码不知道可不可以实现