安裝配置
軟件安裝
下載地址:https://www.dameng.com/view_61.html
本文以x86 win64 DM8為例
安裝完畢后打開DM數據庫配置助手創建數據庫,設置字符集utf8,去除字符大小寫敏感
創建表空間及用戶,最好是一個庫對應一個用戶一個表空間,創建用戶時需要指定對應表空間
需要對用戶分配DBA操作權限
數據表遷移
針對現有項目或框架庫需要同步遷移到達夢數據庫,本文以mysql5.7為例,打開DM數據遷移工具,注意保持對象名大小寫,選擇表時全部取出再全選,遷移的表名和字段名就與原數據庫保持一致
maven引用
<dependency>
<groupId>com.dameng</groupId>
<artifactId>DmJdbcDriver18</artifactId>
<version>8.1.1.193</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.0</version>
</dependency>
數據庫配置
使用druid管理連接池,去除wall的配置否則會報錯
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: dm.jdbc.driver.DmDriver
url: jdbc:dm://localhost:5236/ROOT?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf-8
username: ROOT
password: abcd@1234
filters: stat,slf4j
兼容代碼
映射成LinkHashMap
數據會在達夢的數據庫驅動中強制大寫,這對某些接口的數據返回給前端數據大小寫出現問題,影響范圍較大
JdbcTemplate處理
我們可以通過混合使用jdbcTemplate進行查詢的通用操作,調用query方法,傳入自定義的ResultSetExtractor,得到jdbc原生的ResultSet對象,取出ResultSetMetaData轉換成DmdbResultSetMetaData,其中的columns對象為私有對象且無方法訪問,通過反射取出即可,通過columns獲取到數據庫實際的列名
public List<LinkedHashMap<String, Object>> findListByParam(String sqlText, Map<String, Object> map) {
List<LinkedHashMap<String, Object>> result = new ArrayList<>();
List<Object> paramList = new ArrayList<>();
//解析sqlText中的占位符#{xxxx}
String regex = "\\#\\{(?<RegxName>[\\w.]*)\\}";
String sqlTextCopy = sqlText;
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(sqlTextCopy);
while (matcher.find()) {
String paramNameSymbol = matcher.group(0);
sqlText = sqlText.replace(paramNameSymbol, " ? ");
}
logger.debug("【sqlText】:" + sqlText);
//參數賦值
matcher = pattern.matcher(sqlTextCopy);
while (matcher.find()) {
String paramNameSymbol = matcher.group(0);
String paramName = paramNameSymbol.replace("#", "").replace("{", "").replace("}", "");
Object paramValue = map.get(paramName);
logger.debug("【paramName】:" + paramName);
logger.debug("【paramValue】:" + paramValue);
paramList.add(paramValue);
}
jdbcTemplate.query(sqlText, paramList.toArray(), new ResultSetExtractor<Object>() {
@Override
public Object extractData(ResultSet rs) throws SQLException, DataAccessException {
try {
ResultSetMetaData rsMetaData = rs.getMetaData();
Column[] dm_columns = null;
if (dataBaseInfoUtil.getUsingDataBaseType() == GlobalEnum.DataBaseType.DM) {
ResultSetMetaDataProxyImpl resultSetMetaDataProxy = (ResultSetMetaDataProxyImpl) rsMetaData;
DmdbResultSetMetaData dmdbResultSetMetaData = (DmdbResultSetMetaData) resultSetMetaDataProxy.getRawObject();
Class dataClass = DmdbResultSetMetaData.class;
Field field = dataClass.getDeclaredField("columns");
field.setAccessible(true);
dm_columns = (Column[]) field.get(dmdbResultSetMetaData);
}
while (rs.next()) {
LinkedHashMap<String, Object> resultitem = new LinkedHashMap<>();
for (int i = 1; i <= rsMetaData.getColumnCount(); i++) {
String columnName = "";
if (dataBaseInfoUtil.getUsingDataBaseType() == GlobalEnum.DataBaseType.DM) {
columnName = dm_columns[i - 1].name;
} else {
columnName = rsMetaData.getColumnName(i);
;
}
Object columnValue = rs.getObject(columnName);
resultitem.put(columnName, columnValue);
}
result.add(resultitem);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
return null;
}
}
});
return result;
}
與mybaits統一數據源
在使用事務時,因為查詢操作通過jdbcTemplate,更新操作通過myabtis,在某些隔離級別下會查詢不到未提交的數據,所以需要統一數據源都為druid管理的datasource,這里的dynamicDataSource為我自定義的數據源處理對象,繼承自spring的AbstractRoutingDataSource,為了處理多數據源情況
@Bean
public SqlSessionFactory sqlSessionFactory() throws Exception {
//SpringBootExecutableJarVFS.addImplClass(SpringBootVFS.class);
final PackagesSqlSessionFactoryBean sessionFactory = new PackagesSqlSessionFactoryBean();
sessionFactory.setDataSource(dynamicDataSource());
sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources("classpath*:mybatis/**/*Mapper.xml"));
//關閉駝峰轉換,防止帶下划線的字段無法映射
sessionFactory.getObject().getConfiguration().setMapUnderscoreToCamelCase(false);
return sessionFactory.getObject();
}
@Bean
public JdbcTemplate jdbcTemplate(){
JdbcTemplate jdbcTemplate = null;
try{
jdbcTemplate = new JdbcTemplate(dynamicDataSource());
}catch (Exception e){
e.printStackTrace();
}
return jdbcTemplate;
}
映射成實體類
統一將查詢操作結果轉換成LinkHashMap鍵值對,再通過BeanMap映射成對應的實體類
clob長文本處理
Object value = map.get(resultkey);
if(value instanceof ClobProxyImpl){
try {
value = ((ClobProxyImpl) value).getSubString(1,(int)((ClobProxyImpl) value).length());
} catch (Exception e) {
e.printStackTrace();
}
}
blob二進制處理
Object value = map.get(resultkey);
if(value instanceof DmdbBlob){
try {
DmdbBlob dmdbBlob = (DmdbBlob)value;
value = FileUtil.convertStreamToByte(dmdbBlob.getBinaryStream());
} catch (Exception e) {
e.printStackTrace();
}
}