jfinal-配置druid进行监控及打印sql语句

本文介绍如何使用Druid配置SQL语句打印、监控统计功能,包括Filter配置、log4j2日志配置及内置监控配置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景介绍

前一段时间看了一篇打印sql语句的分享,如下:Jfinal中使用日志框架输出完整sql语句信息

该文章中使用额外的jar包进行sql语句打印,

<dependency>
    <groupId>com.googlecode.log4jdbc</groupId>
    <artifactId>log4jdbc</artifactId>
    <version>1.2</version>
</dependency>

但是因为日志框架的问题无法使用,谁知柳暗花明又一村,让我发现了druid,druid能做的事情更多,除了打印sql外还能监控,统计.druid常见问题

本文整理了druid的sql语句打印,监控统计功能的配置

sql语句打印

filter配置

druid使用了拦截过滤器模式,只要配置相应Filter的即可,代码如下

/**
 * @return 配置完善的DruidPlugin
 */
public static DruidPlugin createDruidPlugin() {
   // 从配置文件中读取数据库url,username,password
   String name = Const.devProfile.getName();
   String url = prop.get(name + ".db.url");
   String username = prop.get(name + ".db.username");
   String password = prop.get(name + ".db.password").trim();
   DruidPlugin dp = new DruidPlugin(url, username, password);
   // 添加数据库插件
   // 1.统计信息插件
   StatFilter statFilter = new StatFilter();
   statFilter.setMergeSql(true);
   statFilter.setLogSlowSql(true);
   // 慢查询目前设置为1s,随着优化一步步进行慢慢更改
   statFilter.setSlowSqlMillis(Duration.ofMillis(1000).toMillis());
   dp.addFilter(statFilter);
   // 2.日志插件
   // 保存DruidDataSource的监控记录,设置打印日志周期,默认使用DruidDataSourceStatLoggerImpl
   // DruidPlugin未暴露setTimeBetweenLogStatsMillis(),只能使用properties方法设置
   dp.setConnectionProperties("druid.timeBetweenLogStatsMillis="
         + Duration.ofHours(24).toMillis());
   Slf4jLogFilter slf4jLogFilter = new Slf4jLogFilter();
   slf4jLogFilter.setDataSourceLogEnabled(false);
   slf4jLogFilter.setConnectionLogEnabled(false);
   slf4jLogFilter.setConnectionLogErrorEnabled(true);
   slf4jLogFilter.setStatementLogEnabled(false);
   slf4jLogFilter.setStatementLogErrorEnabled(true);
   slf4jLogFilter.setResultSetLogEnabled(false);
   slf4jLogFilter.setResultSetLogErrorEnabled(true);
   slf4jLogFilter.setConnectionConnectBeforeLogEnabled(false);
   slf4jLogFilter.setConnectionConnectAfterLogEnabled(false);
   slf4jLogFilter.setConnectionCommitAfterLogEnabled(false);
   slf4jLogFilter.setConnectionRollbackAfterLogEnabled(true);
   slf4jLogFilter.setConnectionCloseAfterLogEnabled(false);
   slf4jLogFilter.setStatementCreateAfterLogEnabled(false);
   slf4jLogFilter.setStatementPrepareAfterLogEnabled(false);
   slf4jLogFilter.setStatementPrepareCallAfterLogEnabled(false);
   slf4jLogFilter.setStatementExecuteAfterLogEnabled(false);
   slf4jLogFilter.setStatementExecuteQueryAfterLogEnabled(false);
   slf4jLogFilter.setStatementExecuteUpdateAfterLogEnabled(false);
   slf4jLogFilter.setStatementExecuteBatchAfterLogEnabled(false);
   slf4jLogFilter.setStatementCloseAfterLogEnabled(false);
   slf4jLogFilter.setStatementParameterSetLogEnabled(false);
   slf4jLogFilter.setResultSetNextAfterLogEnabled(false);
   slf4jLogFilter.setResultSetOpenAfterLogEnabled(false);
   slf4jLogFilter.setResultSetCloseAfterLogEnabled(false);
   if (Const.devProfile == Const.DevProfile.LOCAL_DEV
         || Const.devProfile == Const.DevProfile.LOCAL_TEST) {
      slf4jLogFilter.setStatementExecutableSqlLogEnable(true);
   }
   dp.addFilter(slf4jLogFilter);
   // 3.防注入插件
   WallFilter wall = new WallFilter();
   wall.setDbType("mysql");
   dp.addFilter(wall);
   return dp;
}

配置了3个Filter,就是配置Slf4jLogFilter时需要注意哪些需要打印,哪些不需要

log4j2 配置

此外,还要在log4j2中配置日志过滤,我的Logger配置如下

