当前位置:网站首页>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-29 22:00:00 【Huawei cloud developer Alliance】
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 ~
边栏推荐
- Final training simple address book c language
- leetcode:238. Product of arrays other than itself
- Reflections on remote sensing image interpretation
- My creation anniversary
- Cloud native database query optimization - statistics and row count estimation
- 企业实施MES系统的关键点详解
- The soft youth under the blessing of devcloud makes education "smart" in the cloud
- leetcode:724. Find the central subscript of the array
- DB queries the database, merges two unrelated tables, adds non-existent fields, and assigns default values
- Flutter technology and Practice (2)
猜你喜欢

Summer Challenge harmonyos ark development framework arkui streamer button effect

Simple analysis of wieshark packet capturing MySQL protocol
![[advanced ROS] Lecture 3 ROS file system and distributed communication](/img/9f/2c316f5b0aa36b63769672048da772.png)
[advanced ROS] Lecture 3 ROS file system and distributed communication

Star ring technology data security management platform defender heavy release

yolov6训练自己的数据记录+yolov5对比测试

Golang operation NSQ distributed message queue

Win10添加ssh公钥

Flame retardant test of aluminum sheet as/nzs 1530.1 non combustible materials

leetcode:307. Area and retrieval - array modifiable

Shangsilicon Valley real-time data warehouse project (Alibaba cloud real-time data warehouse)
随机推荐
How to integrate MES system with ERP? This article tells you the answer
ASP动态创建表格 Table
硅树脂油漆申请美国标准UL 790 Class A 合适吗?
Which brokerage commission is the lowest and safest
Amazon Product details API interface - (item_get get Amazon Product details interface), Amazon details API interface
Numpy's research imitation 1
这次跟大家聊聊技术,也聊聊人生
Deep learning remote sensing data set
Golang operation etcd
Db查询数据库合并两个不相关的表,新增不存在的字段,并赋予默认值
Huawei cloud AOM version 2.0 release
Top ten questions for senior Performance Test Engineer
Structure the fifth operation of the actual camp module
In the shop project, implement a menu (add, delete, modify and query)
The logic behind the three whys encountered in technical communication
【ROS进阶篇】第二讲 自定义头、源文件封装
A. Marathon
Detailed explanation of key points in implementing MES system in Enterprises
Summary of document level symbols under different systems
leetcode:238. Product of arrays other than itself