[java] I want to limit the result set of each query to no more than 10,000 rows. How to achieve this?

Article directory

Preface

For some Saas-based software, when a tenant is executing query SQL, if a bug occurs in the query conditions, resulting in the data of all tenants being checked, this situation is very serious, and it is necessary to There are restrictions at the architecture level to prohibit the execution of some special SQL. In addition, in order to protect the database, some query statements may also be restricted from querying too much data. So how to intercept and verify the SQL of the business layer at the platform architecture level? ?
This article shares our company’s approach.

Some projects in our group use Mybatis, and some projects use Spring Data JPA. The common point is that they all use Druid connection pools, so SQL interception and verification can be done at the Druid level.

Druid provides a FilterEventAdapter mechanism, which can be used to intercept the creation of database connections, creation of Statement or PreparedStatement, execution of SQL statements, etc. We can customize a FilterEventAdapter:
Insert image description here

The statementExecuteQueryBefore() method represents the interception point before executing a query statement, and the preparedStatement_executeQuery() method represents the place where the query statement is executed. For example, under normal circumstances, if the preparedStatement_executeQuery() method is successfully executed, the ResultSetProxy will be obtained. It is understood as ResultSet, which represents the query result set.
So if we want to intercept query statements, both of these methods can be done. Back to the title of the article: If we want to limit the result set of each query to no more than 10,000 rows, how to achieve it? ? I give two different implementation methods here.
For a certain query SQL, we first need to know how many pieces of data this SQL will find, then we have to query the SQL, such as select a,b,c from t where a=1 , transformed into select count(1) from t where a=1. Execute the transformed count statement to know how many records the original SQL will find.
Here I provide a method that can transform a simple select statement into a count statement (forgive me for not posting the company's internal code~~~)
Insert image description here

Then, we can make interception judgments in the statementExecuteQueryBefore() method:
Insert image description here

The advantage of this method is that if a certain query SQL does exceed the limit, then it will be intercepted. However, the disadvantage is that if many SQL queries do not exceed the limit, then the count statement will be executed redundantly, reducing the performance.
Then let’s take a look at the second solution. This method rewrites the preparedStatement_executeQuery method. The idea is: first execute the original SQL to get the ResultSet, and then use the ResultSet to determine whether the result set exceeds Limit. If the limit is exceeded, an alarm will be issued. For example, the code is:
Insert image description here

This solution has the opposite advantages and disadvantages to the first solution. The advantage is that there is no additional count statement to be executed. The disadvantage is that if the query statement indeed exceeds the limit, an alarm can only be issued afterwards.
These two options seem to be incompatible. Which one do you think is better?

Guess you like

Origin blog.csdn.net/u011397981/article/details/134564344