栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 前沿技术 > 大数据 > 大数据系统

Springboot+达梦数据库

Springboot+达梦数据库

在项目中遇到需要切换成国产化达梦数据库(DM8),在切换过程中遇到较多的问题,记录一下。

1、首先在在pom文件中引入DM8依赖:


	com.dameng
	Dm8JdbcDriver18
	8.1.1.49

 2、在application.yml文件中引入DM8驱动:

spring:
  datasource:
    driver-class-name: dm.jdbc.driver.DmDriver

3、数据库连接配置(自动加载配置文件中数据库的连接信息,数据库连接信息随着环境的不同,可灵活加载):

@Configuration
@Slf4j
public class MybatisConfig {

    @Autowired
    private DataSourceProperties dataSourceProperties;

    
    private ComponentConfig componentConfig = ApplicationContextExt.getComponentConfig();

    @Bean(name = "dataSource")
    public DruidDataSource DMDataSource() {
        //配置数据源
        DruidDataSource dataSource = new DruidDataSource();
        String driverClassName = dataSourceProperties.getDriverClassName();
        dataSource.setDriverClassName(driverClassName);
        // 获取数据库配置
        SegmentConfig dbConfig = componentConfig.getSegmentSelf(componentConfig.getDbId());
        String dbIP = dbConfig.getProperty("db.ip");
        String dbPort = dbConfig.getProperty("db.port");
        String dbName = dbConfig.getProperty("db.name");
        String dbUserName = dbConfig.getProperty("db.username");
        String dbPassword = dbConfig.getProperty("db.password");
        String url = "jdbc:dm://" + dbIP + ":" + dbPort + "/" + dbName + "?useUnicode=true&characterEncoding=utf-8";
        dataSource.setUrl(url);
        dataSource.setUsername(dbUserName);
        dataSource.setPassword(dbPassword);
        return dataSource;
    }

    public SqlSessionFactory sqlSessionFactory() throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(DMDataSource());
        return sqlSessionFactoryBean.getObject();
    }
}

之后的mapper以及数据库语句这里不再描述。

【问题1】:Caused by: dm.jdbc.driver.DMException: 第1行附件出现错误:系统处于MOUNT状态

该问题可能有两种原因,一种是网上经常写的,DM数据库有三种形态(MOUNT、OPEN、SUSPEND),当其处于MOUNT状态时,不允许访问数据库对象,只能进行控制文件维护、归档配置、数据库模式修改等操作。需要将其转为OPEN状态,命令行方式执行如下语句:

alter database open;

请参考:达梦数据库:系统处于MOUNT状态_祢真伟大的博客-CSDN博客_系统处于mount状态

还有一种原因是因为数据库连接上去了,但是没有连接上正确的数据库名称,比如,我之前按照网上配置数据库连接信息,如下:

spring:
  datasource:
    driver-class-name: dm.jdbc.driver.DmDriver
    url: jdbc:dm://localhost:12345/TEST?useUnicode=true&characterEncoding=utf-8
    username: SYSDBA
    password: SYSDBA

并未自动加载正确的数据库名称。导致在环境中运行时报错。如果大家使用的不是自动加载数据库连接信息的方式,而是直接在yml文件中写死的,那么可以参考如下:

spring:
  datasource:
    driver-class-name: dm.jdbc.driver.DmDriver
    url: jdbc:dm://#{数据库ip地址}:#{数据库端口}/#{数据库名称}?useUnicode=true&characterEncoding=utf-8
    username: #{数据库用户名}
    password: #{数据库连接密码}

#{} 为替换符,大家可以根据实际的数值替换。

【问题2】:testWhileIdle is true, validationQuery not set

这个是因为没有对数据源进行初始化参数配置,如果大家的数据库连接信息是直接在yml文件中写死的,那可以直接在yml中配置数据库的初始化参数。由于我采用的是自动从配置文件中加载的,则写法如下:

