Skip to content

Commit

Permalink
✨ 支持达梦数据库
Browse files Browse the repository at this point in the history
  • Loading branch information
leshalv committed Sep 18, 2020
1 parent 11d58b1 commit a622bdd
Show file tree
Hide file tree
Showing 8 changed files with 571 additions and 16 deletions.
Binary file added lib/Dm7JdbcDriver-16.jar
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@

import cn.smallbun.screw.core.query.cachedb.CacheDbDataBaseQuery;
import cn.smallbun.screw.core.query.db2.Db2DataBaseQuery;
import cn.smallbun.screw.core.query.dm.DmDataBaseQuery;
import cn.smallbun.screw.core.query.h2.H2DataBaseQuery;
import cn.smallbun.screw.core.query.highgo.HigHgoDataBaseQuery;
import cn.smallbun.screw.core.query.hsql.HsqlDataBaseQuery;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,94 @@
*/
package cn.smallbun.screw.core.query.dm;

import static cn.smallbun.screw.core.constant.DefaultConstants.PERCENT_SIGN;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.stream.Collectors;

import javax.sql.DataSource;

import cn.smallbun.screw.core.exception.QueryException;
import cn.smallbun.screw.core.mapping.Mapping;
import cn.smallbun.screw.core.metadata.Column;
import cn.smallbun.screw.core.metadata.Database;
import cn.smallbun.screw.core.metadata.PrimaryKey;
import cn.smallbun.screw.core.metadata.Table;
import cn.smallbun.screw.core.query.AbstractDatabaseQuery;
import cn.smallbun.screw.core.query.dm.model.DmColumnModel;
import cn.smallbun.screw.core.query.dm.model.DmDatabaseModel;
import cn.smallbun.screw.core.query.dm.model.DmPrimaryKeyModel;
import cn.smallbun.screw.core.query.dm.model.DmTableModel;
import cn.smallbun.screw.core.util.Assert;
import cn.smallbun.screw.core.util.CollectionUtils;
import cn.smallbun.screw.core.util.ExceptionUtils;

import javax.sql.DataSource;
import java.util.List;

import static cn.smallbun.screw.core.constant.DefaultConstants.NOT_SUPPORTED;
import cn.smallbun.screw.core.util.JdbcUtils;
import dm.jdbc.driver.DmdbConnection;

