my batis SQL 조회 차단 수정 상세 설명 실현
차단기 의 한 역할 은 바로 우리 가 어떤 방법의 호출 을 차단 할 수 있다 는 것 이다.우 리 는 이러한 차단 되 는 방법 이 실 행 된 전후 에 어떤 논 리 를 추가 할 수도 있 고,이러한 차단 되 는 방법 을 실행 할 때 자신의 논 리 를 실행 할 수도 있 으 며,더 이상 차단 되 는 방법 을 실행 하지 않 을 수도 있다.
Mybatis 차단기 디자인 의 취 지 는 사용자 가 언젠가 자신의 논 리 를 실현 할 수 있 도록 하기 위해 Mybatis 고유의 논 리 를 건 드 리 지 않 아 도 된다 는 것 이다.예 를 들 어 저 는 모든 SQL 에 대해 고정된 작업 을 수행 하고 싶 습 니 다.SQL 조회 에 대해 안전 검 사 를 실시 하거나 관련 SQL 조회 로 그 를 기록 하고 싶 습 니 다.
Mybatis 는 사용자 정의 차단 기 를 실현 할 수 있 는 Interceptor 인 터 페 이 스 를 제공 합 니 다.
public interface Interceptor {
Object intercept(Invocation invocation) throws Throwable;
Object plugin(Object target);
void setProperties(Properties properties);
}
인터페이스 에는 세 가지 방법 정의 가 포함 되 어 있다.intercept 방법 은 구체 적 인 차단 대상 의 처리 방법 으로 들 어 오 는 Invocation 은 목표 류 를 차단 하 는 실력,차단 하 는 방법 과 방법의 입 매개 변수 그룹 을 포함한다.Invocation 의 procced 를 사용 하여 원 함 수 를 실행 합 니 다.
plugin 에서 차단 을 할 지 여 부 를 판단 합 니 다.차단 이 필요 하지 않 으 면 target 으로 돌아 갑 니 다.차단 이 필요 하 다 면 plugin 류 의 wrap 정적 방법 을 호출 합 니 다.현재 차단기 가 임의의 인 터 페 이 스 를 실현 하면 프 록 시 대상 을 되 돌려 줍 니 다.그렇지 않 으 면 바로 돌아 갑 니 다(메모리 프 록 시 모드 의 디자인).프 록 시 대상 은 실제 Plugin 클래스 의 인 스 턴 스 입 니 다.Invocation Handler 인 터 페 이 스 를 실 현 했 습 니 다.Invocation Handler 인 터 페 이 스 는 invoke 방법 만 포함 하여 리 셋 방법 에 사 용 됩 니 다.
프 록 시 대상 의 인터페이스 방법 을 실행 할 때 Plugin 의 invoke 방법 을 호출 합 니 다.실행 할 대상,방법 과 파 라 메 터 를 Invocation 대상 으로 포장 하여 차단기 의 intercept 방법 에 전달 합 니 다.Invocation 은 차단 되 는 원래 방법 을 실행 하기 위해 procced 방법 을 정의 합 니 다.
플러그 인 클래스 정의
public class Plugin implements InvocationHandler {
private Object target;
private Interceptor interceptor;
private Map, Set> signatureMap;
private Plugin(Object target, Interceptor interceptor, Map, Set> signatureMap) {
this.target = target;
this.interceptor = interceptor;
this.signatureMap = signatureMap;
}
public static Object wrap(Object target, Interceptor interceptor) {
Map, Set> signatureMap = getSignatureMap(interceptor);
Class type = target.getClass();
Class[] interfaces = getAllInterfaces(type, signatureMap);
if (interfaces.length > 0) {
return Proxy.newProxyInstance(
type.getClassLoader(),
interfaces,
new Plugin(target, interceptor, signatureMap));
}
return target;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
Set methods = signatureMap.get(method.getDeclaringClass());
if (methods != null && methods.contains(method)) {
return interceptor.intercept(new Invocation(target, method, args));
}
return method.invoke(target, args);
} catch (Exception e) {
throw ExceptionUtil.unwrapThrowable(e);
}
}
private static Map, Set> getSignatureMap(Interceptor interceptor) {
Intercepts interceptsAnnotation = interceptor.getClass().getAnnotation(Intercepts.class);
if (interceptsAnnotation == null) { // issue #251
throw new PluginException("No @Intercepts annotation was found in interceptor " + interceptor.getClass().getName());
}
Signature[] sigs = interceptsAnnotation.value();
Map, Set> signatureMap = new HashMap, Set>();
for (Signature sig : sigs) {
Set methods = signatureMap.get(sig.type());
if (methods == null) {
methods = new HashSet();
signatureMap.put(sig.type(), methods);
}
try {
Method method = sig.type().getMethod(sig.method(), sig.args());
methods.add(method);
} catch (NoSuchMethodException e) {
throw new PluginException("Could not find method on " + sig.type() + " named " + sig.method() + ". Cause: " + e, e);
}
}
return signatureMap;
}
private static Class[] getAllInterfaces(Class type, Map, Set> signatureMap) {
Set> interfaces = new HashSet>();
while (type != null) {
for (Class c : type.getInterfaces()) {
if (signatureMap.containsKey(c)) {
interfaces.add(c);
}
}
type = type.getSuperclass();
}
return interfaces.toArray(new Class[interfaces.size()]);
}
}
setProperties 방법 은 말 그대로 속성 을 설정 하 는 데 사 용 됩 니 다.bean 의 속성 초기 화 방법 은 매우 많은 데,이것 은 그 중의 하나 입 니 다.my batis 는 현재 클래스 가 차단기 임 을 설명 하 는@Intercepts 주 해 를 제공 합 니 다.그 값 은@Signature 배열 로 차단 할 인터페이스,방법 및 대응 하 는 매개 변수 유형 을 표시 합 니 다.
@Intercepts({@Signature(method = "prepare", type = StatementHandler.class, args = {Connection.class}),
@Signature(method = "query", type = StatementHandler.class, args = {java.sql.Statement.class, ResultHandler.class})})
public class TenantInterceptor implements Interceptor {
.....
예 를 들 어 위의 클래스 성명 에서 첫 번 째 Signature 레이 블 은 StatementHandler 클래스 의 입 참 을 차단 하 는 것 은 Connection 이라는 prepare 라 는 방법 입 니 다.두 번 째 Signature 는 StatementHandler 클래스 에 2 개의 입 참(각각 Statement 과 ResultHandler 형식)을 포함 하 는 query 라 는 방법 을 표시 합 니 다.
마지막 으로 성명 한 Interceptor 는 my batis 의 plug 에 등록 해 야 효력 이 발생 합 니 다.
<!-- mybatis -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:mybatis/mybatis-config.xml"/>
<!-- mapper -->
<property name="mapperLocations" value="classpath:mybatis/*/*.xml"/>
<property name="plugins">
<array>
<!-- -->
<bean id="paginationInterceptor" class="xxx.xxx.TenantInterceptor">
</bean>
</array>
</property>
</bean>
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
MySQL/마이바티스 | 동적 쿼리 사용A라는 서비스에 해당하는 테이블을 조인하고 조회하는 데 사용됩니다. 나중에 공통화를 위해 B 및 C 서비스도 추가됩니다. A, B, C 서비스는 모두 단일 쿼리에서 작동할 수 있도록 공통화되어야 합니다. 테이블에 각...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.