package bj.mybatisinterceptor;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import com.zaxxer.hikari.HikariDataSource;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.LoggerFactory;
import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import javax.sql.DataSource;
import javax.validation.constraints.NotNull;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.sql.Connection;
import java.util.List;
import java.util.Map;
import java.util.Properties;
/**
* Created by BaiJiFeiLong@gmail.com at 2018/12/26 下午1:20
*/
@SpringBootApplication
public class App implements ApplicationListener<ApplicationReadyEvent> {
public static void main(String[] args) {
new SpringApplicationBuilder(App.class).web(WebApplicationType.NONE).run(args);
}
@Resource
private JdbcTemplate jdbcTemplate;
@Resource
private UserMapper userMapper;
@Override
public void onApplicationEvent(@NotNull ApplicationReadyEvent event) {
((Logger) LoggerFactory.getLogger(App.class.getPackage().getName())).setLevel(Level.INFO);
jdbcTemplate.execute("DROP TABLE IF EXISTS user");
jdbcTemplate.execute("CREATE TABLE user(id INT PRIMARY KEY AUTO_INCREMENT, username TEXT)");
jdbcTemplate.execute("INSERT INTO user(username) VALUES ('alpha'), ('beta')");
System.out.println("findAll:");
System.out.println(userMapper.findAll());
System.out.println();
System.out.println("findAllLimitOneByAnnotation:");
System.out.println(userMapper.findAllLimitOneByAnnotation());
System.out.println();
System.out.println("findAll again:");
System.out.println(userMapper.findAll());
System.out.println();
System.out.println("findAllLimitOneByAnnotation again:");
System.out.println(userMapper.findAllLimitOneByAnnotation());
System.out.println();
}
@Bean
public DataSource dataSource() {
return new HikariDataSource() {{
setJdbcUrl("jdbc:mysql://localhost/foo");
setUsername("root");
setPassword("root");
}};
}
@Mapper
@Component
interface UserMapper {
@Select("SELECT * FROM user")
List<Map<String, Object>> findAll();
@LimitOne
@Select("SELECT * FROM user")
List<Map<String, Object>> findAllLimitOneByAnnotation();
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface LimitOne {
}
@Component
@Aspect
static class MyAspect {
@Around("@annotation(limitOne)")
public Object doAnnotation(ProceedingJoinPoint joinPoint, LimitOne limitOne) {
try {
LimitOneMyBatisInterceptor.LIMIT_ONE.set(Object.class);
return joinPoint.proceed();
} catch (Throwable throwable) {
throw new RuntimeException(throwable);
} finally {
LimitOneMyBatisInterceptor.LIMIT_ONE.remove();
}
}
}
@Component
@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})
static class LimitOneMyBatisInterceptor implements Interceptor {
final static ThreadLocal<Object> LIMIT_ONE = new ThreadLocal<>();
@Override
public Object intercept(Invocation invocation) throws Throwable {
final String SQL = "delegate.boundSql.sql";
MetaObject metaObject = SystemMetaObject.forObject(invocation.getTarget());
if (LIMIT_ONE.get() != null)
metaObject.setValue(SQL, String.format("%s LIMIT 1", metaObject.getValue(SQL)));
System.out.printf("SQL: \033[1;35m%s\033[0m\n", metaObject.getValue(SQL));
return invocation.proceed();
}
@Override
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
@Override
public void setProperties(Properties properties) {
}
}
}
控制台输出
findAll:
SQL: SELECT * FROM user
[{id=1, username=alpha}, {id=2, username=beta}]
findAllLimitOneByAnnotation:
SQL: SELECT * FROM user LIMIT 1
[{id=1, username=alpha}]
findAll again:
SQL: SELECT * FROM user
[{id=1, username=alpha}, {id=2, username=beta}]
findAllLimitOneByAnnotation again:
SQL: SELECT * FROM user LIMIT 1
[{id=1, username=alpha}]
以上所述就是小编给大家介绍的《mybatis-interceptor》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Effective JavaScript
赫尔曼 (David Herman) / 黄博文、喻杨 / 机械工业出版社 / 2014-1-1 / CNY 49.00
Effective 系列丛书经典著作,亚马逊五星级畅销书,Ecma 的JavaScript 标准化委员会著名专家撰写,JavaScript 语言之父、Mozilla CTO —— Brendan Eich 作序鼎力推荐!作者凭借多年标准化委员会工作和实践经验,深刻辨析JavaScript 的内部运作机制、特性、陷阱和编程最佳实践,将它们高度浓缩为极具实践指导意义的 68 条精华建议。 本书共......一起来看看 《Effective JavaScript》 这本书的介绍吧!