mybatis plus的springboot配置方式和mvc配置方式

目录

                                                                                               mybatis plus的springboot配置方式和mvc配置方式

1、MybatisPlus的springboot的配置方式

1.1、配置application.properties

1.2、MybatisPlusConfig配置

2、mvc配置

2.1、配置properties

2.2、MybatisPlusConfig配置

2.3、SqlLogInterceptor

2.4、TransactionalConfig


1、MybatisPlus的springboot的配置方式

1.1、配置application.properties

#mybatis-plus
mybatis-plus.type-aliases-package=com.xx.archive.*
mybatis-plus.mapper-locations=classpath:dao/*.xml
mybatis-plus.global-config.db-config.table-underline=true
#mybatis-plus.global-config.db-config.column-underline=true
mybatis-plus.global-config.db-config.id-type=auto
#下面这句打开的时候是可以进行 打印sql到控制台
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

1.2、MybatisPlusConfig配置



@Configuration
public class MybatisPlusConfig {
    /*
     * 分页插件,自动识别数据库类型
     * 多租户,请参考官网【插件扩展】
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor page = new PaginationInterceptor();
        page.setDialectType("mysql");
        return page;
    }

    /**
     * SQL执行效率插件(打印sql)
     */
    @Bean
    public PerformanceInterceptor performanceInterceptor() {
        PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
        return performanceInterceptor;
    }
}

2、mvc配置

2.1、配置properties

#mybatis-plus config
mybatis-plus.entities=com.xx.archive
mybatis-plus.mapper=classpath*:dao/*.xml,classpath*:dao/system/*.xml
mybatis-plus.transaction.definition=true

2.2、MybatisPlusConfig配置


@Configuration
@PropertySource(value = "classpath:mybatis/mybatis.properties")
public class MybatisPlusConfig {

    /**
     * 慢查询
     */
    public static final int TIME = 300;

    @Value("${mybatis-plus.entities}")
    private String entities;

    @Value("${mybatis-plus.mapper}")
    private String[] mapperLocations;

    @Autowired
    private DataSource dataSource;


    @MapperScan({"com.xx.archive.business.*.dao", "com.xx.archive.business.*.mapper"})
    @Configuration
    public class MybatisPlusMapperScan {

    }

    @Bean("sqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory() throws Exception {

        MybatisSqlSessionFactoryBean sqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource);
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        try {

            //单个路径配置
            //Resource[] resources = resolver.getResources("classpath*:dao/*.xml");
            sqlSessionFactoryBean.setMapperLocations(getMapperLocations(mapperLocations));
            //配置包的别名,会导致reader entry乱码
            sqlSessionFactoryBean.setTypeAliasesPackage(entities);
        } catch (Exception e) {
            e.printStackTrace();
        }

        //数据库策略
        GlobalConfig globalConfig = new GlobalConfig();
        GlobalConfig.DbConfig dbConfig = new GlobalConfig.DbConfig();
        dbConfig.setIdType(IdType.AUTO);
        globalConfig.setDbConfig(dbConfig);
        sqlSessionFactoryBean.setGlobalConfig(globalConfig);

        //操作日志
        MybatisConfiguration mybatisConfiguration = new MybatisConfiguration();
        mybatisConfiguration.setLogImpl(org.apache.ibatis.logging.stdout.StdOutImpl.class);
        sqlSessionFactoryBean.setConfiguration(mybatisConfiguration);

        //分页拦截器
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        paginationInterceptor.setDialectType("mysql");

        //sql日志 拦截器
        SqlLogInterceptor sqlLogInterceptor = new SqlLogInterceptor();
        sqlLogInterceptor.setWriteInLog(true);
        sqlLogInterceptor.setMaxTime(TIME);

        //加入到sqlSessionFactory
        sqlSessionFactoryBean.setPlugins(new Interceptor[]{
                sqlLogInterceptor,
                paginationInterceptor
        });


        SqlSessionFactory sessionFactory = sqlSessionFactoryBean.getObject();
        return sessionFactory;
    }


    /**
     * @param mapperLocations |多个xml配置的路径
     * @return
     */
    public Resource[] getMapperLocations(String[] mapperLocations) {
        ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
        List<Resource> resources = new ArrayList();
        if (mapperLocations != null) {
            for (String mapperLocation : mapperLocations) {
                try {
                    Resource[] mappers = resourceResolver.getResources(mapperLocation);
                    resources.addAll(Arrays.asList(mappers));
                } catch (IOException e) {

                }
            }
        }
        return resources.toArray(new Resource[resources.size()]);
    }


}

