当前位置:网站首页>How to use filters in jfinal to monitor Druid for SQL execution?
How to use filters in jfinal to monitor Druid for SQL execution?
2022-06-30 22:04:00 【Game programming】
Abstract : What I want to do at first is to intercept through interceptors SQL perform , But it was tested and found that , The filter can listen to at least every SQL Execution and return results of . therefore , Record this exploration .
This article is shared from Huawei cloud community 《jfinal Filter monitoring in Druid Of SQL perform 【 May 07】》, author :KevinQ .
What I want to do at first is to intercept through interceptors SQL perform , For example, similar to PageHelper This plug-in , Through interceptors or filters , Manually modify SQL sentence , To meet certain business requirements , For example, perform paging , Or restrict access to data permissions . But I found the information that the filter is not for this , This is what the database middleware does , such as MyCat etc. .
But it was tested and found that , The filter can listen to at least every SQL Execution and return results of . therefore , Record this exploration .
Configure filters
stay jfinal In the startup configuration class of , There is a function configPlugin(Plugins me) Function to configure the plug-in , This function will be in jfinal Call at startup , The argument to this function is Plugins me, This parameter is a plug-in manager , You can add plug-ins through this plug-in manager .
Database plug-ins Druid Is added in this function .
public void configPlugin(Plugins me) { DruidPlugin druidPlugin = createDruidPlugin_holdoa(); druidPlugin.setPublicKey(p.get("publicKeydebug").trim()); wallFilter = new WallFilter(); wallFilter.setDbType("mysql"); druidPlugin_oa.addFilter(wallFilter); druidPlugin_oa.addFilter(new StatFilter()); me.add(druidPlugin);}We refer to WallFilter as well as StatFilter Also create a filter class :
import com.alibaba.druid.filter.FilterEventAdapter;public class DataScopeFilter extends FilterEventAdapter {}We found that FilterEventAdapter There are several methods in :
public boolean statement_execute(FilterChain chain, StatementProxy statement, String sql) throws SQLException {...}protected void statementExecuteUpdateBefore(StatementProxy statement, String sql) {...}protected void statementExecuteUpdateAfter(StatementProxy statement, String sql, int updateCount) {...}protected void statementExecuteQueryBefore(StatementProxy statement, String sql) {...}protected void statementExecuteQueryAfter(StatementProxy statement, String sql, ResultSetProxy resultSet) {...}protected void statementExecuteBefore(StatementProxy statement, String sql) {...}protected void statementExecuteAfter(StatementProxy statement, String sql, boolean result) {...}Let's repeat these methods to see ( exclude Update Method , Because we are more concerned with query statements )
package xxxx.xxxx;import com.alibaba.druid.filter.FilterChain;import com.alibaba.druid.filter.FilterEventAdapter;import com.alibaba.druid.proxy.jdbc.ResultSetProxy;import com.alibaba.druid.proxy.jdbc.StatementProxy;import com.jfinal.kit.LogKit;import java.sql.SQLException;public class DataScopeFilter extends FilterEventAdapter { @Override public boolean statement_execute(FilterChain chain, StatementProxy statement, String sql) throws SQLException { LogKit.info("statement_execute"); return super.statement_execute(chain, statement, sql); } @Override protected void statementExecuteQueryBefore(StatementProxy statement, String sql) { LogKit.info("statementExecuteQueryBefore"); super.statementExecuteQueryBefore(statement, sql); } @Override protected void statementExecuteQueryAfter(StatementProxy statement, String sql, ResultSetProxy resultSet) { LogKit.info("statementExecuteQueryAfter"); super.statementExecuteQueryAfter(statement, sql, resultSet); } @Override protected void statementExecuteBefore(StatementProxy statement, String sql) { LogKit.info("statementExecuteBefore"); super.statementExecuteBefore(statement, sql); } @Override protected void statementExecuteAfter(StatementProxy statement, String sql, boolean result) { LogKit.info("statementExecuteAfter"); super.statementExecuteAfter(statement, sql, result); } @Override public ResultSetProxy statement_executeQuery(FilterChain chain, StatementProxy statement, String sql) throws SQLException { LogKit.info("statement_executeQuery"); return super.statement_executeQuery(chain, statement, sql); }}And then again config Add a filter to the configuration class :
druidPlugin.addFilter(new DataScopeFilter());The execution sequence of the initiation is :
statement_executeQuerystatementExecuteQueryBeforestatementExecuteQueryAfterView parent code , It is found that the execution logic is , First, execute statement_executeQuery, And then because the method of the parent is called , The parent method body is :
@Override public ResultSetProxy statement_executeQuery(FilterChain chain, StatementProxy statement, String sql) throws SQLException { statementExecuteQueryBefore(statement, sql); try { ResultSetProxy resultSet = super.statement_executeQuery(chain, statement, sql); if (resultSet != null) { statementExecuteQueryAfter(statement, sql, resultSet); resultSetOpenAfter(resultSet); } return resultSet; } catch (SQLException error) { statement_executeErrorAfter(statement, sql, error); throw error; } catch (RuntimeException error) { statement_executeErrorAfter(statement, sql, error); throw error; } catch (Error error) { statement_executeErrorAfter(statement, sql, error); throw error; } } This further triggers statementExecuteQueryBefore Methods and statementExecuteQueryAfter Method .
So we , modify statement_executeQuery Method :
@Override public ResultSetProxy statement_executeQuery(FilterChain chain, StatementProxy statement, String sql) throws SQLException { statementExecuteQueryBefore(statement, sql); ResultSetProxy result = chain.statement_executeQuery(statement, sql); statementExecuteQueryAfter(statement, sql, result); return result; }such , Let the output result be :
statementExecuteQueryBeforestatement_executeQuerystatementExecuteQueryAfterWe can do it in Before perhaps After Method , such as : Record SQL The actual executor of , Operating time , Request execution SQL The interface of .
sql Be declared final type
Find out what's going on SQL stay Druid The corresponding class in is :DruidPooledPreparedStatement, Its class structure is :
public class DruidPooledPreparedStatement extends DruidPooledStatement implements PreparedStatement { private final static Log LOG = LogFactory.getLog(DruidPooledPreparedStatement.class); private final PreparedStatementHolder holder; private final PreparedStatement stmt; private final String sql; ....} This means , Once this class is created ,SQL After setting, it cannot be modified , therefore , We need to change SQL Words , It needs to be in prepared The object is modified to the corresponding execution before it is generated SQL.
In the course of debugging , It is found that the following method needs to be overwritten :
@Override public PreparedStatementProxy connection_prepareStatement(FilterChain chain, ConnectionProxy connection, String sql) throws SQLException { // It can be modified SQL Purpose sql += " LIMIT 1"; PreparedStatementProxy statement = super.connection_prepareStatement(chain, connection, sql); statementPrepareAfter(statement); return statement; } We can add custom here SQL Modify the logic , For example, add data permissions and so on .
Click to follow , The first time to learn about Huawei's new cloud technology ~
author : Huawei cloud developer Alliance
Game programming , A game development favorite ~
If the picture is not displayed for a long time , Please use Chrome Kernel browser .
边栏推荐
- How to judge whether the JS object is empty
- Apache服务器OpenSSL升级
- 国产数据库乱象
- [BSP video tutorial] BSP video tutorial issue 19: AES encryption practice of single chip bootloader, including all open source codes of upper and lower computers (June 26, 2022)
- 1-18 create the most basic express server & API module for creating routes
- Is Wu Enda's machine learning suitable for entry?
- HDFS集中式缓存管理(Centralized Cache Management)
- 5G 在智慧医疗中的需求
- Excitatory neurotransmitter glutamate and brain health
- 1-17 express中间件
猜你喜欢

Failed to configure a DataSource: ‘url‘ attribute is not specified and no embedded datasource could

Jupyter notebook/lab switch CONDA environment

牛逼|珍藏多年的工具让我实现了带薪摸鱼自由

Modify the name of the launched applet

Anfulai embedded weekly report no. 270: June 13, 2022 to June 19, 2022

京东与腾讯续签三年战略合作协议;起薪涨至26万元,韩国三星SK争相加薪留住半导体人才;Firefox 102 发布|极客头条

PyTorch量化实践(1)

Zhoushaojian, rare

PostgreSQL存储结构浅析

Introduce an online platform for multi omics integration and network visual analysis
随机推荐
开发属于自己的包
Excitatory neurotransmitter glutamate and brain health
Web APIs comprehensive case -tab column switching - dark horse programmer
Jupyter notebook/lab switch CONDA environment
微服务链路风险分析
在启牛开的股票账户安全吗?如何申请低佣金的股票账户?
Pytorch quantitative practice (2)
WinDbg debugging tool introduction
How to realize the center progress bar in wechat applet
国产数据库乱象
Uniapp third party network request
将Nagios监控信息存入MySQL
盘点华为云GaussDB(for Redis)六大秒级能力
About, Qianxin detects code vulnerabilities and XSS series solves them
ML&DL:機器學習和深度學習中超參數優化的簡介、評估指標、過擬合現象、常用的調參優化方法之詳細攻略
Inventory the six second level capabilities of Huawei cloud gaussdb (for redis)
Is Wu Enda's machine learning suitable for entry?
Apache服务器OpenSSL升级
Bloom filter
【回溯】全排列 II leetcode47