MybatisPlusConfig.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. package com.xjrsoft.config;
  2. import cn.hutool.core.convert.Convert;
  3. import cn.hutool.core.map.MapUtil;
  4. import cn.hutool.core.util.StrUtil;
  5. import cn.hutool.db.GlobalDbConfig;
  6. import com.baomidou.dynamic.datasource.provider.AbstractJdbcDataSourceProvider;
  7. import com.baomidou.dynamic.datasource.provider.DynamicDataSourceProvider;
  8. import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty;
  9. import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties;
  10. import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.druid.DruidConfig;
  11. import com.baomidou.mybatisplus.autoconfigure.ConfigurationCustomizer;
  12. import com.baomidou.mybatisplus.core.MybatisConfiguration;
  13. import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler;
  14. import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
  15. import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor;
  16. import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
  17. import com.xjrsoft.common.constant.GlobalConstant;
  18. import com.xjrsoft.common.handler.MyLocalDateTimeTypeHandler;
  19. import com.xjrsoft.common.handler.XjrLocalTimeTypeHandler;
  20. import com.xjrsoft.common.interceptor.DataScopeInnerInterceptor;
  21. import com.xjrsoft.common.utils.DatasourceUtil;
  22. import lombok.extern.slf4j.Slf4j;
  23. import org.apache.ibatis.type.BooleanTypeHandler;
  24. import org.apache.ibatis.type.EnumTypeHandler;
  25. import org.apache.ibatis.type.JdbcType;
  26. import org.springframework.beans.factory.annotation.Autowired;
  27. import org.springframework.context.annotation.Bean;
  28. import org.springframework.context.annotation.Configuration;
  29. import org.ssssssss.magicapi.datasource.model.MagicDynamicDataSource;
  30. import javax.sql.DataSource;
  31. import java.sql.ResultSet;
  32. import java.sql.SQLException;
  33. import java.sql.Statement;
  34. import java.time.LocalDateTime;
  35. import java.time.LocalTime;
  36. import java.util.HashMap;
  37. import java.util.Map;
  38. import java.util.Properties;
  39. /**
  40. * mybatis-plus配置
  41. *
  42. * @author tzx
  43. */
  44. @Slf4j
  45. @Configuration
  46. public class MybatisPlusConfig {
  47. @Autowired
  48. private DynamicDataSourceProperties dynamicDataSourceProperties;
  49. private final Map<String, String> datasourceMap = new HashMap<>();
  50. /**
  51. * 分页插件
  52. */
  53. @Bean
  54. public MybatisPlusInterceptor paginationInterceptor() {
  55. MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
  56. interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
  57. return interceptor;
  58. }
  59. /**
  60. * 数据权限插件
  61. */
  62. @Bean
  63. public MybatisPlusInterceptor dataScopeInnerInterceptor() {
  64. MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
  65. interceptor.addInnerInterceptor(new DataScopeInnerInterceptor());
  66. return interceptor;
  67. }
  68. /**
  69. * 防止全表更新与删除
  70. */
  71. @Bean
  72. public MybatisPlusInterceptor blockAttackInnerInterceptor() {
  73. MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
  74. interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
  75. return interceptor;
  76. }
  77. @Bean
  78. public DynamicDataSourceProvider dynamicDataSourceProvider() {
  79. GlobalDbConfig.setCaseInsensitive(false); // 自定义表单hutool包配置,查询表单发布的菜单数据,设置返回的字段名大小写敏感
  80. DataSourceProperty datasource = dynamicDataSourceProperties.getDatasource().get(GlobalConstant.DEFAULT_DATASOURCE_KEY);
  81. return new AbstractJdbcDataSourceProvider(datasource.getDriverClassName(), datasource.getUrl(), datasource.getUsername(), datasource.getPassword()) {
  82. @Override
  83. protected Map<String, DataSourceProperty> executeStmt(Statement statement) throws SQLException {
  84. Map<String, DataSourceProperty> map = new HashMap<>(16);
  85. // 数据库里的所有库
  86. ResultSet rs = statement.executeQuery("SELECT * FROM xjr_databaselink WHERE delete_mark = 0 AND enabled_mark = 1");
  87. while (rs.next()) {
  88. long id = rs.getLong("id");
  89. String host = rs.getString("host");
  90. String username = rs.getString("username");
  91. String password = rs.getString("password");
  92. String driver = rs.getString("driver");
  93. String dbType = rs.getString("db_type");
  94. //缓存起来
  95. datasourceMap.put(Convert.toStr(id), rs.getString("db_name"));
  96. DataSourceProperty property = new DataSourceProperty();
  97. property.setUsername(username);
  98. property.setPassword(password);
  99. property.setUrl(host);
  100. property.setDriverClassName(driver);
  101. // 测试连接,如果连接不上则跳过,避免启动失败
  102. if (!DatasourceUtil.testConnection(host, username, password)) {
  103. continue;
  104. }
  105. DruidConfig druidConfig = property.getDruid();
  106. druidConfig.setInitialSize(10); // 初始化大小
  107. druidConfig.setMaxActive(100);// 最大连接池
  108. druidConfig.setMinIdle(10);// 最小连接池
  109. druidConfig.setMaxWait(60000); //最大等待超时时间
  110. druidConfig.setPoolPreparedStatements(false); // 是否缓存preparedStatement,也就是PSCache 官方建议MySQL下建议关闭 个人建议如果想用SQL防火墙 建议打开
  111. druidConfig.setMaxPoolPreparedStatementPerConnectionSize(20);//是否缓存preparedStatement,也就是PSCache 官方建议MySQL下建议关闭 个人建议如果想用SQL防火墙 建议打开
  112. druidConfig.setTimeBetweenEvictionRunsMillis(60000L);// 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
  113. druidConfig.setMinEvictableIdleTimeMillis(300000L); // 配置一个连接在池中最小生存的时间,单位是毫秒
  114. if (StrUtil.equals(dbType, "oracle")) {
  115. druidConfig.setValidationQuery("SELECT 1 FROM DUAL");
  116. } else {
  117. druidConfig.setValidationQuery("SELECT 1 "); //测试链接 语句
  118. }
  119. druidConfig.setTestWhileIdle(true);
  120. druidConfig.setTestOnReturn(false);
  121. druidConfig.setTestOnBorrow(true);
  122. druidConfig.setFilters("stat,slf4j"); // # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
  123. druidConfig.setUseGlobalDataSourceStat(true);
  124. Properties properties = new Properties();
  125. properties.put("druid.stat.mergeSql", true); //打开mergeSql功能
  126. properties.put("druid.stat.slowSqlMillis", true); // 打开慢sql 记录功能
  127. druidConfig.setConnectionProperties(properties);
  128. map.put(Long.toString(id), property);
  129. }
  130. // yml配置的数据源
  131. Map<String, DataSourceProperty> datasourceMap = dynamicDataSourceProperties.getDatasource();
  132. for (DataSourceProperty dataSourceProperty : datasourceMap.values()) {
  133. // 测试连接,如果连接不上则跳过,避免启动失败
  134. if (!DatasourceUtil.testConnection(dataSourceProperty.getUrl(), dataSourceProperty.getUsername(), dataSourceProperty.getPassword())) {
  135. continue;
  136. }
  137. DruidConfig druidConfig = dataSourceProperty.getDruid();
  138. druidConfig.setInitialSize(10); // 初始化大小
  139. druidConfig.setMaxActive(100);// 最大连接池
  140. druidConfig.setMinIdle(10);// 最小连接池
  141. druidConfig.setMaxWait(60000); //最大等待超时时间
  142. druidConfig.setValidationQueryTimeout(10);//是检测连接是否有效的超时时间,单位:秒
  143. druidConfig.setPoolPreparedStatements(false); // 是否缓存preparedStatement,也就是PSCache 官方建议MySQL下建议关闭 个人建议如果想用SQL防火墙 建议打开
  144. druidConfig.setMaxPoolPreparedStatementPerConnectionSize(20);//是否缓存preparedStatement,也就是PSCache 官方建议MySQL下建议关闭 个人建议如果想用SQL防火墙 建议打开
  145. druidConfig.setTimeBetweenEvictionRunsMillis(2000L);// 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
  146. druidConfig.setMinEvictableIdleTimeMillis(300000L); // 配置一个连接在池中最小生存的时间,单位是毫秒
  147. if (dataSourceProperty.getUrl().contains("oracle")) {
  148. druidConfig.setValidationQuery("SELECT 1 FROM DUAL"); //测试链接 如果是oracle 语句不一样
  149. } else {
  150. druidConfig.setValidationQuery("SELECT 1 "); //测试链接 语句
  151. }
  152. druidConfig.setTestWhileIdle(true);
  153. druidConfig.setTestOnReturn(false);
  154. druidConfig.setTestOnBorrow(false);
  155. druidConfig.setFilters("stat,slf4j"); // # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
  156. druidConfig.setUseGlobalDataSourceStat(true);
  157. Properties properties = new Properties();
  158. properties.put("druid.stat.mergeSql", true); //打开mergeSql功能
  159. properties.put("druid.stat.slowSqlMillis", true); // 打开慢sql 记录功能
  160. druidConfig.setConnectionProperties(properties);
  161. }
  162. map.putAll(datasourceMap);
  163. rs.close();
  164. return map;
  165. }
  166. };
  167. }
  168. /**
  169. * 配置MagicApi多数据源
  170. *
  171. * @return
  172. */
  173. @Bean
  174. public MagicDynamicDataSource magicDynamicDataSource() {
  175. MagicDynamicDataSource dynamicDataSource = new MagicDynamicDataSource();
  176. Map<String, DataSource> dataSources = dynamicDataSourceProvider().loadDataSources();
  177. for (String ds : dataSources.keySet()) {
  178. if (StrUtil.equals(GlobalConstant.DEFAULT_DATASOURCE_KEY, ds)) {
  179. dynamicDataSource.setDefault(dataSources.get(ds));
  180. } else {
  181. //缓存起来的name
  182. if (datasourceMap.containsKey(ds)) {
  183. String name = MapUtil.getStr(datasourceMap, ds);
  184. dynamicDataSource.add(name, dataSources.get(ds));
  185. }
  186. //配置在yml上的 可能获取不到name
  187. else {
  188. dynamicDataSource.add("datasource_" + ds, dataSources.get(ds));
  189. }
  190. }
  191. }
  192. return dynamicDataSource;
  193. }
  194. /**
  195. * MybatisPlus数据库类型处理
  196. * @return
  197. */
  198. @Bean
  199. public ConfigurationCustomizer getConfig(){
  200. return new ConfigurationCustomizer() {
  201. @Override
  202. public void customize(MybatisConfiguration configuration) {
  203. configuration.setMapUnderscoreToCamelCase(true);
  204. configuration.setJdbcTypeForNull(JdbcType.NULL);
  205. configuration.getTypeAliasRegistry().registerAlias("EnumTypeHandler", EnumTypeHandler.class);
  206. configuration.getTypeAliasRegistry().registerAlias("BooleanTypeHandler", BooleanTypeHandler.class);
  207. configuration.getTypeAliasRegistry().registerAlias("AbstractJsonTypeHandler", AbstractJsonTypeHandler.class);
  208. configuration.getTypeHandlerRegistry().register(LocalDateTime.class, MyLocalDateTimeTypeHandler.class);
  209. configuration.getTypeHandlerRegistry().register(LocalTime.class, XjrLocalTimeTypeHandler.class);
  210. }
  211. };
  212. }
  213. }