2.3、SqlLogInterceptor


@Intercepts({
        @Signature(type = StatementHandler.class, method = "query", args = {Statement.class, ResultHandler.class}),
        @Signature(type = StatementHandler.class, method = "update", args = {Statement.class}),
        @Signature(type = StatementHandler.class, method = "batch", args = {Statement.class})
})
@Slf4j(topic = "sql")
public class SqlLogInterceptor implements Interceptor {

    private static final String DruidPooledPreparedStatement = "com.alibaba.druid.pool.DruidPooledPreparedStatement";
    private static final String T4CPreparedStatement = "oracle.jdbc.driver.T4CPreparedStatement";
    private static final String OraclePreparedStatementWrapper = "oracle.jdbc.driver.OraclePreparedStatementWrapper";

    /**
     * SQL 执行最大时长,超过自动停止运行,有助于发现问题。
     */
    @Setter
    @Getter
    @Accessors(chain = true)
    private long maxTime = 0;

    /**
     * SQL 是否格式化
     */
    @Setter
    @Getter
    @Accessors(chain = true)
    private boolean format = false;

    /**
     * 是否写入日志文件<br>
     * true 写入日志文件,不阻断程序执行!<br>
     * 超过设定的最大执行时长异常提示!
     */
    @Setter
    @Getter
    @Accessors(chain = true)
    private boolean writeInLog = false;
    private Method oracleGetOriginalSqlMethod;
    private Method druidGetSQLMethod;

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Statement statement;
        Object firstArg = invocation.getArgs()[0];
        if (Proxy.isProxyClass(firstArg.getClass())) {
            statement = (Statement) SystemMetaObject.forObject(firstArg).getValue("h.statement");
        } else {
            statement = (Statement) firstArg;
        }
        MetaObject stmtMetaObj = SystemMetaObject.forObject(statement);
        try {
            statement = (Statement) stmtMetaObj.getValue("stmt.statement");
        } catch (Exception e) {
            // do nothing
        }
        if (stmtMetaObj.hasGetter("delegate")) {
            //Hikari
            try {
                statement = (Statement) stmtMetaObj.getValue("delegate");
            } catch (Exception ignored) {

            }
        }