<Loggers>
    <!--打印无用日志较多的设置level为info-->
    <!--<Logger name="net.sf.ehcache" level="WARN"/>-->
    <Logger name="org.apache.shiro.web.servlet.SimpleCookie" level="info"/>
    <Logger name="org.apache.shiro" level="info"/>

    <!--设置druid日志level为debug-->
    <Logger name="druid" level="debug" additivity="false">
        <AppenderRef ref="sql"/>
        <AppenderRef ref="Console"/>
    </Logger>

    <Root level="debug">
        <AppenderRef ref="Console"/>
        <AppenderRef ref="debug"/>
        <AppenderRef ref="info"/>
        <AppenderRef ref="warn"/>
        <AppenderRef ref="error"/>
    </Root>
</Loggers>

druid的监控功能

druid的监控功能是通过配置servlet和filter实现的,配置如下:

<!--配置Druid的WebStatFilter-->
<filter>
    <filter-name>DruidWebStatFilter</filter-name>
    <filter-class>com.app.vocalist.filter.druid.MyWebStatFilter</filter-class>
    <init-param>
        <param-name>exclusions</param-name>
        <param-value>*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*</param-value>
    </init-param>
    <init-param>
        <!--开启session监控-->
        <param-name>sessionStatEnable</param-name>
        <param-value>true</param-value>
    </init-param>
    <init-param>
        <!--最大监控session数-->
        <param-name>sessionStatMaxCount</param-name>
        <param-value>2000</param-value>
    </init-param>
    <init-param>
        <!--principal在session中的属性名-->
        <param-name>principalSessionName</param-name>
        <param-value>user</param-value>
    </init-param>
    <init-param>
        <!--单条url分析-->
        <param-name>profileEnable</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>
<!--Druid内置监控配置-->
<servlet>
    <servlet-name>DruidStatView</servlet-name>
    <servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
    <init-param>
        <!-- 用户名 -->
        <param-name>loginUsername</param-name>
        <param-value>root</param-value>
    </init-param>
    <init-param>
        <!-- 密码 -->
        <param-name>loginPassword</param-name>
        <param-value>root</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>DruidStatView</servlet-name>
    <url-pattern>/druid/*</url-pattern>
</servlet-mapping>

注意:

  • com.app.vocalist.filter.druid.MyWebStatFilter是我写的继承com.alibaba.druid.support.http.WebStatFilter的一个类,重写了getPrincipal(httpRequest)
  • jfinal框架是一个Filter,处理request后不会将其交给后续的servlet,而是直接返回(其实是使用了boolean[] isHandled = {false}作为标志,但是在ActionHandler中会将其设置为true,doFilter()中判断为true就直接返回了)
  • 可以在jfinal中设置com.jfinal.plugin.druid.DruidStatViewHandler进行处理,我所有的url格式为/api/*,所以将配置<filter-mapping>即可
<filter-mapping>
    <filter-name>jfinal</filter-name>
    <url-pattern>/api/*</url-pattern>
</filter-mapping>

参考

JFinal 是一款基于 Java 的轻量级 Web 开发框架,支持使用 Java 语言进行 Web 应用开发。JFinal 提供了一个简单的 ORM 框架来操作数据库,使用 JFinal 可以很方便地将中文转换为 SQL 语句。 以下是实现步骤: 1. 首先需要在项目中引入 jfinaldruid 的 jar 包。 2. 在 src/main/resources 目录下创建一个名为 druid.properties 的文件,配置数据库连接信息。例如: ``` jdbcUrl=jdbc:mysql://localhost:3306/test username=root password=123456 driverClassName=com.mysql.jdbc.Driver ``` 3. 在项目中创建一个继承自 JFinalConfig 的配置类,配置数据库连接池和路由。例如: ``` public class AppConfig extends JFinalConfig { public void configConstant(Constants constants) { // 配置开发模式 constants.setDevMode(true); } public void configRoute(Routes routes) { // 配置路由 routes.add("/user", UserController.class); } public void configPlugin(Plugins plugins) { // 配置 druid 数据库连接池插件 DruidPlugin druidPlugin = new DruidPlugin( getProperty("jdbcUrl"), getProperty("username"), getProperty("password"), getProperty("driverClassName") ); plugins.add(druidPlugin); // 配置 ActiveRecord 插件 ActiveRecordPlugin arp = new ActiveRecordPlugin(druidPlugin); plugins.add(arp); // 配置 MySQL 数据库方言 arp.setDialect(new MysqlDialect()); } } ``` 4. 创建一个 UserController 类,处理中文转 SQL 的请求。例如: ``` public class UserController extends Controller { public void index() { renderText("Welcome to JFinal!"); } public void search() { String keyword = getPara("keyword"); String sql = Db.getSql("user.search", keyword); List<User> userList = User.dao.find(sql); renderJson(userList); } } ``` 5. 在 src/main/resources 目录下创建一个名为 sql 的文件夹,用于存放 SQL 文件。例如: ``` user.search=SELECT * FROM user WHERE name LIKE '%?%' ``` 6. 运行项目,在浏览器中访问 http://localhost:8080/user/search?keyword=张三,即可将关键字“张三”转换为 SQL 语句并执行查询。查询结果将以 JSON 格式返回。 以上就是使用 JFinal 实现中文转 SQL 的基本步骤。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值