Nacos2.2.0适配达梦DM8数据源

Nacos 从 2.2.0 版本开始,可通过 SPI 机制注入多数据源实现插件,并在引入对应数据源实现后,便可在 Nacos 启动时通过读取 application.properties 配置文件中 spring.datasource.platform 配置项选择加载对应多数据源插件.

Nacos 官方默认实现 MySQL、Derby ,其他类型数据库接入需要参考下文自己扩展。

文章目录

  • Nacos2.2.0适配达梦DM8数据源
  • 一、Nacos官方文档
  • 二、实现步骤
  • 2.1 2.2.0版本源码下载
  • 2.2 引入DM8驱动包
    • 2.2.1 nacos-all pom.xml
    • 2.2.2 nacos-config pom.xml
  • 2.3 nacos-config模块修改
  • 2.4 **nacos-datasource-plugin模块修改**
    • 2.4.1 DataSourceConstant类修改
    • 2.4.2 增加DM8的mapper实现类
    • 2.4.3 com.alibaba.nacos.plugin.datasource.mapper.Mapper修改
  • 2.5 nacos-console模块修改
  • 2.6 Nacos2.2.0适配DM8建表ddl语句
  • 2.7 启动测试
  • 2.8 打包

一、Nacos官方文档

Nacos整体介绍可看Nacos官方文档

二、实现步骤

下面,重点讲解如何通过修改源码实现DM8适配

2.1 2.2.0版本源码下载

2.2.0版本源码下载

2.2 引入DM8驱动包

根据适配版本选择对应驱动包

2.2.1 nacos-all pom.xml

<dm.version>8.1.2.79</dm.version>
 <!--DM8--><dependency><groupId>com.dameng</groupId><artifactId>DmJdbcDriver18</artifactId><version>${dm.version}</version></dependency>

2.2.2 nacos-config pom.xml

 <!--DM8--><dependency><groupId>com.dameng</groupId><artifactId>DmJdbcDriver18</artifactId></dependency>

2.3 nacos-config模块修改

修改类config/src/main/java/com/alibaba/nacos/config/server/service/datasource/ExternalDataSourceProperties.java

修改后的代码如下:

/** Copyright 1999-2018 Alibaba Group Holding Ltd.** 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 com.alibaba.nacos.config.server.service.datasource;import com.alibaba.nacos.common.utils.Preconditions;
import com.alibaba.nacos.common.utils.StringUtils;
import com.zaxxer.hikari.HikariDataSource;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.boot.context.properties.bind.Bindable;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.core.env.Environment;import java.util.ArrayList;
import java.util.List;
import java.util.Objects;import static com.alibaba.nacos.common.utils.CollectionUtils.getOrDefault;/*** Properties of external DataSource.** @author Nacos*/
public class ExternalDataSourceProperties {private String jdbcDriverName = "dm.jdbc.driver.DmDriver";private String testQuery = "SELECT 1";private Integer num;private List<String> url = new ArrayList<>();private List<String> user = new ArrayList<>();private List<String> password = new ArrayList<>();public void setNum(Integer num) {this.num = num;}public void setUrl(List<String> url) {this.url = url;}public void setUser(List<String> user) {this.user = user;}public void setPassword(List<String> password) {this.password = password;}/*** Build serveral HikariDataSource.** @param environment {@link Environment}* @param callback    Callback function when constructing data source* @return List of {@link HikariDataSource}*/List<HikariDataSource> build(Environment environment, Callback<HikariDataSource> callback) {List<HikariDataSource> dataSources = new ArrayList<>();Binder.get(environment).bind("db", Bindable.ofInstance(this));Preconditions.checkArgument(Objects.nonNull(num), "db.num is null");Preconditions.checkArgument(CollectionUtils.isNotEmpty(user), "db.user or db.user.[index] is null");Preconditions.checkArgument(CollectionUtils.isNotEmpty(password), "db.password or db.password.[index] is null");for (int index = 0; index < num; index++) {int currentSize = index + 1;Preconditions.checkArgument(url.size() >= currentSize, "db.url.%s is null", index);DataSourcePoolProperties poolProperties = DataSourcePoolProperties.build(environment);if (StringUtils.isEmpty(poolProperties.getDataSource().getDriverClassName())) {poolProperties.setDriverClassName(jdbcDriverName);}poolProperties.setJdbcUrl(url.get(index).trim());poolProperties.setUsername(getOrDefault(user, index, user.get(0)).trim());poolProperties.setPassword(getOrDefault(password, index, password.get(0)).trim());HikariDataSource ds = poolProperties.getDataSource();if (StringUtils.isEmpty(ds.getConnectionTestQuery())) {ds.setConnectionTestQuery(testQuery);}dataSources.add(ds);callback.accept(ds);}Preconditions.checkArgument(CollectionUtils.isNotEmpty(dataSources), "no datasource available");return dataSources;}interface Callback<D> {/*** Perform custom logic.** @param datasource dataSource.*/void accept(D datasource);}
}

2.4 nacos-datasource-plugin模块修改

2.4.1 DataSourceConstant类修改

修改类:plugin/datasource/src/main/java/com/alibaba/nacos/plugin/datasource/constants/DataSourceConstant.java

修改后的代码如下:

/** Copyright 1999-2022 Alibaba Group Holding Ltd.** 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 com.alibaba.nacos.plugin.datasource.constants;/*** The data source name.** @author czf**/public class DataSourceConstant {public static final String MYSQL = "mysql";public static final String DERBY = "derby";public static final String DM = "dameng";
}

2.4.2 增加DM8的mapper实现类

先上截图,如下新增10个类:

在plugin/datasource/src/main/java/com/alibaba/nacos/plugin/datasource/impl/目录新建dm目录,再在dm目录新增实现类,各个类代码如下:
1、DmAbstractMapper