        String originalSql = null;
        String stmtClassName = statement.getClass().getName();
        if (DruidPooledPreparedStatement.equals(stmtClassName)) {
            try {
                if (druidGetSQLMethod == null) {
                    Class<?> clazz = Class.forName(DruidPooledPreparedStatement);
                    druidGetSQLMethod = clazz.getMethod("getSql");
                }
                Object stmtSql = druidGetSQLMethod.invoke(statement);
                if (stmtSql instanceof String) {
                    originalSql = (String) stmtSql;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else if (T4CPreparedStatement.equals(stmtClassName)
                || OraclePreparedStatementWrapper.equals(stmtClassName)) {
            try {
                if (oracleGetOriginalSqlMethod != null) {
                    Object stmtSql = oracleGetOriginalSqlMethod.invoke(statement);
                    if (stmtSql instanceof String) {
                        originalSql = (String) stmtSql;
                    }
                } else {
                    Class<?> clazz = Class.forName(stmtClassName);
                    oracleGetOriginalSqlMethod = getMethodRegular(clazz, "getOriginalSql");
                    if (oracleGetOriginalSqlMethod != null) {
                        //OraclePreparedStatementWrapper is not a public class, need set this.
                        oracleGetOriginalSqlMethod.setAccessible(true);
                        if (null != oracleGetOriginalSqlMethod) {
                            Object stmtSql = oracleGetOriginalSqlMethod.invoke(statement);
                            if (stmtSql instanceof String) {
                                originalSql = (String) stmtSql;
                            }
                        }
                    }
                }
            } catch (Exception e) {
                //ignore
            }
        }
        if (originalSql == null) {
            originalSql = statement.toString();
        }
        originalSql = originalSql.replaceAll("[\\s]+", StringPool.SPACE);
        int index = indexOfSqlStart(originalSql);
        if (index > 0) {
            originalSql = originalSql.substring(index);
        }

        // 计算执行 SQL 耗时
        long start = SystemClock.now();
        Object result = invocation.proceed();
        long timing = SystemClock.now() - start;

        // 格式化 SQL 打印执行结果
        Object target = PluginUtils.realTarget(invocation.getTarget());
        MetaObject metaObject = SystemMetaObject.forObject(target);
        MappedStatement ms = (MappedStatement) metaObject.getValue("delegate.mappedStatement");
        //格式化sql拼接
//        String sqlFormatStr = SqlUtils.sqlFormat(originalSql, true);
        StringBuilder formatSql = new StringBuilder()
                .append(" Time:").append(timing)
                .append(" ms - ID:")
                .append(ms.getId())
                .append(StringPool.NEWLINE).append("Execute SQL:")
                .append(originalSql)
                .append(StringPool.NEWLINE);

        if (this.isWriteInLog()) {
            if (this.getMaxTime() >= 1 && timing > this.getMaxTime()) {
                //慢sql
                log.error(formatSql.toString());
            } else {
                log.info(formatSql.toString());
            }
        }
        return result;
    }

    @Override
    public Object plugin(Object target) {
        if (target instanceof StatementHandler) {
            return Plugin.wrap(target, this);
        }
        return target;
    }

    @Override
    public void setProperties(Properties prop) {
        String maxTime = prop.getProperty("maxTime");
        String format = prop.getProperty("format");
        if (StringUtils.isNotEmpty(maxTime)) {
            this.maxTime = Long.parseLong(maxTime);
        }
        if (StringUtils.isNotEmpty(format)) {
            this.format = Boolean.valueOf(format);
        }
    }

    /**
     * 获取此方法名的具体 Method
     *
     * @param clazz      class 对象
     * @param methodName 方法名
     * @return 方法
     */
    public Method getMethodRegular(Class<?> clazz, String methodName) {
        if (Object.class.equals(clazz)) {
            return null;
        }
        for (Method method : clazz.getDeclaredMethods()) {
            if (method.getName().equals(methodName)) {
                return method;
            }
        }
        return getMethodRegular(clazz.getSuperclass(), methodName);
    }

    /**
     * 获取sql语句开头部分
     *
     * @param sql
     * @return
     */
    private int indexOfSqlStart(String sql) {
        String upperCaseSql = sql.toUpperCase();
        Set<Integer> set = new HashSet<>();
        set.add(upperCaseSql.indexOf("SELECT "));
        set.add(upperCaseSql.indexOf("UPDATE "));
        set.add(upperCaseSql.indexOf("INSERT "));
        set.add(upperCaseSql.indexOf("DELETE "));
        set.remove(-1);
        if (CollectionUtils.isEmpty(set)) {
            return -1;
        }
        List<Integer> list = new ArrayList<>(set);
        list.sort(Comparator.naturalOrder());
        return list.get(0);
    }
}

2.4、TransactionalConfig



/**
 * @author yuguang
 * @date 2019/12/11 10:56
 * @desc
 */
@Setter
@Getter
@Configuration
@ConditionalOnExpression("${mybatis-plus.transaction.definition:true}")
@EnableTransactionManagement
public class TransactionalConfig {

    private static final String CUSTOMIZE_TRANSACTION_INTERCEPTOR_NAME = "customizeTransactionInterceptor";
    /**
     * 默认只对 "*Service" , "*ServiceImpl" Bean 进行事务处理,"*"表示模糊匹配, 比如 : userService,orderServiceImpl
     */
    private static final String[] DEFAULT_TRANSACTION_BEAN_NAMES = {"*Service", "*ServiceImpl"};
    /**
     * 可传播事务配置
     */
    private static final String[] DEFAULT_REQUIRED_METHOD_RULE_TRANSACTION_ATTRIBUTES = {
            "add*",
            "save*",
            "insert*",
            "delete*",
            "update*",
            "edit*",
            "batch*",
            "create*",
            "remove*",
    };
    /**
     * 默认的只读事务
     */
    private static final String[] DEFAULT_READ_ONLY_METHOD_RULE_TRANSACTION_ATTRIBUTES = {
            "get*",
            "count*",
            "find*",
            "query*",
            "select*",
            "list*",
            "*",
    };
    /**
     * 自定义事务 BeanName 拦截
     */
    private String[] customizeTransactionBeanNames = {};
    /**
     * 自定义方法名的事务属性相关联,可以使用通配符(*)字符关联相同的事务属性的设置方法; 只读事务
     */
    private String[] customizeReadOnlyMethodRuleTransactionAttributes = {};
    /**
     * 自定义方法名的事务属性相关联,可以使用通配符(*)字符关联相同的事务属性的设置方法;
     * 传播事务(默认的){@link org.springframework.transaction.annotation.Propagation#REQUIRED}
     */
    private String[] customizeRequiredMethodRuleTransactionAttributes = {};


    /**
     * 配置事务拦截器
     *
     * @param transactionManager : 事务管理器
     */
    @Bean(CUSTOMIZE_TRANSACTION_INTERCEPTOR_NAME)
    public TransactionInterceptor customizeTransactionInterceptor(PlatformTransactionManager transactionManager) {
        NameMatchTransactionAttributeSource transactionAttributeSource = new NameMatchTransactionAttributeSource();
        RuleBasedTransactionAttribute readOnly = this.readOnlyTransactionRule();
        RuleBasedTransactionAttribute required = this.requiredTransactionRule();
        // 默认的只读事务配置
        for (String methodName : DEFAULT_READ_ONLY_METHOD_RULE_TRANSACTION_ATTRIBUTES) {
            transactionAttributeSource.addTransactionalMethod(methodName, readOnly);
        }
        // 默认的传播事务配置
        for (String methodName : DEFAULT_REQUIRED_METHOD_RULE_TRANSACTION_ATTRIBUTES) {
            transactionAttributeSource.addTransactionalMethod(methodName, required);
        }
        // 定制的只读事务配置
        for (String methodName : customizeReadOnlyMethodRuleTransactionAttributes) {
            transactionAttributeSource.addTransactionalMethod(methodName, readOnly);
        }
        // 定制的传播事务配置
        for (String methodName : customizeRequiredMethodRuleTransactionAttributes) {
            transactionAttributeSource.addTransactionalMethod(methodName, required);
        }
        return new TransactionInterceptor(transactionManager, transactionAttributeSource);
    }

    /**
     * 配置事务拦截
     * <p>
     * {@link #customizeTransactionInterceptor(PlatformTransactionManager)}
     */
    @Bean
    public BeanNameAutoProxyCreator customizeTransactionBeanNameAutoProxyCreator() {
        BeanNameAutoProxyCreator beanNameAutoProxyCreator = new BeanNameAutoProxyCreator();
        // 设置定制的事务拦截器
        beanNameAutoProxyCreator.setInterceptorNames(CUSTOMIZE_TRANSACTION_INTERCEPTOR_NAME);
        List<String> transactionBeanNames = new ArrayList<>(DEFAULT_TRANSACTION_BEAN_NAMES.length + customizeTransactionBeanNames.length);
        // 默认
        transactionBeanNames.addAll(Arrays.asList(DEFAULT_TRANSACTION_BEAN_NAMES));
        // 定制
        transactionBeanNames.addAll(Arrays.asList(customizeTransactionBeanNames));
        // 归集
        for (String transactionBeanName : transactionBeanNames) {
            beanNameAutoProxyCreator.setBeanNames(transactionBeanName);
        }
        beanNameAutoProxyCreator.setProxyTargetClass(true);
        return beanNameAutoProxyCreator;
    }

    /**
     * 支持当前事务;如果不存在创建一个新的
     * {@link org.springframework.transaction.annotation.Propagation#REQUIRED}
     */
    private RuleBasedTransactionAttribute requiredTransactionRule() {
        RuleBasedTransactionAttribute required = new RuleBasedTransactionAttribute();
        required.setRollbackRules(Collections.singletonList(new RollbackRuleAttribute(Exception.class)));
        required.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        required.setTimeout(TransactionDefinition.TIMEOUT_DEFAULT);
        return required;
    }

    /**
     * 只读事务
     * {@link org.springframework.transaction.annotation.Propagation#NOT_SUPPORTED}
     */
    private RuleBasedTransactionAttribute readOnlyTransactionRule() {
        RuleBasedTransactionAttribute readOnly = new RuleBasedTransactionAttribute();
        readOnly.setReadOnly(true);
        readOnly.setPropagationBehavior(TransactionDefinition.PROPAGATION_NOT_SUPPORTED);
        return readOnly;
    }
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值