/**
* 达梦数据库查询
*
* @author SanLi
* Created by qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/3/20 17:40
* Created by jincy@neusoft.com + qinggang.zuo@gmail.com / 2689170096@qq.com on 2020/9/17 17:40
*/
@SuppressWarnings("serial")
public class DmDataBaseQuery extends AbstractDatabaseQuery {
private ConcurrentMap<String, List<DmTableModel>> tablesMap = new ConcurrentHashMap<>();
private static String DM_QUERY_TABLE_SQL = ""
+ "select "
+ " ut.table_name TABLE_NAME, "
+ " utc.comments COMMENTS "
+ "from "
+ " user_tables ut "
+ "left join USER_TAB_COMMENTS utc "
+ "on "
+ " ut.table_name=utc.table_name ";

private static String DM_QUERY_COLUMNS_SQL = "" + "select "
+ " ut.table_name TABLE_NAME , "
+ " uc.column_name COLUMN_NAME , "
//+ " case uc.data_type when 'INT' then uc.data_type when 'CLOB' then uc.data_type when 'BLOB' then uc.data_type when 'INTEGER' then uc.data_type else concat(concat(concat(uc.data_type, '('), uc.data_length), ')') end case AS COLUMN_TYPE , "
+ " case uc.data_type when 'CLOB' then uc.data_type when 'BLOB' then uc.data_type else concat(concat(concat(uc.data_type, '('), uc.data_length), ')') end case AS COLUMN_TYPE , "
+ " uc.data_length COLUMN_LENGTH , "
+ " uc.DATA_PRECISION DATA_PRECISION, "
+ " uc.DATA_SCALE DECIMAL_DIGITS, "
+ " case uc.NULLABLE when 'Y' then '1' else '0' end case NULLABLE,"
+ " uc.DATA_DEFAULT COLUMN_DEF, "
+ " ucc.comments REMARKS "
+ "from "
+ " user_tables ut "
+ "left join USER_TAB_COMMENTS utc "
+ "on "
+ " ut.table_name=utc.table_name "
+ "left join user_tab_columns uc "
+ "on "
+ " ut.table_name=uc.table_name "
+ "left join user_col_comments ucc "
+ "on "
+ " uc.table_name =ucc.table_name "
+ " and uc.column_name=ucc.column_name "
+ "where 1=1 ";

private static String DM_QUERY_PK_SQL = "" + "SELECT "
+ "C.OWNER AS TABLE_SCHEM, "
+ "C.TABLE_NAME , "
+ "C.COLUMN_NAME , "
+ "C.POSITION AS KEY_SEQ , "
+ "C.CONSTRAINT_NAME AS PK_NAME "
+ "FROM "
+ " ALL_CONS_COLUMNS C, "
+ " ALL_CONSTRAINTS K "
+ "WHERE "
+ " K.CONSTRAINT_TYPE = 'P' "
+ " AND K.OWNER = '%s' "
+ " AND K.CONSTRAINT_NAME = C.CONSTRAINT_NAME "
+ " AND K.TABLE_NAME = C.TABLE_NAME "
+ " AND K.OWNER = C.OWNER ";

/**
* 构造函数
Expand All @@ -55,7 +122,46 @@ public DmDataBaseQuery(DataSource dataSource) {
*/
@Override
public Database getDataBase() throws QueryException {
throw ExceptionUtils.mpe(NOT_SUPPORTED);
DmDatabaseModel model = new DmDatabaseModel();
//当前数据库名称
model.setDatabase(getSchema());
return model;
}

/**
* 获取达梦数据库的schema
*
* @return {@link String} 达梦数据库的schema信息
*/
@Override
public String getSchema() throws QueryException {
try {
String schema;
DmdbConnection conn = (DmdbConnection) getMetaData().getConnection();
schema = conn.getUserName();
return schema;
} catch (SQLException e) {
throw ExceptionUtils.mpe(e);
}
}

/**
* 获取达梦数据库的schema
*
* @return {@link String} 达梦数据库的schema信息
*/
public String getSchemaBak() throws QueryException {
try {
String schema = null;
ResultSet rs = getMetaData().getSchemas();
while (rs.next()) {
schema = rs.getString(1);
break;
}
return schema;
} catch (Exception e) {
throw ExceptionUtils.mpe(e);
}
}

/**
Expand All @@ -64,21 +170,87 @@ public Database getDataBase() throws QueryException {
* @return {@link List} 所有表信息
*/
@Override
public List<Table> getTables() {
throw ExceptionUtils.mpe(NOT_SUPPORTED);
public List<DmTableModel> getTables() throws QueryException {
ResultSet resultSet = null;
try {
//查询
resultSet = getMetaData().getTables(getSchema(), getSchema(), PERCENT_SIGN,
new String[] { "TABLE" });
//映射
List<DmTableModel> list = Mapping.convertList(resultSet, DmTableModel.class);

resultSet = prepareStatement(DM_QUERY_TABLE_SQL).executeQuery();
List<DmTableModel> inquires = Mapping.convertList(resultSet, DmTableModel.class);

//处理备注信息
list.forEach((DmTableModel model) -> {
//备注
inquires.stream()
.filter(inquire -> model.getTableName().equals(inquire.getTableName()))
.forEachOrdered(inquire -> model.setRemarks(inquire.getRemarks()));
});
if (!list.isEmpty()) {
tablesMap.put("AllTable", list);
}
return list;
} catch (SQLException e) {
throw ExceptionUtils.mpe(e);
} finally {
JdbcUtils.close(resultSet, this.connection);
}
}

/**
* 获取列信息
*
* @param table {@link String} 表名
* @return {@link List} 表字段信息
* @throws QueryException QueryException
*/
@Override
public List<Column> getTableColumns(String table) throws QueryException {
public List<DmColumnModel> getTableColumns(String table) throws QueryException {
Assert.notEmpty(table, "Table name can not be empty!");
throw ExceptionUtils.mpe(NOT_SUPPORTED);
ResultSet resultSet = null;
List<DmColumnModel> resultList = new ArrayList<>();
List<String> tableNames = new ArrayList<>();
try {
//从缓存中获取表对象
List<DmTableModel> tables = tablesMap.get("AllTable");
if (tables.isEmpty()) {
tables = getTables();
} else {
for (DmTableModel dtm : tables) {
tableNames.add(dtm.getTableName());
}
}
/*如果表为空,则直接返回*/
if (tableNames.isEmpty()) {
return null;
}

if (CollectionUtils.isEmpty(columnsCaching)) {
//查询全部
if (table.equals(PERCENT_SIGN)) {
PreparedStatement statement = prepareStatement(DM_QUERY_COLUMNS_SQL);
resultSet = statement.executeQuery();
} else {
//查询单表的列信息
String singleTableSql = DM_QUERY_COLUMNS_SQL.concat(" and ut.table_name='%s'");
resultSet = prepareStatement(String.format(singleTableSql, table))
.executeQuery();
}

List<DmColumnModel> inquires = Mapping.convertList(resultSet, DmColumnModel.class);
//这里利用lambda表达式将多行列信息按table name 进行归类,并放入缓存
tableNames.forEach(name -> columnsCaching.put(name, inquires.stream()
.filter(i -> i.getTableName().equals(name)).collect(Collectors.toList())));
resultList = inquires;
}
return resultList;
} catch (SQLException e) {
throw ExceptionUtils.mpe(e);
} finally {
JdbcUtils.close(resultSet, this.connection);
}
}

/**
Expand All @@ -89,7 +261,7 @@ public List<Column> getTableColumns(String table) throws QueryException {
*/
@Override
public List<? extends Column> getTableColumns() throws QueryException {
throw ExceptionUtils.mpe(NOT_SUPPORTED);
return getTableColumns(PERCENT_SIGN);
}

/**
Expand All @@ -101,7 +273,37 @@ public List<? extends Column> getTableColumns() throws QueryException {
*/
@Override
public List<? extends PrimaryKey> getPrimaryKeys(String table) throws QueryException {
throw ExceptionUtils.mpe(NOT_SUPPORTED);
ResultSet resultSet = null;
try {
//查询
resultSet = getMetaData().getPrimaryKeys(getSchema(), getSchema(), table);
//映射
return Mapping.convertList(resultSet, DmPrimaryKeyModel.class);
} catch (SQLException e) {
throw ExceptionUtils.mpe(e);
} finally {
JdbcUtils.close(resultSet, this.connection);
}
}

/**
* 根据表名获取主键
*
* @return {@link List}
* @throws QueryException QueryException
*/
@Override
public List<? extends PrimaryKey> getPrimaryKeys() throws QueryException {
ResultSet resultSet = null;
try {
// 由于单条循环查询存在性能问题,所以这里通过自定义SQL查询数据库主键信息
String sql = String.format(DM_QUERY_PK_SQL, getSchema());
resultSet = prepareStatement(sql).executeQuery();
return Mapping.convertList(resultSet, DmPrimaryKeyModel.class);
} catch (SQLException e) {
throw new QueryException(e);
} finally {
JdbcUtils.close(resultSet);
}
}
}
Loading

0 comments on commit a622bdd

Please sign in to comment.