實(shí)踐出真知,歡迎關(guān)注我的公眾號(hào):Hoeller
對(duì)于一些Saas化軟件,當(dāng)某個(gè)租戶在執(zhí)行查詢SQL時(shí),如果查詢條件出現(xiàn)了BUG,導(dǎo)致去查了所有租戶的數(shù)據(jù),這種情況是非常嚴(yán)重的,此時(shí)就需要在架構(gòu)層面做限制,禁止一些特殊SQL的執(zhí)行,另外,為了保護(hù)數(shù)據(jù)庫(kù),也可能會(huì)限制某些查詢語(yǔ)句不要查詢太多的數(shù)據(jù),那么怎樣在平臺(tái)架構(gòu)層面對(duì)業(yè)務(wù)層的SQL做攔截和校驗(yàn)?zāi)??本文分享一下我司的做法?/p>
我們集團(tuán)里有的項(xiàng)目用的Mybatis,有的項(xiàng)目用的Spring Data JPA,共同點(diǎn)在于都用的Druid連接池,所以可以在Druid層面做SQL的攔截和校驗(yàn)。
Druid提供了FilterEventAdapter機(jī)制,可以用來(lái)攔截?cái)?shù)據(jù)庫(kù)連接的創(chuàng)建、Statement或PreparedStatement的創(chuàng)建、SQL語(yǔ)句的執(zhí)行等等,我們可以自定義一個(gè)FilterEventAdapter:
其中statementExecuteQueryBefore()
方法表示在執(zhí)行某個(gè)查詢語(yǔ)句前的攔截點(diǎn),preparedStatement_executeQuery()
方法表示執(zhí)行查詢語(yǔ)句的地方,比如正常情況下preparedStatement_executeQuery()
方法順利執(zhí)行的話就會(huì)得到ResultSetProxy,可以理解為就是ResultSet,也就代表查詢結(jié)果集。
所以如果我們想做查詢語(yǔ)句的攔截,這兩個(gè)方法都可以做到,回到文章題目:想要限制每次查詢的結(jié)果集不能超過(guò)10000行,該如何實(shí)現(xiàn)?我這里給兩種不同的實(shí)現(xiàn)方式。
對(duì)于某一個(gè)查詢SQL,我們首先得知道這個(gè)SQL將會(huì)查出多少條數(shù)據(jù),那就得把該查詢SQL,比如select a,b,c from t where a=1
,改造成為select count(1) from t where a=1
,執(zhí)行改造后的count語(yǔ)句就能知道原始SQL會(huì)查出多少條記錄了。
我這里提供一個(gè)方法,能夠把簡(jiǎn)單的select語(yǔ)句改造為count語(yǔ)句(原諒我不能把公司內(nèi)部的代碼貼出來(lái)~~~)
然后,我們就能在statementExecuteQueryBefore()方法中做攔截判斷了:
這種方式的好處是:如果某個(gè)查詢SQL確實(shí)超過(guò)限制了,那么就它被攔截了,但是缺點(diǎn)是:如果很多SQL并沒(méi)有超過(guò)限制,那么就多余執(zhí)行了count語(yǔ)句,降低了性能。
那么我們來(lái)看看第二種方案,這種方法重寫的是preparedStatement_executeQuery
方法,思路是:先執(zhí)行原始SQL,得到ResultSet,然后通過(guò)ResultSet來(lái)判斷結(jié)果集是否超過(guò)了限制,如果超過(guò)了限制則告警,比如代碼為:
這種方案和第一種方案的優(yōu)缺點(diǎn)正好相反,優(yōu)點(diǎn)是:沒(méi)有額外執(zhí)行count語(yǔ)句,缺點(diǎn)是:如果查詢語(yǔ)句確實(shí)超過(guò)了限制只能事后告警了。
這兩種方案似乎魚和熊掌不可兼得,大家覺(jué)得哪個(gè)方案更好呢?文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-754360.html
我是大都督,之前是一名講師,現(xiàn)在是一名架構(gòu)師,實(shí)踐才能出真知,這是我重回一線的原因!如果大家覺(jué)得有所收獲,可以關(guān)注我的公眾號(hào):Hoeller,里面也有我的聯(lián)系方式,歡迎勾搭。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-754360.html
到了這里,關(guān)于SQL攔截:想要限制每次查詢的結(jié)果集不能超過(guò)10000行,該如何實(shí)現(xiàn)?的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!