| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301 |
- package jnpf.database.util;
- import cn.hutool.core.util.ReflectUtil;
- import com.alibaba.druid.pool.DruidDataSource;
- import com.alibaba.druid.proxy.jdbc.ConnectionProxy;
- import jnpf.database.model.dto.PrepSqlDTO;
- import jnpf.database.model.entity.DbLinkEntity;
- import jnpf.database.model.interfaces.DbSourceOrDbLink;
- import jnpf.database.source.DbBase;
- import jnpf.database.source.impl.DbOracle;
- import jnpf.exception.DataException;
- import jnpf.util.StringUtil;
- import jnpf.util.TenantHolder;
- import lombok.extern.slf4j.Slf4j;
- import java.sql.Connection;
- import java.sql.DriverManager;
- import java.sql.SQLException;
- import java.util.Objects;
- import java.util.Properties;
- /**
- * Connection数据连接相关工具类
- *
- * @author JNPF开发平台组
- * @version V3.2.0
- * @copyright 引迈信息技术有限公司
- * @date 2021/10/6
- */
- @Slf4j
- public class ConnUtil {
- public static Connection getConnOrDefault(DbSourceOrDbLink dbSourceOrDbLink) throws DataException {
- if(dbSourceOrDbLink == null){
- dbSourceOrDbLink = DynamicDataSourceUtil.getDataSourceUtil();
- }
- return PrepSqlDTO.getConn(dbSourceOrDbLink.init());
- }
- public static Connection getConn(DbSourceOrDbLink dbSourceOrDbLink) throws DataException {
- return PrepSqlDTO.getConn(dbSourceOrDbLink.init());
- }
- public static Connection getConn(DbSourceOrDbLink dbSourceOrDbLink, String dbName) throws DataException {
- return PrepSqlDTO.getConn(dbSourceOrDbLink.init(dbName));
- }
- public static Connection getConn(String userName, String password, String url) throws DataException {
- DbLinkEntity dbLinkEntity = new DbLinkEntity();
- dbLinkEntity.setUserName(userName);
- dbLinkEntity.setPassword(password);
- dbLinkEntity.setUrl(url);
- dbLinkEntity.setDbType(DbTypeUtil.getDb(url).getJnpfDbEncode());
- return PrepSqlDTO.getConn(dbLinkEntity);
- }
- /**
- * 连接Connection
- */
- @Deprecated
- private static Connection getConnection(DbSourceOrDbLink dbSourceOrDbLink) throws DataException {
- return getConnection(dbSourceOrDbLink, null);
- }
- /**
- * 指定库名(多租户)
- */
- @Deprecated
- private static Connection getConnection(DbSourceOrDbLink dataSourceUtil, String dbName) throws DataException {
- DbLinkEntity dbLinkEntity = dataSourceUtil.init();
- // Oracle特殊连接
- if(DbTypeUtil.checkOracle(dbLinkEntity)){ return getOracleConn(dbLinkEntity); }
- return getConnection(dbLinkEntity.getAutoUsername(), dbLinkEntity.getAutoPassword(), getUrl(dbLinkEntity));
- }
- /**
- * 基础连接方式
- */
- @Deprecated
- private static Connection getConnection(String userName, String password, String url) throws DataException {
- DbBase db = DbTypeUtil.getDb(url);
- return ConnCommon.createConn(db.getDriver(), userName, password, url);
- }
- /* ==================================================== */
- /**
- * oracle特殊连接方式
- */
- private static Connection getOracleConn(DbLinkEntity dsd) throws DataException {
- DbOracle dbOracle = new DbOracle();
- return dbOracle.getOracleConn(dsd, getUrl(dsd));
- }
- /*==============获取数据连接URL==============*/
- public static String getUrl(DbSourceOrDbLink dbSourceOrDbLink) {
- return getUrl(dbSourceOrDbLink, null);
- }
- /**
- * 指定库名(多租户)
- *
- * @param dbSourceOrDbLink 数据源
- * @param dbName 数据库名
- * @return url连接
- */
- public static String getUrl(DbSourceOrDbLink dbSourceOrDbLink, String dbName) {
- return DbBase.BaseCommon.getDbBaseConnUrl(dbSourceOrDbLink, dbName);
- }
- public static void switchConnectionSchema(Connection conn) throws SQLException {
- if(TenantDataSourceUtil.isMultiTenancy() && DynamicDataSourceUtil.isPrimaryDataSoure() && TenantHolder.getLocalTenantCache() != null) {
- String schema = TenantDataSourceUtil.getTenantDbName();
- if (StringUtil.isNotEmpty(schema)) {
- Connection tmpConnection = getRealConnection(conn);
- //多租户模式, Schema模式下降连接切换至租户库
- //判断数据库类型
- try {
- switch (DynamicDataSourceUtil.getPrimaryDbType()) {
- case DbBase.SQL_SERVER:
- case DbBase.MYSQL:
- if(!Objects.equals(tmpConnection.getCatalog(), schema)) {
- tmpConnection.setCatalog(schema);
- }
- break;
- case DbBase.POSTGRE_SQL:
- //POSTGRE转小写
- schema = schema.toLowerCase();
- if(!Objects.equals(tmpConnection.getSchema(), schema)) {
- tmpConnection.setSchema(schema);
- }
- break;
- case DbBase.ORACLE:
- //Oracle转大写
- schema = schema.toUpperCase();
- if(!Objects.equals(tmpConnection.getSchema(), schema)) {
- tmpConnection.setSchema(schema);
- }
- break;
- case DbBase.KINGBASE_ES:
- case DbBase.DM:
- default:
- if(!Objects.equals(tmpConnection.getSchema(), schema)) {
- tmpConnection.setSchema(schema);
- }
- }
- }catch (Exception e){
- //切库失败 连接不可用 需要先手动关闭链接
- conn.close();
- String url = "";
- if(tmpConnection instanceof ConnectionProxy){
- try {
- url = ((ConnectionProxy) tmpConnection).getDirectDataSource().getUrl();
- }catch (Exception ee){}
- }
- log.error("切库失败, 租户:{}, URL: {}, Msg: {}", TenantHolder.getDatasourceId(), url, e.getMessage());
- throw e;
- }
- }
- }
- }
- public static String getConnectionDbName(Connection conn) throws SQLException {
- Connection tmpConnection = getRealConnection(conn);
- String dbName;
- String dbCode = DbTypeUtil.getDb(tmpConnection.getMetaData().getURL()).getJnpfDbEncode();
- //多租户模式, Schema模式下降连接切换至租户库
- //判断数据库类型
- switch (dbCode) {
- case DbBase.ORACLE://DBName:Schema
- case DbBase.DM://DBName:Schema
- dbName = tmpConnection.getSchema();
- break;
- case DbBase.SQL_SERVER://DBName:CataLog
- case DbBase.MYSQL://DBName:CataLog
- case DbBase.POSTGRE_SQL://DBName:CataLog, Schema:Schema
- case DbBase.KINGBASE_ES://DBName:CataLog, Schema:Schema
- default:
- dbName = tmpConnection.getCatalog();
- }
- return dbName;
- }
- public static String getConnectionSchema(Connection conn) throws SQLException {
- Connection tmpConnection = getRealConnection(conn);
- String dbName;
- String dbCode = DbTypeUtil.getDb(tmpConnection.getMetaData().getURL()).getJnpfDbEncode();
- //多租户模式, Schema模式下降连接切换至租户库
- //判断数据库类型
- switch (dbCode) {
- case DbBase.ORACLE://DBName:Schema
- case DbBase.DM://DBName:Schema
- case DbBase.POSTGRE_SQL://DBName:CataLog, Schema:Schema
- case DbBase.KINGBASE_ES://DBName:CataLog, Schema:Schema
- case DbBase.SQL_SERVER://DBName:CataLog
- dbName = tmpConnection.getSchema();
- break;
- case DbBase.MYSQL://DBName:CataLog
- default:
- dbName = tmpConnection.getCatalog();
- }
- return dbName;
- }
- /**
- * 获取包装连接中的数据连接
- * @param connection
- * @return
- */
- public static Connection getRealConnection(Connection connection){
- Connection tmpConnection = connection;
- //Druid连接包装只允许Mysql切换Schema
- for (int i = 0; i < 6; i++) {
- //最大6次避免有不知名的数据源自己获取自己无限循环
- try{
- tmpConnection = ReflectUtil.invoke(tmpConnection, "getConnection");
- }catch (Exception e){
- break;
- }
- }
- return tmpConnection;
- }
- /**
- * 获取DruidDataSource
- */
- public static DruidDataSource getDruidDataSource(DataSourceUtil dataSourceUtil) throws DataException {
- DruidDataSource druidDataSource = new DruidDataSource();
- druidDataSource.setUsername(dataSourceUtil.getUserName());
- druidDataSource.setPassword(dataSourceUtil.getPassword());
- //jdbc-url
- druidDataSource.setUrl(ConnUtil.getUrl(dataSourceUtil));
- //数据库驱动
- druidDataSource.setDriverClassName(DbTypeUtil.getDb(dataSourceUtil).getDriver());
- return druidDataSource;
- }
- /**
- * 以下为ConnUtil上面非显性的公开方法
- * 让调用者只关注getConn方法而不造成干扰
- */
- public static class ConnCommon {
- /**
- * (基础)获取数据连接
- *
- * @param driver 驱动
- * @param userName 用户
- * @param password 密码
- * @param url url
- * @return 数据库连接
- * @throws DataException ignore
- */
- public static Connection createConn(String driver, String userName, String password, String url) throws DataException {
- try {
- Class.forName(driver);
- return DriverManager.getConnection(url, userName, password);
- } catch (Exception e) {
- e.printStackTrace();
- throw DataException.errorLink(e.getMessage());
- }
- }
- public static Connection createConnByProp(String driver, String userName, String password, String url, Properties conProps) throws DataException {
- try {
- conProps.put("user", userName);
- conProps.put("password", password);
- Class.forName(driver);
- return DriverManager.getConnection(url, conProps);
- } catch (Exception e) {
- throw new DataException(e.getMessage());
- }
- }
- /**
- * 开启数据库获取表注解连接
- *
- * @param dbSourceOrDbLink 数据源对象
- * @return ignore
- */
- public static Connection getConnRemarks(DataSourceUtil dbSourceOrDbLink) throws DataException {
- Properties props = new Properties();
- //设置可以获取remarks信息
- props.setProperty("remarks", "true");
- props.setProperty("remarksReporting", "true");
- //设置可以获取tables remarks信息
- props.setProperty("useInformationSchema", "true");
- return createConnByProp(DbTypeUtil.getDb(getUrl(dbSourceOrDbLink)).getDriver(), dbSourceOrDbLink.getUserName(), dbSourceOrDbLink.getPassword(),
- getUrl(dbSourceOrDbLink), props);
- }
- }
- }
|