private DruidDataSource halfInitDataSource() {
    try {
        DruidDataSource dataSource = new DruidDataSource();
        // 可选配置---------------------------------------------------------------------------------------
        // 配置初始化大小、最小、最大
        String initSizeStr = componentConfig.getProperty("datasource.initial-size");
        int initSize = 5;
        if (StringUtils.isNotBlank(initSizeStr) && NumberUtils.isDigits(initSizeStr.trim())) {
            initSize = NumberUtils.toInt(initSizeStr.trim());
        }
        dataSource.setInitialSize(initSize);

        // 配置最小闲置时间
        String miniIdleStr = componentConfig.getProperty("datasource.min-idle");
        int minIdle = 5;
        if (StringUtils.isNotBlank(miniIdleStr) && NumberUtils.isDigits(miniIdleStr.trim())) {
            minIdle = NumberUtils.toInt(miniIdleStr.trim());
        }
        dataSource.setMinIdle(minIdle);

        // 最大连接数
        String maxConnStr = componentConfig.getProperty("datasource.max-active");
        int maxConn = 20;
        if (StringUtils.isNotBlank(maxConnStr) && NumberUtils.isDigits(maxConnStr.trim())) {
            maxConn = NumberUtils.toInt(maxConnStr.trim());
        }
        dataSource.setMaxActive(maxConn);

        // 配置获取连接等待超时的时间
        String maxWaitStr = componentConfig.getProperty("datasource.max-wait");
        int maxWait = 10 * 1000;
        if (StringUtils.isNotBlank(maxWaitStr) && NumberUtils.isDigits(maxWaitStr.trim())) {
            maxWait = NumberUtils.toInt(maxWaitStr.trim());
        }
        dataSource.setMaxWait(maxWait);

        // 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
        String evictionRunMillsStr = componentConfig.getProperty("datasource.time-between-eviction-runs-millis");
        int evictionRunMills = 60 * 1000;
        if (StringUtils.isNotBlank(evictionRunMillsStr) && NumberUtils.isDigits(evictionRunMillsStr.trim())) {
            evictionRunMills = NumberUtils.toInt(evictionRunMillsStr.trim());
        }
        dataSource.setTimeBetweenEvictionRunsMillis(evictionRunMills);

        // 配置一个连接在池中最小生存的时间,单位是毫秒
        String evictionIdleMillsStr = componentConfig.getProperty("datasource.min-evictable-idle-time-millis");
        int evictionIdleMills = 5 * 60 * 1000;
        if (StringUtils.isNotBlank(evictionIdleMillsStr) && NumberUtils.isDigits(evictionIdleMillsStr.trim())) {
            evictionIdleMills = NumberUtils.toInt(evictionIdleMillsStr.trim());
        }
        dataSource.setMinEvictableIdleTimeMillis(evictionIdleMills);

        // 这里配置提交方式,默认就是TRUE,可以不用配置
        String autoCommitStr = componentConfig.getProperty("datasource.default-auto-commit");
        Boolean autoCommit = true;
        if (StringUtils.isNotBlank(autoCommitStr)) {
            autoCommit = BooleanUtils.toBoolean(autoCommitStr.trim());
        }
        dataSource.setDefaultAutoCommit(autoCommit);

        // 指定获取连接时连接校验的sql查询语句
        String validateQueryStr = componentConfig.getProperty("datasource.validation-query");
        String validateQuery = "Select 1";
        if (StringUtils.isNotBlank(validateQueryStr)) {
            validateQuery = validateQueryStr.trim();
        }
        dataSource.setValidationQuery(validateQuery);

        // 当连接空闲时,是否执行连接测试
        String testWhileIdleStr = componentConfig.getProperty("datasource.test.while-idle");
        Boolean testWhileIdle = true;
        if (StringUtils.isNotBlank(testWhileIdleStr)) {
            testWhileIdle = BooleanUtils.toBoolean(testWhileIdleStr.trim());
        }
        dataSource.setTestWhileIdle(testWhileIdle);

        // 当从连接池借用连接时,是否测试该连接
        String testonBorrowStr = componentConfig.getProperty("datasource.test.on-borrow");
        Boolean testonBorrow = true;
        if (StringUtils.isNotBlank(testOnBorrowStr)) {
            testonBorrow = BooleanUtils.toBoolean(testOnBorrowStr.trim());
        }
        dataSource.setTestonBorrow(testOnBorrow);

        // 在连接归还到连接池时是否测试该连接
        String testonReturnStr = componentConfig.getProperty("datasource.test.on-return");
        Boolean testonReturn = false;
        if (StringUtils.isNotBlank(testOnReturnStr)) {
            testonReturn = BooleanUtils.toBoolean(testOnReturnStr.trim());
        }
        dataSource.setTestonReturn(testOnReturn);


        // 指定是否池化statements
        String prepStatmentStr = componentConfig.getProperty("datasource.pool-prepared-statements");
        Boolean prepStament = false;
        if (StringUtils.isNotBlank(prepStatmentStr)) {
            prepStament = BooleanUtils.toBoolean(prepStatmentStr.trim());
        }
        dataSource.setPoolPreparedStatements(prepStament);

        // 指定最大的打开的prepared statements数量
        String maxPrepStatmentStr = componentConfig.getProperty("datasource.max-open-prepared-statements");
        int maxPrepStament = 10;
        if (StringUtils.isNotBlank(maxPrepStatmentStr) && NumberUtils.isDigits(maxPrepStatmentStr.trim())) {
            maxPrepStament = NumberUtils.toInt(maxPrepStatmentStr.trim());
        }
        dataSource.setMaxOpenPreparedStatements(maxPrepStament);

        //
        String maxPrepStatmentPerConnStr = componentConfig.getProperty("datasource.max-pool-prepared-statement-per-connection-size");
        int maxPrepStamentPerConn = 20;
        if (StringUtils.isNotBlank(maxPrepStatmentPerConnStr) && NumberUtils.isDigits(maxPrepStatmentPerConnStr.trim())) {
            maxPrepStamentPerConn = NumberUtils.toInt(maxPrepStatmentPerConnStr.trim());
        }
        dataSource.setMaxPoolPreparedStatementPerConnectionSize(maxPrepStamentPerConn);
        return dataSource;
    } catch (Throwable e) {
        String msg = "create 'dataSource' bean error.";
        log.error(HikLog.toLog(ExceptionUtil.formatErrorCode(UisErrorCode.ERR_FAILED.errorCode()), msg), e);
        throw new RuntimeException(msg, e);
    }
}

 DruidDataSource参数详解见:SpringBoot配置属性之DataSource_stupider0623的博客-CSDN博客

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/313009.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号