cn.eova.common.jdbc.DruidDataSource Maven / Gradle / Ivy
The newest version!
/*
* Copyright (c) 2023 EOVA.CN. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.eova.common.jdbc;
import java.sql.SQLException;
import java.util.HashMap;
import cn.eova.tools.string.AESUtil;
import cn.eova.tools.x;
import com.alibaba.druid.filter.logging.Log4jFilter;
import com.alibaba.druid.filter.stat.StatFilter;
import com.alibaba.druid.util.JdbcUtils;
import com.alibaba.druid.wall.WallConfig;
import com.alibaba.druid.wall.WallFilter;
import com.jfinal.config.Plugins;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.activerecord.CaseInsensitiveContainerFactory;
import com.jfinal.plugin.activerecord.IDataSourceProvider;
import com.jfinal.plugin.activerecord.dialect.MysqlDialect;
import com.jfinal.plugin.druid.DruidPlugin;
/**
* Druid 数据源
* @author Jieven
*/
public class DruidDataSource {
/**
* 注册数据源(支持多数据源)
*
* @author Jieven
*/
public static HashMap create(Plugins plugins) {
HashMap dps = create();
HashMap arps = new HashMap<>();
dps.forEach((dp, arp) -> {
plugins.add(dp).add(arp);
arps.put(arp.getConfig().getName(), arp);
});
return arps;
}
/**
* 创建数据源(支持多数据源)
*
* @author Jieven
*/
public static HashMap create() {
HashMap arps = new HashMap<>();
// 多数据源支持
String datasource = x.conf.get("db.datasource");
if (x.isEmpty(datasource)) {
throw new RuntimeException("数据源配置项不存在,请检查配置jdbc.config 配置项[db.datasource]");
}
for (String ds : datasource.split(",")) {
ds = ds.trim();
String url = x.conf.get(ds + ".url");
String user = x.conf.get(ds + ".user");
String pwd = x.conf.get(ds + ".pwd");
if (x.isEmpty(url)) {
throw new RuntimeException(String.format("数据源[%s]配置异常,请检查请检查配置jdbc.config", ds));
}
// JDBC密码加密
if (x.conf.getBool("db.pwd.encrypt", false)) {
pwd = AESUtil.decrypt(pwd);
}
DruidPlugin dp = DruidDataSource.initDruidPlugin(url, user, pwd);
ActiveRecordPlugin arp = DruidDataSource.initActiveRecordPlugin(url, ds, dp);
x.log.info("create ds[{}] {} > {}", ds, user, url);
arps.put(dp, arp);
}
return arps;
}
/**
* init Druid
*
* @param url JDBC
* @param username 数据库用户
* @param password 数据库密码
* @return
*/
public static DruidPlugin initDruidPlugin(String url, String username, String password) {
// 设置方言
WallFilter wall = new WallFilter();
String dbType = null;
try {
dbType = JdbcUtils.getDbType(url, JdbcUtils.getDriverClassName(url));
} catch (SQLException e) {
throw new RuntimeException(e);
}
wall.setDbType(dbType);
DruidPlugin dp = new DruidPlugin(url, username, password);
dp.addFilter(new StatFilter());
dp.setInitialSize(x.conf.getInt("db.conn.init", 1));// 初始化1个
dp.setMinIdle(x.conf.getInt("db.conn.min", 2));// 最少空闲2个
dp.setMaxActive(x.conf.getInt("db.conn.max", 64));// 连接上限
dp.setMaxWait(x.conf.getInt("db.conn.timeout", 60000));// 配置获取连接等待超时的时间 60s(时间太短会导致高并发连接耗尽异常)
// 开发者模式 降低SQL安全策略, 保证应用商店安装卸载需要开发者模式.
boolean devMode = x.conf.getBool("devMode", false);
if (devMode) {
// https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE-wallfilter
WallConfig config = new WallConfig();
config.setMultiStatementAllow(true);// 一次执行多条语句
config.setNoneBaseStatementAllow(false);// 非基本DDL语句
wall.setConfig(config);
wall.setThrowException(false);// SQL注入抛出SQLException
wall.setLogViolation(true);/// SQL注入输出日志
// 配置log插件
Log4jFilter logFilter = new Log4jFilter();
logFilter.setStatementLogEnabled(false);
logFilter.setStatementLogErrorEnabled(true);
logFilter.setStatementExecutableSqlLogEnable(true);
dp.addFilter(logFilter);
}
dp.addFilter(wall);
return dp;
}
/**
* init ActiveRecord
*
* @param url JDBC
* @param ds DataSource
* @param dp Druid
* @return
*/
public static ActiveRecordPlugin initActiveRecordPlugin(String url, String ds, IDataSourceProvider dp) {
// 提升事务级别保证事务回滚 MYSQL TRANSACTION_REPEATABLE_READ=4
int lv = x.conf.getInt("db.transaction_level", 4);
// DB默认命名规则
boolean isLowerCase = x.conf.getBool("db.islowercase", true);
// 是否输出SQL日志
boolean isShowSql = x.conf.getBool("db.showsql", true);
ActiveRecordPlugin arp = new ActiveRecordPlugin(ds, dp);
// 构建方言
arp.setDialect(new MysqlDialect());
arp.setShowSql(isShowSql);
arp.setTransactionLevel(lv);
// 忽略大小写敏感字段无序
arp.setContainerFactory(new CaseInsensitiveContainerFactory(isLowerCase));
// 大小写敏感 保持字段顺序()
// arp.setContainerFactory(new EovaContainerFactory(isLowerCase));
return arp;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy