| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340 |
- package jnpf.base.service.impl;
- import com.google.common.collect.ImmutableMap;
- import jnpf.base.Page;
- import jnpf.base.Pagination;
- import jnpf.base.service.DbLinkService;
- import jnpf.base.service.DbTableService;
- import jnpf.base.util.dbutil.TableUtil;
- import jnpf.constant.MsgCode;
- import jnpf.database.datatype.db.DtDMEnum;
- import jnpf.database.datatype.db.interfaces.DtInterface;
- import jnpf.database.datatype.viewshow.ViewDataTypeEnum;
- import jnpf.database.datatype.viewshow.constant.DtViewConst;
- import jnpf.database.enums.DbAliasEnum;
- import jnpf.database.model.dbfield.DbFieldModel;
- import jnpf.database.model.dbtable.DbTableFieldModel;
- import jnpf.database.model.dto.PrepSqlDTO;
- import jnpf.database.model.entity.DbLinkEntity;
- import jnpf.database.model.page.DbTableDataForm;
- import jnpf.database.model.page.JdbcPageMod;
- import jnpf.database.source.DbBase;
- import jnpf.database.source.impl.DbPostgre;
- import jnpf.database.sql.enums.base.SqlComEnum;
- import jnpf.database.sql.util.SqlFastUtil;
- import jnpf.database.sql.util.SqlFrameUtil;
- import jnpf.database.util.DbTypeUtil;
- import jnpf.database.util.JdbcUtil;
- import jnpf.database.util.NotTenantPluginHolder;
- import jnpf.exception.DataException;
- import jnpf.util.StringUtil;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Service;
- import java.lang.reflect.Method;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.Map;
- import java.util.Optional;
- import java.util.stream.Collectors;
- /**
- * 数据管理
- *
- * @author JNPF开发平台组
- * @version V3.1.0
- * @copyright 引迈信息技术有限公司
- * @date 2019年9月27日 上午9:18
- */
- @Slf4j
- @Service
- public class DbTableServiceImpl implements DbTableService {
- @Autowired
- private DbLinkService dblinkService;
- @Autowired
- private DbTableService dbTableService;
- @Override
- public List<DbTableFieldModel> getList(String dbLinkId, String methodName) throws Exception {
- DbLinkEntity dbLinkEntity = dblinkService.getResource(dbLinkId);
- return SqlFastUtil.getTableList(dbLinkEntity, methodName);
- }
- @Override
- public List<DbTableFieldModel> getListPage(String dbLinkId, Page page) throws Exception {
- List<DbTableFieldModel> list = getList(dbLinkId, DbAliasEnum.TABLE_TYPE.getAlias());
- if(StringUtil.isNotEmpty(page.getKeyword())){
- // 过滤不符条件的元素
- String keyWord = SqlFrameUtil.keyWordTrim(page.getKeyword()).toLowerCase();
- list = list.stream().filter(t->
- (StringUtil.isNotEmpty(t.getComment()) && t.getComment().toLowerCase().contains(keyWord))
- || t.getTable().toLowerCase().contains(keyWord)
- ).collect(Collectors.toList());
- }
- return list;
- }
- @Override
- public List<DbTableFieldModel> getListPage(String dbLinkId, Pagination pagination) throws Exception {
- List<DbTableFieldModel> list = getList(dbLinkId, null);
- if(StringUtil.isNotEmpty(pagination.getKeyword())){
- // 过滤不符条件的元素
- String keyWord = SqlFrameUtil.keyWordTrim(pagination.getKeyword()).toLowerCase();
- list = list.stream().filter(t->
- (StringUtil.isNotEmpty(t.getComment()) && t.getComment().toLowerCase().contains(keyWord))
- || t.getTable().toLowerCase().contains(keyWord)
- ).collect(Collectors.toList());
- }
- long beginIndex = (pagination.getCurrentPage() -1) * pagination.getPageSize();
- long endIndex = beginIndex + pagination.getPageSize();
- List<DbTableFieldModel> listVO = new ArrayList<>();
- for (int i = 0; i < list.size(); i++) {
- if(beginIndex <= i && i < endIndex){
- listVO.add(list.get(i));
- }
- }
- pagination.setTotal(list.size());
- return listVO;
- }
- @Override
- public DbTableFieldModel getTable(String dbLinkId, String table) throws Exception {
- DbLinkEntity dbLinkEntity = dblinkService.getResource(dbLinkId);
- DbTableFieldModel dbTableFieldModel = SqlFastUtil.getTable(dbLinkEntity, table);
- dbTableFieldModel.setHasTableData(getSum(dbLinkId, table) > 0);
- return dbTableFieldModel;
- }
- @Override
- public List<DbFieldModel> getFieldList(String dbLinkId, String table) throws Exception {
- DbLinkEntity dbLinkEntity = dblinkService.getResource(dbLinkId);
- return SqlFastUtil.getFieldList(dbLinkEntity, table);
- }
- @Override
- public boolean isExistTable(String dbLinkId, String table) throws Exception {
- DbLinkEntity dbLinkEntity = dblinkService.getResource(dbLinkId);
- return SqlFastUtil.isExistTable(dbLinkEntity, table);
- }
- @Override
- public boolean dropExistsTable(String dbLinkId, String table) throws Exception {
- DbLinkEntity dbLinkEntity = dblinkService.getResource(dbLinkId);
- if(isExistTable(dbLinkId, table)){
- return SqlFastUtil.dropTable(dbLinkEntity, table);
- }
- return true;
- }
- @Override
- public List<Map<String, Object>> getData(DbTableDataForm dbTableDataForm, String dbLinkId, String table) throws Exception {
- DbLinkEntity dbLinkEntity = dblinkService.getResource(dbLinkId);
- JdbcPageMod result = new JdbcPageMod();
- String orderKey = dbTableDataForm.getField();
- // 防止SQL注入
- String finalOrderKey = orderKey;
- if(getFieldList(dbLinkId, table).stream().noneMatch(field -> field.getField().equals(finalOrderKey))){
- throw new DataException("排序字段不存在");
- }
- if (dbLinkEntity != null) {
- List<Object> dataList = new ArrayList<>();
- if(DbTypeUtil.checkPostgre(dbLinkEntity)){
- table = DbPostgre.getTable(table);
- orderKey = DbPostgre.getTable(orderKey);
- // String schema = dbLinkEntity.getDbSchema();
- // if(StringUtil.isNotEmpty(schema)){
- // table = schema + "." + table;
- // }
- }
- StringBuilder sql = new StringBuilder(SqlComEnum.SELECT_TABLE.getOutSql(table));
- //模糊查询
- if (!StringUtil.isEmpty(dbTableDataForm.getKeyword()) && !StringUtil.isEmpty(orderKey)) {
- sql.append(" where " + orderKey + " like ?");
- dataList.add("%" + SqlFrameUtil.keyWordTrim(dbTableDataForm.getKeyword()) + "%");
- }
- result = JdbcUtil.queryPage(
- new PrepSqlDTO(sql.toString(), dataList).withConn(dbLinkEntity),
- checkOrderKey(orderKey, dbLinkId, table, dbLinkEntity.getDbType()),
- (int) dbTableDataForm.getCurrentPage(),
- (int) dbTableDataForm.getPageSize())
- .setIsLowerCase(true).setIsAlias(true).get();
- }
- dbTableDataForm.setTotal(result.getTotalRecord());
- return (List<Map<String, Object>>)result.getDataList();
- }
- private String checkOrderKey(String orderKey, String dbLinkId, String table, String dbEncode){
- try {
- if(DbBase.DM.equals(dbEncode)){
- List<DbFieldModel> fieldList = getFieldList(dbLinkId, table);
- Optional<DbFieldModel> first = fieldList.stream().filter(field -> field.getField().equals(orderKey)).findFirst();
- if(first.isPresent()){
- String dataType = first.get().getDataType();
- if(dataType.equals(DtDMEnum.CLOB.getDataType()) || dataType.equals(DtDMEnum.TEXT.getDataType())){
- // throw new Exception("无法使用CLOB、TEXT作为字段排序条件");
- Optional<DbFieldModel> first1 = fieldList.stream().filter(field -> field.getField().toLowerCase().contains("id")).findFirst();
- if(first1.isPresent()){
- return first1.get().getField();
- }
- }
- }
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- return orderKey;
- }
- @Override
- public int getSum(String dbLinkId,String table)throws Exception {
- DbLinkEntity dbLinkEntity = dblinkService.getResource(dbLinkId);
- return SqlFastUtil.getSum(dbLinkEntity, table);
- }
- /**=====================增删改========================**/
- @Override
- public void delete(String dbLinkId, String table) throws Exception {
- // 校验
- checkTab(table, dbLinkId, 1);
- SqlFastUtil.dropTable(dblinkService.getResource(dbLinkId), table);
- }
- @Override
- public void deleteAllTable(String dbLinkId, String dbType) throws Exception {
- DbLinkEntity dbLinkEntity = dblinkService.getResource(dbLinkId);
- if(!dbLinkEntity.getDbType().equals(dbType)) throw new Exception("数据库类型不符");
- for (DbTableFieldModel dbTableFieldModel : SqlFastUtil.getTableList(dbLinkEntity)) {
- SqlFastUtil.dropTable(dbLinkEntity, dbTableFieldModel.getTable());
- }
- }
- @Override
- public int createTable(DbTableFieldModel dbTableFieldModel) throws Exception {
- DbLinkEntity dbLinkEntity = dblinkService.getResource(dbTableFieldModel.getDbLinkId());
- // 数据库编码查询校验 (打印模板校验)
- String opeDb = dbLinkEntity.getDbType();
- String creDb = dbTableFieldModel.getDbEncode();
- if(StringUtil.isNotEmpty(creDb) && !creDb.equals(opeDb)){
- throw new DataException(MsgCode.DB008.get() + ":" + creDb + " -> " + opeDb);
- }
- // 表重名判断
- if (isExistTable(dbTableFieldModel.getDbLinkId(), dbTableFieldModel.getTable())) {
- return 0;
- }
- // 表主键检验
- checkPrimary(dbTableFieldModel.getDbFieldModelList(), dbLinkEntity.getDbType());
- // 创建表
- SqlFastUtil.creTable(dbLinkEntity, dbTableFieldModel);
- return 1;
- }
- @Override
- public void update(DbTableFieldModel dbTableFieldModel) throws Exception {
- // 校验
- checkTab(dbTableFieldModel.getUpdateOldTable(), dbTableFieldModel.getDbLinkId(), 2);
- DbLinkEntity dbLinkEntity = dblinkService.getResource(dbTableFieldModel.getDbLinkId());
- //临时表名
- String oldTable = dbTableFieldModel.getUpdateOldTable();
- String newTable = dbTableFieldModel.getUpdateNewTable();
- String tempTabName = "Temp_" + TableUtil.getStringRandom(5);
- // 第一步:创建新表 (成功则删除旧表,失败则回滚)
- checkPrimary(dbTableFieldModel.getDbFieldModelList(), dbLinkEntity.getDbType());
- SqlFastUtil.creTable(dbLinkEntity,
- new DbTableFieldModel(
- tempTabName,
- dbTableFieldModel.getComment(),
- dbTableFieldModel.getDbFieldModelList()
- ));
- // 第二步:删除旧表
- SqlFastUtil.dropTable(dbLinkEntity, oldTable);
- // 第三步:新表改名
- SqlFastUtil.reTableName(dbLinkEntity, tempTabName, newTable);
- }
- @Override
- public void addField(DbTableFieldModel dbTableFieldModel) throws Exception {
- DbLinkEntity dbLinkEntity = dblinkService.getResource(dbTableFieldModel.getDbLinkId());
- SqlFastUtil.addField(dbLinkEntity, dbTableFieldModel.getUpdateNewTable(), dbTableFieldModel.getDbFieldModelList());
- }
- @Override
- public DbTableFieldModel getDbTableModel(String dbLinkId, String tableName)throws Exception {
- NotTenantPluginHolder.setNotSwitchFlag();
- DbTableFieldModel dbTableModel = getList(dbLinkId, null).stream().filter(m -> m.getTable().equals(tableName)).findFirst().orElse(null);
- if(dbTableModel != null){
- dbTableModel.setDbFieldModelList(getFieldList(dbLinkId, tableName));
- return dbTableModel;
- }else {
- throw new DataException("请在数据库中添加对应的数据表");
- }
- }
- /* ================复用代码================== */
- /**
- * 校验表可操作
- *
- * @param table 表
- * @param dbLinkId 数据连接ID
- * @param type 1:删除 2:编辑
- * @throws Exception 错误信息
- */
- private void checkTab(String table, String dbLinkId, Integer type) throws Exception {
- if (TableUtil.checkByoTable(table)) throw new DataException(type == 1 ? MsgCode.DB101.get() : MsgCode.DB102.get());
- if (getSum(dbLinkId, table) > 0) throw new DataException(type == 1 ? MsgCode.DB201.get() : MsgCode.DB202.get());
- }
- /**
- * 检查主键
- * @param tableFieldList 表字段集合
- * @throws DataException ignore
- */
- private void checkPrimary(List<DbFieldModel> tableFieldList, String dbEncode) throws Exception {
- // 默认主键为字符串类型
- // 主键会自动添加"非空"限制,所以不用做判断。(为空不加语句,且数据库默认字段可为空)
- int autoIncrementNum = 0;
- for(DbFieldModel field : tableFieldList) {
- if(field.getIsAutoIncrement() != null && field.getIsAutoIncrement()){
- field.setNullSign("NOT NULL");
- // 一张表最多只有一个自增主键,且此字段必须为primary key或者unique key。
- autoIncrementNum += 1;
- if(autoIncrementNum > 1){
- throw new DataException("一张表最多只运行有一个自增主键");
- }
- if(!(field.getDataType().equals(DtViewConst.INT) || field.getDataType().equals(DtViewConst.BIGINT))){
- throw new DataException("自增字段类型必须为数字类型");
- }
- if(!field.getIsPrimaryKey()){
- throw new DataException("自增字段类型必须为主键");
- }
- }else {
- if (field.getIsPrimaryKey()) {
- field.setNullSign("NOT NULL");
- Method method = ViewDataTypeEnum.class.getMethod("getDt" + dbEncode + "Enum");
- Map<ViewDataTypeEnum, String> allowDtMap = ImmutableMap.of(
- ViewDataTypeEnum.VARCHAR, DtViewConst.VARCHAR,
- ViewDataTypeEnum.INT, DtViewConst.INT,
- ViewDataTypeEnum.BIGINT, DtViewConst.BIGINT
- );
- boolean primaryFlag = false;
- for (Map.Entry<ViewDataTypeEnum, String> mapEntity : allowDtMap.entrySet()) {
- DtInterface primaryVarcharEnum = (DtInterface)(method.invoke(mapEntity.getKey()));
- boolean enumFlag = field.getDataType().equalsIgnoreCase(primaryVarcharEnum.getDataType());
- boolean viewFlag = field.getDataType().equalsIgnoreCase(mapEntity.getValue());
- if(enumFlag || viewFlag){
- primaryFlag = true;
- }
- }
- if(!primaryFlag){
- throw new DataException("主键必须为字符串或整型、长整型");
- }
- }
- }
- }
- }
- }
|