package com.alibaba.nacos.plugin.datasource.impl.dm;import com.alibaba.nacos.plugin.datasource.mapper.AbstractMapper;import java.util.List;/*** The mysql implementation of DmAbstractMapper.** @author czf*/
public abstract class DmAbstractMapper extends AbstractMapper {@Overridepublic String select(List<String> columns, List<String> where) {StringBuilder sql = new StringBuilder("SELECT ");for (int i = 0; i < columns.size(); i++) {sql.append(columns.get(i));if (i == columns.size() - 1) {sql.append(" ");} else {sql.append(",");}}sql.append("FROM ");sql.append(getTableName());sql.append(" ");if (where.size() == 0) {return sql.toString();}sql.append("WHERE ");for (int i = 0; i < where.size(); i++) {String column = where.get(i);// 租户列特殊处理 避免前端传空字符串是Oracle查询不到数据if ("tenant_id".equalsIgnoreCase(column)) {sql.append("(");sql.append(column).append(" = ").append("?");sql.append(" OR ");sql.append(column).append(" IS NULL ");sql.append(")");} else {sql.append(column).append(" = ").append("?");}if (i != where.size() - 1) {sql.append(" AND ");}}return sql.toString();}@Overridepublic String update(List<String> columns, List<String> where) {StringBuilder sql = new StringBuilder();String method = "UPDATE ";sql.append(method);sql.append(getTableName()).append(" ").append("SET ");for (int i = 0; i < columns.size(); i++) {sql.append(columns.get(i)).append(" = ").append("?");if (i != columns.size() - 1) {sql.append(",");}}if (where.size() == 0) {return sql.toString();}sql.append(" WHERE ");for (int i = 0; i < where.size(); i++) {String column = where.get(i);if ("tenant_id".equalsIgnoreCase(column)) {sql.append("(");sql.append(column).append(" = ").append("?");sql.append(" OR ");sql.append(column).append(" IS NULL ");sql.append(")");} else {sql.append(column).append(" = ").append("?");}if (i != where.size() - 1) {sql.append(" AND ");}}return sql.toString();}@Overridepublic String delete(List<String> params) {StringBuilder sql = new StringBuilder();String method = "DELETE ";sql.append(method).append("FROM ").append(getTableName()).append(" ").append("WHERE ");for (int i = 0; i < params.size(); i++) {String column = params.get(i);if ("tenant_id".equalsIgnoreCase(column)) {sql.append("(");sql.append(column).append(" = ").append("?");sql.append(" OR ");sql.append(column).append(" IS NULL ");sql.append(")");} else {sql.append(column).append(" = ").append("?");}if (i != params.size() - 1) {sql.append("AND ");}}return sql.toString();}@Overridepublic String count(List<String> where) {StringBuilder sql = new StringBuilder();String method = "SELECT ";sql.append(method);sql.append("COUNT(*) FROM ");sql.append(getTableName());sql.append(" ");if (null == where || where.size() == 0) {return sql.toString();}sql.append("WHERE ");for (int i = 0; i < where.size(); i++) {String column = where.get(i);if ("tenant_id".equalsIgnoreCase(column)) {sql.append("(");sql.append(column).append(" = ").append("?");sql.append(" OR ");sql.append(column).append(" IS NULL ");sql.append(")");} else {sql.append(column).append(" = ").append("?");}if (i != where.size() - 1) {sql.append(" AND ");}}return sql.toString();}public String buildPaginationSql(String originalSql, int startRow, int pageSize) {return "SELECT * FROM ( SELECT TMP2.* FROM (SELECT TMP.*, ROWNUM ROW_ID FROM ( " + originalSql+ " ) TMP) TMP2 WHERE ROWNUM <=" + (startRow + pageSize) + ") WHERE ROW_ID > " + startRow;}@Overridepublic abstract String getTableName();@Overridepublic abstract String getDataSource();}

2、ConfigInfoAggrMapperByDm

package com.alibaba.nacos.plugin.datasource.impl.dm;import com.alibaba.nacos.plugin.datasource.constants.DataSourceConstant;
import com.alibaba.nacos.plugin.datasource.constants.TableConstant;
import com.alibaba.nacos.plugin.datasource.mapper.ConfigInfoAggrMapper;import java.util.List;/*** The mysql implementation of ConfigInfoAggrMapperByDm.** @author czf*/
public class ConfigInfoAggrMapperByDm extends DmAbstractMapper implements ConfigInfoAggrMapper {@Overridepublic String batchRemoveAggr(List<String> datumList) {final StringBuilder datumString = new StringBuilder();for (String datum : datumList) {datumString.append('\'').append(datum).append("',");}datumString.deleteCharAt(datumString.length() - 1);return "DELETE FROM config_info_aggr WHERE data_id = ? AND group_id = ? AND (tenant_id = ? OR tenant_id IS NULL) AND datum_id IN ("+ datumString + ")";}@Overridepublic String aggrConfigInfoCount(int size, boolean isIn) {StringBuilder sql = new StringBuilder("SELECT count(*) FROM config_info_aggr WHERE data_id = ? AND group_id = ? AND (tenant_id = ? OR tenant_id IS NULL) AND datum_id");if (isIn) {sql.append(" IN (");} else {sql.append(" NOT IN (");}for (int i = 0; i < size; i++) {if (i > 0) {sql.append(", ");}sql.append('?');}sql.append(')');return sql.toString();}@Overridepublic String findConfigInfoAggrIsOrdered() {return "SELECT data_id,group_id,tenant_id,datum_id,app_name,content FROM "+ "config_info_aggr WHERE data_id = ? AND group_id = ? AND (tenant_id = ? OR tenant_id IS NULL) ORDER BY datum_id";}@Overridepublic String findConfigInfoAggrByPageFetchRows(int startRow, int pageSize) {String sql = "SELECT data_id,group_id,tenant_id,datum_id,app_name,content FROM config_info_aggr WHERE data_id= ? AND "+ "group_id= ? AND (tenant_id= ? OR tenant_id IS NULL) ORDER BY datum_id";return buildPaginationSql(sql, startRow, pageSize);}@Overridepublic String findAllAggrGroupByDistinct() {return "SELECT DISTINCT data_id, group_id, tenant_id FROM config_info_aggr";}@Overridepublic String getTableName() {return TableConstant.CONFIG_INFO_AGGR;}@Overridepublic String getDataSource() {return DataSourceConstant.DM;}}

3、ConfigInfoBetaMapperByDm

package com.alibaba.nacos.plugin.datasource.impl.dm;import com.alibaba.nacos.plugin.datasource.constants.DataSourceConstant;
import com.alibaba.nacos.plugin.datasource.constants.TableConstant;
import com.alibaba.nacos.plugin.datasource.mapper.ConfigInfoBetaMapper;/*** The mysql implementation of ConfigInfoBetaMapperByDm.** @author czf*/
public class ConfigInfoBetaMapperByDm extends DmAbstractMapper implements ConfigInfoBetaMapper {@Overridepublic String updateConfigInfo4BetaCas() {return "UPDATE config_info_beta SET content = ?,md5 = ?,beta_ips = ?,src_ip = ?,src_user = ?,gmt_modified = ?,app_name = ? "+ "WHERE data_id = ? AND group_id = ? AND (tenant_id = ? OR tenant_id IS NULL) AND (md5 = ? or md5 is null or md5 = '')";}@Overridepublic String findAllConfigInfoBetaForDumpAllFetchRows(int startRow, int pageSize) {return " SELECT t.id,data_id,group_id,tenant_id,app_name,content,md5,gmt_modified,beta_ips,encrypted_data_key "+ " FROM ( SELECT rownum ROW_ID,id FROM config_info_beta  WHERE  ROW_ID<=  " + (startRow + pageSize)+ " ORDER BY id )" + " g, config_info_beta t WHERE g.id = t.id AND g.ROW_ID >" + startRow;}@Overridepublic String getTableName() {return TableConstant.CONFIG_INFO_BETA;}@Overridepublic String getDataSource() {return DataSourceConstant.DM;}}

4、ConfigInfoMapperByDm

package com.alibaba.nacos.plugin.datasource.impl.dm;import com.alibaba.nacos.common.utils.CollectionUtils;
import com.alibaba.nacos.common.utils.StringUtils;
import com.alibaba.nacos.plugin.datasource.constants.DataSourceConstant;
import com.alibaba.nacos.plugin.datasource.constants.TableConstant;
import com.alibaba.nacos.plugin.datasource.mapper.ConfigInfoMapper;import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;/*** The mysql implementation of ConfigInfoMapperByDm.** @author czf*/
public class ConfigInfoMapperByDm extends DmAbstractMapper implements ConfigInfoMapper {private static final String DATA_ID = "dataId";private static final String GROUP = "group";private static final String APP_NAME = "appName";private static final String CONTENT = "content";private static final String TENANT = "tenant";@Overridepublic String findConfigMaxId() {return "SELECT MAX(id) FROM config_info";}@Overridepublic String findAllDataIdAndGroup() {return "SELECT DISTINCT data_id, group_id FROM config_info";}@Overridepublic String findConfigInfoByAppCountRows() {return "SELECT count(*) FROM config_info WHERE (tenant_id LIKE ? OR tenant_id IS NULL) AND app_name= ?";}@Overridepublic String findConfigInfoByAppFetchRows(int startRow, int pageSize) {String sql = "SELECT id,data_id,group_id,tenant_id,app_name,content FROM config_info"+ " WHERE (tenant_id LIKE ? OR tenant_id IS NULL) AND app_name= ?";return buildPaginationSql(sql, startRow, pageSize);}@Overridepublic String configInfoLikeTenantCount() {return "SELECT count(*) FROM config_info WHERE (tenant_id LIKE ? OR tenant_id IS NULL)";}@Overridepublic String getTenantIdList(int startRow, int pageSize) {String sql = "SELECT tenant_id FROM config_info WHERE tenant_id IS NOT NULL GROUP BY tenant_id ";return buildPaginationSql(sql, startRow, pageSize);}@Overridepublic String getGroupIdList(int startRow, int pageSize) {String sql = "SELECT group_id FROM config_info WHERE tenant_id IS NULL GROUP BY group_id ";return buildPaginationSql(sql, startRow, pageSize);}@Overridepublic String findAllConfigKey(int startRow, int pageSize) {String sql = " SELECT id,data_id,group_id,app_name FROM config_info WHERE (tenant_id LIKE ? OR tenant_id IS NULL)  ORDER BY id ";return buildPaginationSql(sql, startRow, pageSize);}@Overridepublic String findAllConfigInfoBaseFetchRows(int startRow, int pageSize) {String sql = "SELECT id,data_id,group_id,content,md5 FROM  config_info  ORDER BY id  ";return buildPaginationSql(sql, startRow, pageSize);}@Overridepublic String findAllConfigInfoFragment(int startRow, int pageSize) {String sql = "SELECT id,data_id,group_id,tenant_id,app_name,content,md5,gmt_modified,type,encrypted_data_key "+ "FROM config_info WHERE id > ? ORDER BY id ASC ";return buildPaginationSql(sql, startRow, pageSize);}@Overridepublic String findChangeConfig() {return "SELECT data_id, group_id, tenant_id, app_name, content, gmt_modified,encrypted_data_key "+ "FROM config_info WHERE gmt_modified >= ? AND gmt_modified <= ?";}@Overridepublic String findChangeConfigCountRows(Map<String, String> params, final Timestamp startTime,final Timestamp endTime) {final String tenant = params.get(TENANT);final String dataId = params.get(DATA_ID);final String group = params.get(GROUP);final String appName = params.get(APP_NAME);final String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant;final String sqlCountRows = "SELECT count(*) FROM config_info WHERE ";String where = " 1=1 ";if (!StringUtils.isBlank(dataId)) {where += " AND data_id LIKE ? ";}if (!StringUtils.isBlank(group)) {where += " AND group_id LIKE ? ";}if (!StringUtils.isBlank(tenantTmp)) {where += " AND (tenant_id = ? OR tenant_id IS NULL) ";}if (!StringUtils.isBlank(appName)) {where += " AND app_name = ? ";}if (startTime != null) {where += " AND gmt_modified >=? ";}if (endTime != null) {where += " AND gmt_modified <=? ";}return sqlCountRows + where;}@Overridepublic String findChangeConfigFetchRows(Map<String, String> params, final Timestamp startTime,final Timestamp endTime, int startRow, int pageSize, long lastMaxId) {final String tenant = params.get(TENANT);final String dataId = params.get(DATA_ID);final String group = params.get(GROUP);final String appName = params.get(APP_NAME);final String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant;final String sqlFetchRows = "SELECT id,data_id,group_id,tenant_id,app_name,content,type,md5,gmt_modified FROM config_info WHERE ";String where = " 1=1 ";if (!StringUtils.isBlank(dataId)) {where += " AND data_id LIKE ? ";}if (!StringUtils.isBlank(group)) {where += " AND group_id LIKE ? ";}if (!StringUtils.isBlank(tenantTmp)) {where += " AND (tenant_id = ? OR tenant_id IS NULL) ";}if (!StringUtils.isBlank(appName)) {where += " AND app_name = ? ";}if (startTime != null) {where += " AND gmt_modified >=? ";}if (endTime != null) {where += " AND gmt_modified <=? ";}String sql = sqlFetchRows + where + " AND id > " + lastMaxId + " ORDER BY id ASC";return buildPaginationSql(sql, 0, pageSize);}@Overridepublic String listGroupKeyMd5ByPageFetchRows(int startRow, int pageSize) {String sql = "SELECT id,data_id,group_id,tenant_id,app_name,md5,type,gmt_modified,encrypted_data_key  config_info  ORDER BY id ";return buildPaginationSql(sql, startRow, pageSize);}@Overridepublic String findAllConfigInfo4Export(List<Long> ids, Map<String, String> params) {String tenant = params.get("tenant");String tenantTmp = StringUtils.isBlank(tenant) ? StringUtils.EMPTY : tenant;String sql = "SELECT id,data_id,group_id,tenant_id,app_name,content,type,md5,gmt_create,gmt_modified,src_user,src_ip,"+ "c_desc,c_use,effect,c_schema,encrypted_data_key FROM config_info";StringBuilder where = new StringBuilder(" WHERE ");List<Object> paramList = new ArrayList<>();if (!CollectionUtils.isEmpty(ids)) {where.append(" id IN (");for (int i = 0; i < ids.size(); i++) {if (i != 0) {where.append(", ");}where.append('?');paramList.add(ids.get(i));}where.append(") ");} else {where.append(" (tenant_id= ? OR tenant_id IS NULL)");paramList.add(tenantTmp);if (!StringUtils.isBlank(params.get(DATA_ID))) {where.append(" AND data_id LIKE ? ");}if (StringUtils.isNotBlank(params.get(GROUP))) {where.append(" AND group_id= ? ");}if (StringUtils.isNotBlank(params.get(APP_NAME))) {where.append(" AND app_name= ? ");}}return sql + where;}@Overridepublic String findConfigInfoBaseLikeCountRows(Map<String, String> params) {final String sqlCountRows = "SELECT count(*) FROM config_info WHERE ";String where = " 1=1 AND (tenant_id='' OR tenant_id IS NULL) ";if (!StringUtils.isBlank(params.get(DATA_ID))) {where += " AND data_id LIKE ? ";}if (!StringUtils.isBlank(params.get(GROUP))) {where += " AND group_id LIKE ";}if (!StringUtils.isBlank(params.get(CONTENT))) {where += " AND content LIKE ? ";}return sqlCountRows + where;}@Overridepublic String findConfigInfoBaseLikeFetchRows(Map<String, String> params, int startRow, int pageSize) {final String sqlFetchRows = "SELECT id,data_id,group_id,tenant_id,content FROM config_info WHERE ";String where = " 1=1 AND (tenant_id='' OR tenant_id IS NULL) ";if (!StringUtils.isBlank(params.get(DATA_ID))) {where += " AND data_id LIKE ? ";}if (!StringUtils.isBlank(params.get(GROUP))) {where += " AND group_id LIKE ";}if (!StringUtils.isBlank(params.get(CONTENT))) {where += " AND content LIKE ? ";}String sql = sqlFetchRows + where;return buildPaginationSql(sql, startRow, pageSize);}@Overridepublic String findConfigInfo4PageCountRows(Map<String, String> params) {final String appName = params.get(APP_NAME);final String dataId = params.get(DATA_ID);final String group = params.get(GROUP);final String sqlCount = "SELECT count(*) FROM config_info";StringBuilder where = new StringBuilder(" WHERE ");where.append(" ( tenant_id= ?  or tenant_id is NULL )");if (StringUtils.isNotBlank(dataId)) {where.append(" AND data_id=? ");}if (StringUtils.isNotBlank(group)) {where.append(" AND group_id=? ");}if (StringUtils.isNotBlank(appName)) {where.append(" AND app_name=? ");}return sqlCount + where;}@Overridepublic String findConfigInfo4PageFetchRows(Map<String, String> params, int startRow, int pageSize) {final String appName = params.get(APP_NAME);final String dataId = params.get(DATA_ID);final String group = params.get(GROUP);final String sql = "SELECT id,data_id,group_id,tenant_id,app_name,content,type,encrypted_data_key FROM config_info";StringBuilder where = new StringBuilder(" WHERE ");where.append(" ( tenant_id= ?  or tenant_id is NULL ) ");if (StringUtils.isNotBlank(dataId)) {where.append(" AND data_id=? ");}if (StringUtils.isNotBlank(group)) {where.append(" AND group_id=? ");}if (StringUtils.isNotBlank(appName)) {where.append(" AND app_name=? ");}return buildPaginationSql(sql + where, startRow, pageSize);}@Overridepublic String findConfigInfoBaseByGroupFetchRows(int startRow, int pageSize) {String sql = "SELECT id,data_id,group_id,content FROM config_info WHERE group_id=? AND ( tenant_id= ?  or tenant_id is NULL )";return buildPaginationSql(sql, startRow, pageSize);}@Overridepublic String findConfigInfoLike4PageCountRows(Map<String, String> params) {String dataId = params.get(DATA_ID);String group = params.get(GROUP);final String appName = params.get(APP_NAME);final String content = params.get(CONTENT);final String sqlCountRows = "SELECT count(*) FROM config_info";StringBuilder where = new StringBuilder(" WHERE ");where.append(" (tenant_id LIKE ? OR tenant_id IS NULL) ");if (!StringUtils.isBlank(dataId)) {where.append(" AND data_id LIKE ? ");}if (!StringUtils.isBlank(group)) {where.append(" AND group_id LIKE ? ");}if (!StringUtils.isBlank(appName)) {where.append(" AND app_name = ? ");}if (!StringUtils.isBlank(content)) {where.append(" AND content LIKE ? ");}return sqlCountRows + where;}@Overridepublic String findConfigInfoLike4PageFetchRows(Map<String, String> params, int startRow, int pageSize) {String dataId = params.get(DATA_ID);String group = params.get(GROUP);final String appName = params.get(APP_NAME);final String content = params.get(CONTENT);final String sqlFetchRows = "SELECT id,data_id,group_id,tenant_id,app_name,content,encrypted_data_key FROM config_info";StringBuilder where = new StringBuilder(" WHERE ");where.append(" (tenant_id LIKE ? OR tenant_id IS NULL) ");if (!StringUtils.isBlank(dataId)) {where.append(" AND data_id LIKE ? ");}if (!StringUtils.isBlank(group)) {where.append(" AND group_id LIKE ? ");}if (!StringUtils.isBlank(appName)) {where.append(" AND app_name = ? ");}if (!StringUtils.isBlank(content)) {where.append(" AND content LIKE ? ");}return buildPaginationSql(sqlFetchRows + where, startRow, pageSize);}@Overridepublic String findAllConfigInfoFetchRows(int startRow, int pageSize) {String sql = "SELECT id,data_id,group_id,tenant_id,app_name,content,md5 "+ " FROM  config_info WHERE (tenant_id LIKE ? OR tenant_id IS NULL) ORDER BY id ";return buildPaginationSql(sql, startRow, pageSize);}@Overridepublic String findConfigInfosByIds(int idSize) {StringBuilder sql = new StringBuilder("SELECT ID,data_id,group_id,tenant_id,app_name,content,md5 FROM config_info WHERE ");sql.append("id IN (");for (int i = 0; i < idSize; i++) {if (i != 0) {sql.append(", ");}sql.append('?');}sql.append(") ");return sql.toString();}@Overridepublic String removeConfigInfoByIdsAtomic(int size) {StringBuilder sql = new StringBuilder("DELETE FROM config_info WHERE ");sql.append("id IN (");for (int i = 0; i < size; i++) {if (i != 0) {sql.append(", ");}sql.append('?');}sql.append(") ");return sql.toString();}@Overridepublic String updateConfigInfoAtomicCas() {return "UPDATE config_info SET "+ "content=?, md5 = ?, src_ip=?,src_user=?,gmt_modified=?, app_name=?,c_desc=?,c_use=?,effect=?,type=?,c_schema=? "+ "WHERE data_id=? AND group_id=? AND (tenant_id=? OR tenant_id IS NULL) AND (md5=? OR md5 IS NULL OR md5='')";}@Overridepublic String getTableName() {return TableConstant.CONFIG_INFO;}@Overridepublic String getDataSource() {return DataSourceConstant.DM;}}

5、ConfigInfoTagMapperByDm

package com.alibaba.nacos.plugin.datasource.impl.dm;import com.alibaba.nacos.plugin.datasource.constants.DataSourceConstant;
import com.alibaba.nacos.plugin.datasource.constants.TableConstant;
import com.alibaba.nacos.plugin.datasource.mapper.ConfigInfoTagMapper;/*** The mysql implementation of ConfigInfoTagMapperByDm.** @author czf*/
public class ConfigInfoTagMapperByDm extends DmAbstractMapper implements ConfigInfoTagMapper {@Overridepublic String updateConfigInfo4TagCas() {return "UPDATE config_info_tag SET content = ?, md5 = ?, src_ip = ?,src_user = ?"+ ",gmt_modified = ?,app_name = ? "+ "WHERE data_id = ? AND group_id = ? AND"+ " (tenant_id = ? OR tenant_id IS NULL) AND tag_id = ? AND (md5 = ? OR md5 IS NULL OR md5 = '')";}@Overridepublic String findAllConfigInfoTagForDumpAllFetchRows(int startRow, int pageSize) {return " SELECT t.id,data_id,group_id,tenant_id,tag_id,app_name,content,md5,gmt_modified "+ " FROM (  SELECT id FROM config_info_tag WHERE  ROWNUM > " + startRow + " AND ROWNUM <="+ (startRow + pageSize) + "ORDER BY id   " + " ) " + "g, config_info_tag t  WHERE g.id = t.id  ";}@Overridepublic String getTableName() {return TableConstant.CONFIG_INFO_TAG;}@Overridepublic String getDataSource() {return DataSourceConstant.DM;}}

6、ConfigTagsRelationMapperByDm

package com.alibaba.nacos.plugin.datasource.impl.dm;import com.alibaba.nacos.common.utils.StringUtils;
import com.alibaba.nacos.plugin.datasource.constants.DataSourceConstant;
import com.alibaba.nacos.plugin.datasource.constants.TableConstant;
import com.alibaba.nacos.plugin.datasource.mapper.ConfigTagsRelationMapper;import java.util.Map;/*** The mysql implementation of ConfigTagsRelationMapperByDm.** @author czf*/
public class ConfigTagsRelationMapperByDm extends DmAbstractMapper implements ConfigTagsRelationMapper {@Overridepublic String findConfigInfo4PageCountRows(final Map<String, String> params, final int tagSize) {final String appName = params.get("appName");final String dataId = params.get("dataId");final String group = params.get("group");StringBuilder where = new StringBuilder(" WHERE ");final String sqlCount = "SELECT count(*) FROM config_info  a LEFT JOIN config_tags_relation b ON a.id=b.id";where.append(" (a.tenant_id=? OR a.tenant_id IS NULL)");if (StringUtils.isNotBlank(dataId)) {where.append(" AND a.data_id=? ");}if (StringUtils.isNotBlank(group)) {where.append(" AND a.group_id=? ");}if (StringUtils.isNotBlank(appName)) {where.append(" AND a.app_name=? ");}where.append(" AND b.tag_name IN (");for (int i = 0; i < tagSize; i++) {if (i != 0) {where.append(", ");}where.append('?');}where.append(") ");return sqlCount + where;}@Overridepublic String findConfigInfo4PageFetchRows(Map<String, String> params, int tagSize, int startRow, int pageSize) {final String appName = params.get("appName");final String dataId = params.get("dataId");final String group = params.get("group");StringBuilder where = new StringBuilder(" WHERE ");final String sql = "SELECT a.id,a.data_id,a.group_id,a.tenant_id,a.app_name,a.content FROM config_info  a LEFT JOIN "+ "config_tags_relation b ON a.id=b.id";where.append("( a.tenant_id=? OR tenant_id IS NULL)");if (StringUtils.isNotBlank(dataId)) {where.append(" AND a.data_id=? ");}if (StringUtils.isNotBlank(group)) {where.append(" AND a.group_id=? ");}if (StringUtils.isNotBlank(appName)) {where.append(" AND a.app_name=? ");}where.append(" AND b.tag_name IN (");for (int i = 0; i < tagSize; i++) {if (i != 0) {where.append(", ");}where.append('?');}where.append(") ");return sql + where + " AND  ROWNUM > " + sql + " AND ROWNUM <= " + (startRow + pageSize);}@Overridepublic String findConfigInfoLike4PageCountRows(final Map<String, String> params, int tagSize) {final String appName = params.get("appName");final String content = params.get("content");final String dataId = params.get("dataId");final String group = params.get("group");StringBuilder where = new StringBuilder(" WHERE ");final String sqlCountRows = "SELECT count(*) FROM config_info  a LEFT JOIN config_tags_relation b ON a.id=b.id ";where.append(" a.(tenant_id LIKE ? OR tenant_id IS NULL) ");if (!StringUtils.isBlank(dataId)) {where.append(" AND a.data_id LIKE ? ");}if (!StringUtils.isBlank(group)) {where.append(" AND a.group_id LIKE ? ");}if (!StringUtils.isBlank(appName)) {where.append(" AND a.app_name = ? ");}if (!StringUtils.isBlank(content)) {where.append(" AND a.content LIKE ? ");}where.append(" AND b.tag_name IN (");for (int i = 0; i < tagSize; i++) {if (i != 0) {where.append(", ");}where.append('?');}where.append(") ");return sqlCountRows + where;}@Overridepublic String findConfigInfoLike4PageFetchRows(final Map<String, String> params, int tagSize, int startRow,int pageSize) {final String appName = params.get("appName");final String content = params.get("content");final String dataId = params.get("dataId");final String group = params.get("group");StringBuilder where = new StringBuilder(" WHERE ");final String sqlFetchRows = "SELECT a.id,a.data_id,a.group_id,a.tenant_id,a.app_name,a.content "+ "FROM config_info a LEFT JOIN config_tags_relation b ON a.id=b.id ";where.append(" a.(tenant_id LIKE ? OR tenant_id IS NULL) ");if (!StringUtils.isBlank(dataId)) {where.append(" AND a.data_id LIKE ? ");}if (!StringUtils.isBlank(group)) {where.append(" AND a.group_id LIKE ? ");}if (!StringUtils.isBlank(appName)) {where.append(" AND a.app_name = ? ");}if (!StringUtils.isBlank(content)) {where.append(" AND a.content LIKE ? ");}where.append(" AND b.tag_name IN (");for (int i = 0; i < tagSize; i++) {if (i != 0) {where.append(", ");}where.append('?');}where.append(") ");return sqlFetchRows + where + " AND ROWNUM > " + startRow + " AND ROWNUM <= " + (startRow + pageSize);}@Overridepublic String getTableName() {return TableConstant.CONFIG_TAGS_RELATION;}@Overridepublic String getDataSource() {return DataSourceConstant.DM;}}

7、GroupCapacityMapperByDm

package com.alibaba.nacos.plugin.datasource.impl.dm;import com.alibaba.nacos.plugin.datasource.constants.DataSourceConstant;
import com.alibaba.nacos.plugin.datasource.constants.TableConstant;
import com.alibaba.nacos.plugin.datasource.mapper.GroupCapacityMapper;/*** The mysql implementation of GroupCapacityMapperByDm.** @author czf*/
public class GroupCapacityMapperByDm extends DmAbstractMapper implements GroupCapacityMapper {@Overridepublic String insertIntoSelect() {return "INSERT INTO group_capacity (group_id, quota, `usage`, `max_size`, max_aggr_count, max_aggr_size,gmt_create,"+ " gmt_modified) SELECT ?, ?, count(*), ?, ?, ?, ?, ? FROM config_info";}@Overridepublic String insertIntoSelectByWhere() {return "INSERT INTO group_capacity (group_id, quota,`usage`, `max_size`, max_aggr_count, max_aggr_size, gmt_create,"+ " gmt_modified) SELECT ?, ?, count(*), ?, ?, ?, ?, ? FROM config_info WHERE group_id=? AND tenant_id = ''";}@Overridepublic String incrementUsageByWhereQuotaEqualZero() {return "UPDATE group_capacity SET `usage` = `usage` + 1, gmt_modified = ? WHERE group_id = ? AND `usage` < ? AND quota = 0";}@Overridepublic String incrementUsageByWhereQuotaNotEqualZero() {return "UPDATE group_capacity SET `usage` = `usage` + 1, gmt_modified = ? WHERE group_id = ? AND `usage` < quota AND quota != 0";}@Overridepublic String incrementUsageByWhere() {return "UPDATE group_capacity SET `usage` = `usage` + 1, gmt_modified = ? WHERE group_id = ?";}@Overridepublic String decrementUsageByWhere() {return "UPDATE group_capacity SET `usage` = `usage` - 1, gmt_modified = ? WHERE group_id = ? AND `usage` > 0";}@Overridepublic String updateUsage() {return "UPDATE group_capacity SET `usage` = (SELECT count(*) FROM config_info), gmt_modified = ? WHERE group_id = ?";}@Overridepublic String updateUsageByWhere() {return "UPDATE group_capacity SET `usage` = (SELECT count(*) FROM config_info WHERE group_id=? AND tenant_id = ''),"+ " gmt_modified = ? WHERE group_id= ?";}@Overridepublic String selectGroupInfoBySize() {return "SELECT id, group_id FROM group_capacity WHERE id > ? ROWNUM > ?";}@Overridepublic String getTableName() {return TableConstant.GROUP_CAPACITY;}@Overridepublic String getDataSource() {return DataSourceConstant.DM;}}

8、HistoryConfigInfoMapperByDm

package com.alibaba.nacos.plugin.datasource.impl.dm;import com.alibaba.nacos.plugin.datasource.constants.DataSourceConstant;
import com.alibaba.nacos.plugin.datasource.constants.TableConstant;
import com.alibaba.nacos.plugin.datasource.mapper.HistoryConfigInfoMapper;/*** The mysql implementation of HistoryConfigInfoMapperByDm.* @author czf*/
public class HistoryConfigInfoMapperByDm extends DmAbstractMapper implements HistoryConfigInfoMapper {@Overridepublic String removeConfigHistory() {return "DELETE FROM his_config_info WHERE gmt_modified < ? AND ROWNUM > ?";}@Overridepublic String findConfigHistoryCountByTime() {return "SELECT count(*) FROM his_config_info WHERE gmt_modified < ?";}@Overridepublic String findDeletedConfig() {return "SELECT DISTINCT data_id, group_id, tenant_id FROM his_config_info WHERE op_type = 'D' AND gmt_modified >= ? AND gmt_modified <= ?";}@Overridepublic String findConfigHistoryFetchRows() {return "SELECT nid,data_id,group_id,tenant_id,app_name,src_ip,src_user,op_type,gmt_create,gmt_modified FROM his_config_info "+ "WHERE data_id = ? AND group_id = ? AND (tenant_id = ? OR tenant_id IS NULL) ORDER BY nid DESC";}@Overridepublic String detailPreviousConfigHistory() {return "SELECT nid,data_id,group_id,tenant_id,app_name,content,md5,src_user,src_ip,op_type,gmt_create,gmt_modified "+ "FROM his_config_info WHERE nid = (SELECT max(nid) FROM his_config_info WHERE id = ?) ";}@Overridepublic String getTableName() {return TableConstant.HIS_CONFIG_INFO;}@Overridepublic String getDataSource() {return DataSourceConstant.DM;}}

9、TenantCapacityMapperByDm

package com.alibaba.nacos.plugin.datasource.impl.dm;import com.alibaba.nacos.plugin.datasource.constants.DataSourceConstant;
import com.alibaba.nacos.plugin.datasource.constants.TableConstant;
import com.alibaba.nacos.plugin.datasource.mapper.TenantCapacityMapper;/*** The mysql implementation of TenantCapacityMapperByDm.** @author czf*/
public class TenantCapacityMapperByDm extends DmAbstractMapper implements TenantCapacityMapper {@Overridepublic String incrementUsageWithDefaultQuotaLimit() {return "UPDATE tenant_capacity SET `usage` = `usage` + 1,"+ " gmt_modified = ? WHERE ((tenant_id = ? OR tenant_id IS NULL) OR tenant_id IS NULL) AND `usage` <"+ " ? AND quota = 0";}@Overridepublic String incrementUsageWithQuotaLimit() {return "UPDATE tenant_capacity SET `usage` = `usage` + 1, gmt_modified = ? WHERE (tenant_id = ? OR tenant_id IS NULL) AND `usage` < "+ "quota AND quota != 0";}@Overridepublic String incrementUsage() {return "UPDATE tenant_capacity SET `usage` = `usage` + 1, gmt_modified = ? WHERE (tenant_id = ? OR tenant_id IS NULL)";}@Overridepublic String decrementUsage() {return "UPDATE tenant_capacity SET `usage` = `usage` - 1, gmt_modified = ? WHERE (tenant_id = ? OR tenant_id IS NULL) AND `usage` > 0";}@Overridepublic String correctUsage() {return "UPDATE tenant_capacity SET `usage` = (SELECT count(*) FROM config_info WHERE (tenant_id = ? OR tenant_id IS NULL)), "+ "gmt_modified = ? WHERE (tenant_id = ? OR tenant_id IS NULL)";}@Overridepublic String getCapacityList4CorrectUsage() {return "SELECT id, tenant_id FROM tenant_capacity WHERE id> AND  ROWNUM > ?";}@Overridepublic String insertTenantCapacity() {return "INSERT INTO tenant_capacity (tenant_id, quota, `usage`, `max_size`, max_aggr_count, max_aggr_size, "+ "gmt_create, gmt_modified) SELECT ?, ?, count(*), ?, ?, ?, ?, ? FROM config_info WHERE tenant_id=? OR tenant_id IS NULL;";}@Overridepublic String getTableName() {return TableConstant.TENANT_CAPACITY;}@Overridepublic String getDataSource() {return DataSourceConstant.DM;}}

10、TenantInfoMapperByDm

package com.alibaba.nacos.plugin.datasource.impl.dm;import com.alibaba.nacos.plugin.datasource.constants.DataSourceConstant;
import com.alibaba.nacos.plugin.datasource.constants.TableConstant;
import com.alibaba.nacos.plugin.datasource.mapper.TenantInfoMapper;/*** The mysql implementation of TenantInfoMapperByDm.** @author czf*/
public class TenantInfoMapperByDm extends DmAbstractMapper implements TenantInfoMapper {@Overridepublic String getTableName() {return TableConstant.TENANT_INFO;}@Overridepublic String getDataSource() {return DataSourceConstant.DM;}}

2.4.3 com.alibaba.nacos.plugin.datasource.mapper.Mapper修改

修改类:plugin/datasource/src/main/resources/META-INF/services/com.alibaba.nacos.plugin.datasource.mapper.Mapper

#
# Copyright 1999-2022 Alibaba Group Holding Ltd.
#
# 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.
#com.alibaba.nacos.plugin.datasource.impl.mysql.ConfigInfoAggrMapperByMySql
com.alibaba.nacos.plugin.datasource.impl.mysql.ConfigInfoBetaMapperByMySql
com.alibaba.nacos.plugin.datasource.impl.mysql.ConfigInfoMapperByMySql
com.alibaba.nacos.plugin.datasource.impl.mysql.ConfigInfoTagMapperByMySql
com.alibaba.nacos.plugin.datasource.impl.mysql.ConfigTagsRelationMapperByMySql
com.alibaba.nacos.plugin.datasource.impl.mysql.HistoryConfigInfoMapperByMySql
com.alibaba.nacos.plugin.datasource.impl.mysql.TenantInfoMapperByMySql
com.alibaba.nacos.plugin.datasource.impl.mysql.TenantCapacityMapperByMySql
com.alibaba.nacos.plugin.datasource.impl.mysql.GroupCapacityMapperByMysqlcom.alibaba.nacos.plugin.datasource.impl.derby.ConfigInfoAggrMapperByDerby
com.alibaba.nacos.plugin.datasource.impl.derby.ConfigInfoBetaMapperByDerby
com.alibaba.nacos.plugin.datasource.impl.derby.ConfigInfoMapperByDerby
com.alibaba.nacos.plugin.datasource.impl.derby.ConfigInfoTagMapperByDerby
com.alibaba.nacos.plugin.datasource.impl.derby.ConfigInfoTagsRelationMapperByDerby
com.alibaba.nacos.plugin.datasource.impl.derby.HistoryConfigInfoMapperByDerby
com.alibaba.nacos.plugin.datasource.impl.derby.TenantInfoMapperByDerby
com.alibaba.nacos.plugin.datasource.impl.derby.TenantCapacityMapperByDerby
com.alibaba.nacos.plugin.datasource.impl.derby.GroupCapacityMapperByDerbycom.alibaba.nacos.plugin.datasource.impl.dm.ConfigInfoAggrMapperByDm
com.alibaba.nacos.plugin.datasource.impl.dm.ConfigInfoBetaMapperByDm
com.alibaba.nacos.plugin.datasource.impl.dm.ConfigInfoMapperByDm
com.alibaba.nacos.plugin.datasource.impl.dm.ConfigInfoTagMapperByDm
com.alibaba.nacos.plugin.datasource.impl.dm.ConfigTagsRelationMapperByDm
com.alibaba.nacos.plugin.datasource.impl.dm.HistoryConfigInfoMapperByDm
com.alibaba.nacos.plugin.datasource.impl.dm.TenantInfoMapperByDm
com.alibaba.nacos.plugin.datasource.impl.dm.TenantCapacityMapperByDm
com.alibaba.nacos.plugin.datasource.impl.dm.GroupCapacityMapperByDm

2.5 nacos-console模块修改

修改配置文件:console/src/main/resources/application.properties
只修改一部分,数据源连接信息,截图如下:

#*************** Config Module Related Configurations ***************#
### Deprecated configuration property, it is recommended to use `spring.sql.init.platform` replaced.
spring.datasource.platform=dameng
#nacos.plugin.datasource.log.enabled=true
#spring.sql.init.platform=dm
### Count of DB:
db.num=1### Connect URL of DB:
# db.url.0=jdbc:mysql://127.0.0.1:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
# db.user=nacos
# db.password=nacos
db.url.0=jdbc:dm://127.0.0.1:5236/nacos?schema=nacos&useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true
db.user.0=SYSDBA
db.password.0=SYSDBA
pool.config.driver-class-name: dm.jdbc.driver.DmDriver

2.6 Nacos2.2.0适配DM8建表ddl语句

Nacos2.2.0适配DM8建表ddl语句

2.7 启动测试

启动主类加入 -Dnacos.standalone=true 参数,以单机模式启动


如果出现 use external storage 说明你全部配置正确,如果没有,请仔细检查操作步骤。

访问http://localhost:8848/nacos

2.8 打包

在nacos-all目录下执行mvn命令

mvn -Prelease-nacos -Dmaven.test.skip=true -Dpmd.skip=true -Drat.skip=true -Dcheckstyle.skip=true clean install -U

最后在distributioni目录下的target就会出现压缩文件了,这样就相当于从nacos官网直接下载的压缩包,具体nacos配置可以自行完成。

【Nacos2.2.0适配达梦DM8数据源】相关推荐

