上海手机网站建设价格,做网站哪个软件好,WordPress留言提取,注册网站登录文章目录 前言 前言
对于一些Saas化软件#xff0c;当某个租户在执行查询SQL时#xff0c;如果查询条件出现了BUG#xff0c;导致去查了所有租户的数据#xff0c;这种情况是非常严重的#xff0c;此时就需要在架构层面做限制#xff0c;禁止一些特殊SQL的执行#xff… 文章目录 前言 前言
对于一些Saas化软件当某个租户在执行查询SQL时如果查询条件出现了BUG导致去查了所有租户的数据这种情况是非常严重的此时就需要在架构层面做限制禁止一些特殊SQL的执行另外为了保护数据库也可能会限制某些查询语句不要查询太多的数据那么怎样在平台架构层面对业务层的SQL做拦截和校验呢 本文分享一下我司的做法。
我们集团里有的项目用的Mybatis有的项目用的Spring Data JPA共同点在于都用的Druid连接池所以可以在Druid层面做SQL的拦截和校验。
Druid提供了FilterEventAdapter机制可以用来拦截数据库连接的创建、Statement或PreparedStatement的创建、SQL语句的执行等等我们可以自定义一个FilterEventAdapter
其中statementExecuteQueryBefore()方法表示在执行某个查询语句前的拦截点preparedStatement_executeQuery()方法表示执行查询语句的地方比如正常情况下preparedStatement_executeQuery()方法顺利执行的话就会得到ResultSetProxy可以理解为就是ResultSet也就代表查询结果集。 所以如果我们想做查询语句的拦截这两个方法都可以做到回到文章题目想要限制每次查询的结果集不能超过10000行该如何实现我这里给两种不同的实现方式。 对于某一个查询SQL我们首先得知道这个SQL将会查出多少条数据那就得把该查询SQL比如select a,b,c from t where a1改造成为select count(1) from t where a1执行改造后的count语句就能知道原始SQL会查出多少条记录了。 我这里提供一个方法能够把简单的select语句改造为count语句原谅我不能把公司内部的代码贴出来~~~
然后我们就能在statementExecuteQueryBefore()方法中做拦截判断了
这种方式的好处是如果某个查询SQL确实超过限制了那么就它被拦截了但是缺点是如果很多SQL并没有超过限制那么就多余执行了count语句降低了性能。 那么我们来看看第二种方案这种方法重写的是preparedStatement_executeQuery方法思路是先执行原始SQL得到ResultSet然后通过ResultSet来判断结果集是否超过了限制如果超过了限制则告警比如代码为
这种方案和第一种方案的优缺点正好相反优点是没有额外执行count语句缺点是如果查询语句确实超过了限制只能事后告警了。 这两种方案似乎鱼和熊掌不可兼得大家觉得哪个方案更好呢