Skip to content

Commit 24d2b6c

Browse files
committed
implement sql query filter. fix #14
1 parent b0c9abb commit 24d2b6c

File tree

3 files changed

+51
-6
lines changed

3 files changed

+51
-6
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88

99
## [2.0.0]
1010
### Added
11+
- Accept filter criteria for query counting
1112
- Make autocomplete work for N+1 queries detection properties.
1213
- Add more precise detection to
1314
- Avoid false positive with multiple calls to same method

src/main/java/com/yannbriancon/interceptor/HibernateQueryInterceptor.java

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,8 @@
1111

1212
import javax.persistence.EntityManager;
1313
import java.io.Serializable;
14-
import java.util.HashMap;
15-
import java.util.HashSet;
16-
import java.util.Map;
17-
import java.util.Optional;
18-
import java.util.Set;
14+
import java.util.*;
15+
import java.util.function.Predicate;
1916
import java.util.function.Supplier;
2017

2118
@Component
@@ -36,6 +33,7 @@ public class HibernateQueryInterceptor extends EmptyInterceptor {
3633

3734
private static final String HIBERNATE_PROXY_PREFIX = "org.hibernate.proxy";
3835
private static final String PROXY_METHOD_PREFIX = "com.sun.proxy";
36+
private transient Predicate<String> filter;
3937

4038
public HibernateQueryInterceptor(
4139
NPlusOneQueriesDetectionProperties NPlusOneQueriesDetectionProperties
@@ -70,16 +68,29 @@ public void startQueryCount() {
7068
threadQueryCount.set(0L);
7169
}
7270

71+
/**
72+
* Start or reset the query count to 0 for the considered thread.
73+
* Counts only if given filter matches.
74+
*
75+
* @param filter string filter predicate
76+
*/
77+
public void startQueryCount(Predicate<String> filter) {
78+
this.filter = filter;
79+
startQueryCount();
80+
}
81+
7382
/**
7483
* Get the query count for the considered thread
7584
*/
7685
public Long getQueryCount() {
86+
this.filter = null;
7787
return threadQueryCount.get();
7888
}
7989

8090
/**
8191
* Detect the N+1 queries by keeping the history of sql queries generated per proxy method.
8292
* Increment the query count for the considered thread for each new statement if the count has been initialized.
93+
* If a query filter is set it will be preferred.
8394
*
8495
* @param sql Query to be executed
8596
* @return Query to be executed
@@ -91,7 +102,13 @@ public String onPrepareStatement(String sql) {
91102
}
92103
Long count = threadQueryCount.get();
93104
if (count != null) {
94-
threadQueryCount.set(count + 1);
105+
if (Objects.nonNull(filter)) {
106+
if (filter.test(sql)) {
107+
threadQueryCount.set(count + 1);
108+
}
109+
} else {
110+
threadQueryCount.set(count + 1);
111+
}
95112
}
96113
return super.onPrepareStatement(sql);
97114
}

src/test/java/com/yannbriancon/interceptor/QueryCountTest.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,20 @@
44
import com.yannbriancon.utils.repository.MessageRepository;
55
import com.yannbriancon.utils.repository.UserRepository;
66
import org.junit.jupiter.api.Test;
7+
import org.junit.jupiter.params.ParameterizedTest;
8+
import org.junit.jupiter.params.provider.Arguments;
9+
import org.junit.jupiter.params.provider.MethodSource;
710
import org.junit.runner.RunWith;
811
import org.springframework.beans.factory.annotation.Autowired;
912
import org.springframework.boot.test.context.SpringBootTest;
1013
import org.springframework.test.context.junit4.SpringRunner;
1114
import org.springframework.transaction.annotation.Transactional;
1215

16+
import java.util.function.Predicate;
17+
import java.util.stream.Stream;
18+
1319
import static org.assertj.core.api.Assertions.assertThat;
20+
import static org.junit.jupiter.params.provider.Arguments.arguments;
1421

1522
@RunWith(SpringRunner.class)
1623
@SpringBootTest
@@ -45,4 +52,24 @@ void queryCount_isOkWhenSaveQueryIsExecutedBeforeStartingTheCount() {
4552

4653
assertThat(hibernateQueryInterceptor.getQueryCount()).isEqualTo(1);
4754
}
55+
56+
@ParameterizedTest
57+
@MethodSource("prepareQueryCountWithStartsWithFilterData")
58+
void queryCountWithStartsWithFilter(String filter, int expectedQueryCount) {
59+
final Predicate<String> predicate = f -> f.startsWith(filter);
60+
61+
hibernateQueryInterceptor.startQueryCount(predicate);
62+
63+
userRepository.saveAndFlush(new User());
64+
messageRepository.findAll();
65+
66+
assertThat(hibernateQueryInterceptor.getQueryCount()).isEqualTo(expectedQueryCount);
67+
}
68+
69+
static Stream<Arguments> prepareQueryCountWithStartsWithFilterData() {
70+
return Stream.of(arguments("select", 1),
71+
arguments("insert", 1),
72+
arguments("update", 0),
73+
arguments("delete", 0));
74+
}
4875
}

0 commit comments

Comments
 (0)