  1. 国产化之路-统信UOS /Nginx /Asp.Net Core+ EF Core 3.1/达梦DM8实现简单增删改查操作

    引言 经过前期的准备工作,.net core 3.1的运行环境和WEB服务器已经搭建完毕,这里需要注意一下,达梦DM8数据库对于Entity Framework Core 3.1 的驱动在NuGet官 ...

  2. 立足国产自主可控技术 达梦DM8数据库新品化繁为简

    戳蓝字"CSDN云计算"关注我们哦! 面对技术日新月异的发展,如今俨然已经演变成为数据发展引来的潮流,而数据库的建立对企业的发展有着举足轻重的作用,对数据库的有效开发和管理是企业正 ...

  3. javaweb简单的登录增删改查系统_国产化之路统信UOS /Nginx /Asp.Net Core+ EF Core 3.1/达梦DM8实现简单增删改查操作...

    引言 经过前期的准备工作,.net core 3.1的运行环境和WEB服务器已经搭建完毕,这里需要注意一下,达梦DM8数据库对于Entity Framework Core 3.1 的驱动在NuGet官 ...

  4. liquibase 扩展适配达梦数据库(dm7)

    背景 之前因项目客户要求,需要适配国产数据库-达梦(这里适配的是达梦大型通用数据库管理系统,简称DM7),对代码中的sql 改造,同时因为项目中的数据库的建表脚本.字典等都是使用 liquibase ...

  5. 达梦dm8可视化工具_活字格兼容达梦DM8,低代码支持数据库国产化

    DM8是达梦公司在总结DM系列产品研发与应用经验的基础上,坚持开放创新.简洁实用的理念,历经五年匠心打磨,推出的新一代自研数据库.DM8和同类自主知识产权数据库一起,正在引领数据库国产化的大趋势. ( ...

  6. 达梦DM8搭建DSC过程以及遇到的问题

    达梦DM8搭建DSC过程以及遇到的问题 DMDSC 是什么? DM DSC是一个单数据库.多实例的集群系统:具有高可用性.高性能.负载均衡等特性 DMDSC架构 DMDSC 组件: 集群主要由数据库和 ...

  7. 达梦DM8数据库异机数据迁移测试

    达梦 DM8 数据库异机数据迁移测试 一.源库备份 源库DMOA,主机名:dm3   目标库 DMOA 主机名:db 在DMTEST模式里创建了T_EMP01.T_EMP02.T_EMP03.T_TE ...

  8. 达梦DM8之闪回查询

    达梦DM8之闪回功能测试         当用户操作不慎导致错误的删改数据时,非常希望有一种简单快捷的方式可以恢复数据.闪回技术,就是为了用户可以迅速处理这种数据逻辑损坏的情况而产生的.        ...

  9. 达梦DM8主从复制配置实战

    概述 达梦数据复制(DATA REPLICATION)是一个分担系统访问压力.加快异地访问响应速度.提高数据可靠性的解决方案.将一个服务器实例上的数据变更复制到另外的服务器实例.可以用于解决大.中型应 ...

最新文章

  1. TableStore: 海量结构化数据分层存储方案
  2. 三方博弈matlab_小星星的读研日记之电商动态博弈知多少?
  3. Java面向对象(三)Static
  4. Python中__init__和self的意义和作用
  5. 5A通过PMP考试分享
  6. PHP查询微信的投诉单列表
  7. java语言实现视频音频采集_详解js的视频和音频采集
  8. 【智慧农业】智慧温室建造流程
  9. linux用户禁止登录,Linux限制用户登录
  10. 项目1在线交流平台-7.构建安全高效的企业服务-2.使用Security自定义社区网页认证与授权
  11. 疫情最大赢家现身,不是疫苗公司,是集装箱!
  12. 怎么在线免费压缩图片
  13. Python - 定时自动获取 Bing 首页壁纸
  14. 电子表整点报时怎么取消_歪果仁怎么说“我被放鸽子了”?这可跟鸽子没关系哦...
  15. 2021上海高考小三门成绩查询,2021上海高考等级考分数怎么划分等级的
  16. 卷起来了!校招提前批爆发期!
  17. 刷脸时代真的来了?R5人脸识别智能锁告诉你
  18. python教程07-while语句的基本使用、for...in循环的使用、break与continue、打印矩形三角形九九乘法表、基础题、进阶题
  19. 【转】寻找一种易于理解的一致性算法(扩展版)
  20. mysql存储过程异常记录_MySQL存储过程的“异常处理”

热门文章

  1. iOS 获取汉字的拼音
  2. STM32F103时钟结构
  3. kali+linux+手机装热点,详解:手机安装Kali Linux
  4. python十六进制转换为字符串_Python 十六进制整数与ASCii编码字符串相互转换方法...
  5. 5G 关键技术 通信人家园转载
  6. 系统分析师论文3:论信息系统开发方法及应用
  7. 程序人生(二)汉语拼音之父周有光去世——一个播音专业安卓程序员有感
  8. 南京理工大学 计算机调剂科目,南京理工大学2019考研调剂信息
  9. Effective C++ 日积月累
  10. 3DAOI原理及编程手册(1)——工作原理