diff --git a/czsj-common/pom.xml b/czsj-common/pom.xml index e366902..80394a8 100644 --- a/czsj-common/pom.xml +++ b/czsj-common/pom.xml @@ -124,6 +124,108 @@ javax.servlet-api + + ch.ethz.ganymed + ganymed-ssh2 + build210 + + + + com.baomidou + mybatisplus-spring-boot-starter + 1.0.5 + + + com.baomidou + mybatis-plus-extension + 3.3.1 + compile + + + + org.projectlombok + lombok + 1.18.24 + compile + + + org.apache.commons + commons-lang3 + 3.3.2 + compile + + + commons-collections + commons-collections + 3.2.2 + compile + + + junit + junit + test + + + org.apache.commons + commons-lang3 + + + com.dtstack.dtcenter + common.loader.core + 1.8.0-RELEASE + + + cn.hutool + hutool-all + 4.5.1 + compile + + + com.czsj + czsj-core + 3.8.2 + compile + + + com.aspose + aspose-words + 20.3 + jdk17 + + + + com.zaxxer + HikariCP + 5.0.1 + + + + com.microsoft.sqlserver + mssql-jdbc + 12.8.0.jre11 + + + + + + + + + org.springframework.amqp + spring-rabbit + + + org.springframework + spring-webmvc + + + + + AsposeJavaAPI + Aspose Java API + https://releases.aspose.com/java/repo/ + + \ No newline at end of file diff --git a/czsj-common/src/main/java/com/czsj/common/database/DialectFactory.java b/czsj-common/src/main/java/com/czsj/common/database/DialectFactory.java new file mode 100644 index 0000000..3a8c313 --- /dev/null +++ b/czsj-common/src/main/java/com/czsj/common/database/DialectFactory.java @@ -0,0 +1,24 @@ +package com.czsj.common.database; + + + + +import com.czsj.common.database.constants.DbType; +import com.czsj.common.database.dialect.DialectRegistry; +import com.czsj.common.database.service.DbDialect; + + +/** + * 方言工厂类 + * + * @author yuwei + * @since 2020-03-14 + */ +public class DialectFactory { + + private static final DialectRegistry DIALECT_REGISTRY = new DialectRegistry(); + + public static DbDialect getDialect(DbType dbType) { + return DIALECT_REGISTRY.getDialect(dbType); + } +} diff --git a/czsj-common/src/main/java/com/czsj/common/database/cache/DefaultSqlCache.java b/czsj-common/src/main/java/com/czsj/common/database/cache/DefaultSqlCache.java new file mode 100644 index 0000000..f60758e --- /dev/null +++ b/czsj-common/src/main/java/com/czsj/common/database/cache/DefaultSqlCache.java @@ -0,0 +1,123 @@ +package com.czsj.common.database.cache; + +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +public class DefaultSqlCache extends LinkedHashMap> implements SqlCache { + + private int capacity; + + private long expire; + + private ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); + + public DefaultSqlCache(int capacity, long expire) { + super((int) Math.ceil(capacity / 0.75) + 1, 0.75f, true); + // 容量 + this.capacity = capacity; + // 固定过期时间 + this.expire = expire; + } + + @Override + public void put(String key, Object value, long ttl) { + long expireTime = Long.MAX_VALUE; + if (ttl >= 0) { + expireTime = System.currentTimeMillis() + (ttl == 0 ? this.expire : ttl); + } + lock.writeLock().lock(); + try { + // 封装成过期时间节点 + put(key, new ExpireNode<>(expireTime, value)); + } finally { + lock.writeLock().unlock(); + } + } + + @Override + public Object get(String key) { + lock.readLock().lock(); + ExpireNode expireNode; + try { + expireNode = super.get(key); + } finally { + lock.readLock().unlock(); + } + if (expireNode == null) { + return null; + } + // 惰性删除过期的 + if (this.expire > -1L && expireNode.expire < System.currentTimeMillis()) { + try { + lock.writeLock().lock(); + super.remove(key); + } finally { + lock.writeLock().unlock(); + } + return null; + } + return expireNode.value; + } + + @Override + public void delete(String key) { + try { + lock.writeLock().lock(); + Iterator>> iterator = super.entrySet().iterator(); + // 清除key的缓存 + while (iterator.hasNext()) { + Map.Entry> entry = iterator.next(); + if (entry.getKey().equals(key)) { + iterator.remove(); + } + } + } finally { + lock.writeLock().unlock(); + } + } + + + @Override + protected boolean removeEldestEntry(Map.Entry> eldest) { + if (this.expire > -1L && size() > capacity) { + clean(); + } + // lru淘汰 + return size() > this.capacity; + } + + /** + * 清理已过期的数据 + */ + private void clean() { + try { + lock.writeLock().lock(); + Iterator>> iterator = super.entrySet().iterator(); + long now = System.currentTimeMillis(); + while (iterator.hasNext()) { + Map.Entry> next = iterator.next(); + // 判断是否过期 + if (next.getValue().expire < now) { + iterator.remove(); + } + } + } finally { + lock.writeLock().unlock(); + } + } + + + /** + * 过期时间节点 + */ + static class ExpireNode { + long expire; + Object value; + public ExpireNode(long expire, Object value) { + this.expire = expire; + this.value = value; + } + } +} diff --git a/czsj-common/src/main/java/com/czsj/common/database/cache/SqlCache.java b/czsj-common/src/main/java/com/czsj/common/database/cache/SqlCache.java new file mode 100644 index 0000000..3444913 --- /dev/null +++ b/czsj-common/src/main/java/com/czsj/common/database/cache/SqlCache.java @@ -0,0 +1,39 @@ +package com.czsj.common.database.cache; + + +import com.czsj.common.database.utils.MD5Util; + +import java.util.Arrays; + +/** + * SQL缓存接口 + */ +public interface SqlCache { + + /** + * 计算key + */ + default String buildSqlCacheKey(String sql, Object[] args) { + return MD5Util.encrypt(sql + ":" + Arrays.toString(args)); + } + + /** + * 存入缓存 + * @param key key + * @param value 值 + */ + void put(String key, Object value, long ttl); + + /** + * 获取缓存 + * @param key key + * @return + */ + T get(String key); + + /** + * 删除缓存 + * @param key key + */ + void delete(String key); +} diff --git a/czsj-common/src/main/java/com/czsj/common/database/constants/DbQueryProperty.java b/czsj-common/src/main/java/com/czsj/common/database/constants/DbQueryProperty.java new file mode 100644 index 0000000..c077270 --- /dev/null +++ b/czsj-common/src/main/java/com/czsj/common/database/constants/DbQueryProperty.java @@ -0,0 +1,37 @@ +package com.czsj.common.database.constants; + + +import lombok.AllArgsConstructor; +import lombok.Data; +import org.springframework.util.StringUtils; + +import java.io.Serializable; + +@Data +@AllArgsConstructor +public class DbQueryProperty implements Serializable { + + private static final long serialVersionUID = 1L; + + private String dbType; + private String host; + private String username; + private String password; + private Integer port; + private String dbName; + private String sid; + + /** + * 参数合法性校验 + */ + public void viald() { + if (StringUtils.isEmpty(dbType) || StringUtils.isEmpty(host) || + StringUtils.isEmpty(username) || StringUtils.isEmpty(password) || + StringUtils.isEmpty(port)) { + throw new RuntimeException("参数不完整"); + } + if (DbType.OTHER.getDb().equals(dbType)) { + throw new RuntimeException("不支持的数据库类型"); + } + } +} diff --git a/czsj-common/src/main/java/com/czsj/common/database/constants/DbType.java b/czsj-common/src/main/java/com/czsj/common/database/constants/DbType.java new file mode 100644 index 0000000..a98a974 --- /dev/null +++ b/czsj-common/src/main/java/com/czsj/common/database/constants/DbType.java @@ -0,0 +1,100 @@ +package com.czsj.common.database.constants; + +/** + * 数据库类型 + * + * @author yuwei + * @since 2020-03-14 + */ +public enum DbType { + + /** + * MYSQL + */ + MYSQL("1", "MySql数据库", "jdbc:mysql://${host}:${port}/${dbName}?serverTimezone=GMT%2B8&characterEncoding=UTF-8&useUnicode=true&useSSL=false"), + /** + * MARIADB + */ + MARIADB("2", "MariaDB数据库", "jdbc:mariadb://${host}:${port}/${dbName}"), + /** + * ORACLE + */ + ORACLE("3", "Oracle11g及以下数据库", "jdbc:oracle:thin:@${host}:${port}:${sid}"), + /** + * oracle12c new pagination + */ + ORACLE_12C("4", "Oracle12c+数据库", "jdbc:oracle:thin:@${host}:${port}:${sid}"), + /** + * POSTGRESQL + */ + POSTGRE_SQL("5", "PostgreSql数据库", "jdbc:postgresql://${host}:${port}/${dbName}"), + /** + * SQLSERVER2005 + */ + SQL_SERVER2008("6", "SQLServer2008及以下数据库", "jdbc:sqlserver://${host}:${port};DatabaseName=${dbName}"), + /** + * SQLSERVER + */ + SQL_SERVER("7", "SQLServer2012+数据库", "jdbc:sqlserver://${host}:${port};DatabaseName=${dbName}"), + + /** + * UNKONWN DB + */ + OTHER("8", "其他数据库", ""), + /** + * CLICKHOUSE + */ + CLICKHOUSE("9", "Clickhouse数据库", "jdbc:clickhouse://${host}:${port}/${dbName}"), + /** + * HIVE + */ + HIVE("10", "Hive数据库", "jdbc:hive2://${host}:${port}/${dbName}"); + + + /** + * 数据库名称 + */ + private final String db; + + /** + * 描述 + */ + private final String desc; + + /** + * url + */ + private final String url; + + public String getDb() { + return this.db; + } + + public String getDesc() { + return this.desc; + } + + public String getUrl() { + return this.url; + } + + DbType(String db, String desc, String url) { + this.db = db; + this.desc = desc; + this.url = url; + } + + /** + * 获取数据库类型 + * + * @param dbType 数据库类型字符串 + */ + public static DbType getDbType(String dbType) { + for (DbType type : DbType.values()) { + if (type.db.equals(dbType)) { + return type; + } + } + return OTHER; + } +} diff --git a/czsj-common/src/main/java/com/czsj/common/database/datasource/AbstractDataSourceFactory.java b/czsj-common/src/main/java/com/czsj/common/database/datasource/AbstractDataSourceFactory.java new file mode 100644 index 0000000..f611dde --- /dev/null +++ b/czsj-common/src/main/java/com/czsj/common/database/datasource/AbstractDataSourceFactory.java @@ -0,0 +1,72 @@ +package com.czsj.common.database.datasource; + + +import com.czsj.common.database.DialectFactory; +import com.czsj.common.database.constants.DbQueryProperty; +import com.czsj.common.database.constants.DbType; +import com.czsj.common.database.query.AbstractDbQueryFactory; +import com.czsj.common.database.query.CacheDbQueryFactoryBean; +import com.czsj.common.database.service.DataSourceFactory; +import com.czsj.common.database.service.DbDialect; +import com.czsj.common.database.service.DbQuery; +import com.zaxxer.hikari.HikariDataSource; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; + +import javax.sql.DataSource; +import java.util.Properties; + +@Component +public class AbstractDataSourceFactory implements DataSourceFactory { + + + public DbQuery createDbQuery(DbQueryProperty property) { + property.viald(); + DbType dbType = DbType.getDbType(property.getDbType()); + DataSource dataSource = createDataSource(property); + DbQuery dbQuery = createDbQuery(dataSource, dbType); + return dbQuery; + } + + public static DbQuery createDbQuery(DataSource dataSource, DbType dbType) { + DbDialect dbDialect = DialectFactory.getDialect(dbType); + if(dbDialect == null){ + throw new RuntimeException("该数据库类型正在开发中"); + } + AbstractDbQueryFactory dbQuery = new CacheDbQueryFactoryBean(); + dbQuery.setDataSource(dataSource); + dbQuery.setJdbcTemplate(new JdbcTemplate(dataSource)); + dbQuery.setDbDialect(dbDialect); + return dbQuery; + } + + public DataSource createDataSource(DbQueryProperty property) { + HikariDataSource dataSource = new HikariDataSource(); + if(DbType.ORACLE_12C.getDb().equals(property.getDbType())){ + Properties properties = new Properties(); + properties.put("driverType","thin"); + dataSource.setDataSourceProperties(properties); + } + dataSource.setJdbcUrl(trainToJdbcUrl(property)); + dataSource.setUsername(property.getUsername()); + dataSource.setPassword(property.getPassword()); + return dataSource; + } + + protected String trainToJdbcUrl(DbQueryProperty property) { + String url = DbType.getDbType(property.getDbType()).getUrl(); + if (StringUtils.isEmpty(url)) { + throw new RuntimeException("无效数据库类型!"); + } + url = url.replace("${host}", property.getHost()); + url = url.replace("${port}", String.valueOf(property.getPort())); + if (DbType.ORACLE.getDb().equals(property.getDbType()) || DbType.ORACLE_12C.getDb().equals(property.getDbType())) { + url = url.replace("${sid}", property.getSid()); + } else { + url = url.replace("${dbName}", property.getDbName()); + } + return url; + } + +} diff --git a/czsj-common/src/main/java/com/czsj/common/database/datasource/CacheDataSourceFactoryBean.java b/czsj-common/src/main/java/com/czsj/common/database/datasource/CacheDataSourceFactoryBean.java new file mode 100644 index 0000000..7e538a2 --- /dev/null +++ b/czsj-common/src/main/java/com/czsj/common/database/datasource/CacheDataSourceFactoryBean.java @@ -0,0 +1,65 @@ +package com.czsj.common.database.datasource; + + + +import com.czsj.common.database.constants.DbQueryProperty; + +import javax.sql.DataSource; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +public class CacheDataSourceFactoryBean extends AbstractDataSourceFactory { + + /** + * 数据源缓存 + */ + private static Map dataSourceMap = new ConcurrentHashMap<>(); + + @Override + public DataSource createDataSource(DbQueryProperty property) { + String key = property.getHost() + ":" + property.getPort() + ":" + property.getUsername()+ ":" + property.getDbName(); + String s = compress(key); + DataSource dataSource = dataSourceMap.get(s); + if (null == dataSource) { + synchronized (CacheDataSourceFactoryBean.class) { + if (null == dataSource) { + dataSource = super.createDataSource(property); + dataSourceMap.put(s, dataSource); + } + } + } + return dataSource; + } + + // 压缩 + public static String compress(String str) { + if (str == null || str.length() == 0) { + return str; + } + MessageDigest md = null; + try { + md = MessageDigest.getInstance("MD5"); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } + md.update(str.getBytes()); + byte b[] = md.digest(); + int i; + StringBuffer buf = new StringBuffer(); + for (int offset = 0; offset < b.length; offset++) { + i = b[offset]; + if (i < 0) + i += 256; + if (i < 16) + buf.append("0"); + buf.append(Integer.toHexString(i)); + } +// System.out.println("MD5(" + str + ",32小写) = " + buf.toString()); +// System.out.println("MD5(" + str + ",32大写) = " + buf.toString().toUpperCase()); +// System.out.println("MD5(" + str + ",16小写) = " + buf.toString().substring(8, 24)); +// System.out.println("MD5(" + str + ",16大写) = " + buf.toString().substring(8, 24).toUpperCase()); + return buf.toString().substring(8, 24).toUpperCase(); + } +} diff --git a/czsj-common/src/main/java/com/czsj/common/database/datasource/DefaultDataSourceFactoryBean.java b/czsj-common/src/main/java/com/czsj/common/database/datasource/DefaultDataSourceFactoryBean.java new file mode 100644 index 0000000..4c07f86 --- /dev/null +++ b/czsj-common/src/main/java/com/czsj/common/database/datasource/DefaultDataSourceFactoryBean.java @@ -0,0 +1,4 @@ +package com.czsj.common.database.datasource; + +public class DefaultDataSourceFactoryBean extends AbstractDataSourceFactory { +} diff --git a/czsj-common/src/main/java/com/czsj/common/database/dialect/AbstractDbDialect.java b/czsj-common/src/main/java/com/czsj/common/database/dialect/AbstractDbDialect.java new file mode 100644 index 0000000..ba86c77 --- /dev/null +++ b/czsj-common/src/main/java/com/czsj/common/database/dialect/AbstractDbDialect.java @@ -0,0 +1,38 @@ +package com.czsj.common.database.dialect; + + +import com.czsj.common.database.service.DbDialect; + +/** + * 方言抽象类 + * + * @author yuwei + * @since 2020-03-14 + */ +public abstract class AbstractDbDialect implements DbDialect { + + @Override + public String columns(String dbName, String tableName) { + return "select column_name AS COLNAME, ordinal_position AS COLPOSITION, column_default AS DATADEFAULT, is_nullable AS NULLABLE, data_type AS DATATYPE, " + + "character_maximum_length AS DATALENGTH, numeric_precision AS DATAPRECISION, numeric_scale AS DATASCALE, column_key AS COLKEY, column_comment AS COLCOMMENT " + + "from information_schema.columns where table_schema = '" + dbName + "' and table_name = '" + tableName + "' order by ordinal_position "; + } + + @Override + public String tables(String dbName) { + return "SELECT table_name AS TABLENAME, table_comment AS TABLECOMMENT FROM information_schema.tables where table_schema = '" + dbName + "' "; + } + + @Override + public String buildPaginationSql(String originalSql, long offset, long count) { + // 获取 分页实际条数 + StringBuilder sqlBuilder = new StringBuilder(originalSql); + sqlBuilder.append(" LIMIT ").append(offset).append(" , ").append(count); + return sqlBuilder.toString(); + } + + @Override + public String count(String sql) { + return "SELECT COUNT(*) FROM ( " + sql + " ) TEMP"; + } +} diff --git a/czsj-common/src/main/java/com/czsj/common/database/dialect/CKAbstractDbDialect.java b/czsj-common/src/main/java/com/czsj/common/database/dialect/CKAbstractDbDialect.java new file mode 100644 index 0000000..71f6d74 --- /dev/null +++ b/czsj-common/src/main/java/com/czsj/common/database/dialect/CKAbstractDbDialect.java @@ -0,0 +1,36 @@ +package com.czsj.common.database.dialect; + + +import com.czsj.common.database.service.DbDialect; + +/** + * 方言抽象类 + * + * @author yuwei + * @since 2020-03-14 + */ +public abstract class CKAbstractDbDialect implements DbDialect { + + @Override + public String columns(String dbName, String tableName) { + return "select name COLNAME,type DATATYPE,'' DATALENGTH, '' DATAPRECISION,'' DATASCALE, is_in_primary_key COLKEY,'' NULLABLE,rowNumberInAllBlocks() COLPOSITION,default_expression DATADEFAULT,comment COLCOMMENT from system.columns where database = '" + dbName + "' and table = '" + tableName + "'"; + } + + @Override + public String tables(String dbName) { + return "SELECT name AS TABLENAME, '' AS TABLECOMMENT FROM system.tables where database = '" + dbName + "' "; + } + + @Override + public String buildPaginationSql(String originalSql, long offset, long count) { + // 获取 分页实际条数 + StringBuilder sqlBuilder = new StringBuilder(originalSql); + sqlBuilder.append(" LIMIT ").append(offset).append(" , ").append(count); + return sqlBuilder.toString(); + } + + @Override + public String count(String sql) { + return "SELECT COUNT(*) FROM ( " + sql + " ) TEMP"; + } +} diff --git a/czsj-common/src/main/java/com/czsj/common/database/dialect/ClickhouseDialect.java b/czsj-common/src/main/java/com/czsj/common/database/dialect/ClickhouseDialect.java new file mode 100644 index 0000000..5d6d77f --- /dev/null +++ b/czsj-common/src/main/java/com/czsj/common/database/dialect/ClickhouseDialect.java @@ -0,0 +1,45 @@ +package com.czsj.common.database.dialect; + + + +import com.czsj.core.database.core.DbColumn; +import com.czsj.core.database.core.DbTable; +import org.springframework.jdbc.core.RowMapper; + +import java.sql.ResultSet; + +/** + * clickhouse + * + * @author xinjingczsj + * @since 2023-05-30 + */ +public class ClickhouseDialect extends CKAbstractDbDialect { + + @Override + public RowMapper columnMapper() { + return (ResultSet rs, int rowNum) -> { + DbColumn entity = new DbColumn(); + entity.setColName(rs.getString("COLNAME")); + entity.setDataType(rs.getString("DATATYPE")); + entity.setDataLength(rs.getString("DATALENGTH")); + entity.setDataPrecision(rs.getString("DATAPRECISION")); + entity.setDataScale(rs.getString("DATASCALE")); + entity.setColKey("1".equals(rs.getString("COLKEY")) ? true : false); + entity.setNullable("Y".equals(rs.getString("NULLABLE")) ? true : false); + entity.setColPosition(rs.getInt("COLPOSITION")); + // entity.setDataDefault(rs.getString("DATADEFAULT")); + entity.setColComment(rs.getString("COLCOMMENT")); + return entity; + }; + } + @Override + public RowMapper tableMapper() { + return (ResultSet rs, int rowNum) -> { + DbTable entity = new DbTable(); + entity.setTableName(rs.getString("TABLENAME")); + entity.setTableComment(rs.getString("TABLECOMMENT")); + return entity; + }; + } +} diff --git a/czsj-common/src/main/java/com/czsj/common/database/dialect/DialectRegistry.java b/czsj-common/src/main/java/com/czsj/common/database/dialect/DialectRegistry.java new file mode 100644 index 0000000..e916615 --- /dev/null +++ b/czsj-common/src/main/java/com/czsj/common/database/dialect/DialectRegistry.java @@ -0,0 +1,30 @@ +package com.czsj.common.database.dialect; + + +import com.czsj.common.database.constants.DbType; +import com.czsj.common.database.service.DbDialect; + +import java.util.EnumMap; +import java.util.Map; + +public class DialectRegistry { + + private final Map dialect_enum_map = new EnumMap<>(DbType.class); + + public DialectRegistry() { + dialect_enum_map.put(DbType.MARIADB, new MariaDBDialect()); + dialect_enum_map.put(DbType.MYSQL, new MySqlDialect()); + dialect_enum_map.put(DbType.ORACLE_12C, new Oracle12cDialect()); + dialect_enum_map.put(DbType.ORACLE, new OracleDialect()); + dialect_enum_map.put(DbType.POSTGRE_SQL, new PostgreDialect()); + dialect_enum_map.put(DbType.SQL_SERVER2008, new SQLServer2008Dialect()); + dialect_enum_map.put(DbType.SQL_SERVER, new SQLServerDialect()); + dialect_enum_map.put(DbType.CLICKHOUSE, new ClickhouseDialect()); + dialect_enum_map.put(DbType.HIVE, new HiveDialect()); + dialect_enum_map.put(DbType.OTHER, new UnknownDialect()); + } + + public DbDialect getDialect(DbType dbType) { + return dialect_enum_map.get(dbType); + } +} diff --git a/czsj-common/src/main/java/com/czsj/common/database/dialect/HiveAbstractDbDialect.java b/czsj-common/src/main/java/com/czsj/common/database/dialect/HiveAbstractDbDialect.java new file mode 100644 index 0000000..34845db --- /dev/null +++ b/czsj-common/src/main/java/com/czsj/common/database/dialect/HiveAbstractDbDialect.java @@ -0,0 +1,36 @@ +package com.czsj.common.database.dialect; + + +import com.czsj.common.database.service.DbDialect; + +/** + * 方言抽象类 + * + * @author xinjingczsj + * @since 2023-08-14 + */ +public abstract class HiveAbstractDbDialect implements DbDialect { + + @Override + public String columns(String dbName, String tableName) { + return "desc "+dbName+"."+tableName; + } + + @Override + public String tables(String dbName) { + return "show tables in "+dbName; + } + + @Override + public String buildPaginationSql(String originalSql, long offset, long count) { + // 获取 分页实际条数 + StringBuilder sqlBuilder = new StringBuilder(originalSql); + sqlBuilder.append(" LIMIT ").append(offset).append(" , ").append(count); + return sqlBuilder.toString(); + } + + @Override + public String count(String sql) { + return "SELECT COUNT(1) FROM ( " + sql + " ) TEMP"; + } +} diff --git a/czsj-common/src/main/java/com/czsj/common/database/dialect/HiveDialect.java b/czsj-common/src/main/java/com/czsj/common/database/dialect/HiveDialect.java new file mode 100644 index 0000000..f0924e5 --- /dev/null +++ b/czsj-common/src/main/java/com/czsj/common/database/dialect/HiveDialect.java @@ -0,0 +1,30 @@ +package com.czsj.common.database.dialect; + + +import com.czsj.core.database.core.DbColumn; +import com.czsj.core.database.core.DbTable; +import org.springframework.jdbc.core.RowMapper; + +import java.sql.ResultSet; + +public class HiveDialect extends HiveAbstractDbDialect { + @Override + public RowMapper columnMapper() { + return (ResultSet rs, int rowNum) -> { + DbColumn entity = new DbColumn(); + entity.setColName(rs.getString("col_name")); + entity.setDataType(rs.getString("data_type")); + entity.setColComment(rs.getString("comment")); + return entity; + }; + } + + @Override + public RowMapper tableMapper() { + return (ResultSet rs, int rowNum) -> { + DbTable entity = new DbTable(); + entity.setTableName(rs.getString("tab_name")); + return entity; + }; + } +} diff --git a/czsj-common/src/main/java/com/czsj/common/database/dialect/MariaDBDialect.java b/czsj-common/src/main/java/com/czsj/common/database/dialect/MariaDBDialect.java new file mode 100644 index 0000000..2526c5e --- /dev/null +++ b/czsj-common/src/main/java/com/czsj/common/database/dialect/MariaDBDialect.java @@ -0,0 +1,10 @@ +package com.czsj.common.database.dialect; + +/** + * MariaDB 数据库方言 + * + * @author yuwei + * @since 2020-03-14 + */ +public class MariaDBDialect extends MySqlDialect { +} diff --git a/czsj-common/src/main/java/com/czsj/common/database/dialect/MySqlDialect.java b/czsj-common/src/main/java/com/czsj/common/database/dialect/MySqlDialect.java new file mode 100644 index 0000000..f96efb6 --- /dev/null +++ b/czsj-common/src/main/java/com/czsj/common/database/dialect/MySqlDialect.java @@ -0,0 +1,44 @@ +package com.czsj.common.database.dialect; + +import com.czsj.core.database.core.DbColumn; +import com.czsj.core.database.core.DbTable; +import org.springframework.jdbc.core.RowMapper; + +import java.sql.ResultSet; + +/** + * MySql 数据库方言 + * + * @author yuwei + * @since 2020-03-14 + */ +public class MySqlDialect extends AbstractDbDialect { + + @Override + public RowMapper columnMapper() { + return (ResultSet rs, int rowNum) -> { + DbColumn entity = new DbColumn(); + entity.setColName(rs.getString("COLNAME")); + entity.setDataType(rs.getString("DATATYPE")); + entity.setDataLength(rs.getString("DATALENGTH")); + entity.setDataPrecision(rs.getString("DATAPRECISION")); + entity.setDataScale(rs.getString("DATASCALE")); + entity.setColKey("PRI".equals(rs.getString("COLKEY")) ? true : false); + entity.setNullable("YES".equals(rs.getString("NULLABLE")) ? true : false); + entity.setColPosition(rs.getInt("COLPOSITION")); + entity.setDataDefault(rs.getString("DATADEFAULT")); + entity.setColComment(rs.getString("COLCOMMENT")); + return entity; + }; + } + + @Override + public RowMapper tableMapper() { + return (ResultSet rs, int rowNum) -> { + DbTable entity = new DbTable(); + entity.setTableName(rs.getString("TABLENAME")); + entity.setTableComment(rs.getString("TABLECOMMENT")); + return entity; + }; + } +} diff --git a/czsj-common/src/main/java/com/czsj/common/database/dialect/Oracle12cDialect.java b/czsj-common/src/main/java/com/czsj/common/database/dialect/Oracle12cDialect.java new file mode 100644 index 0000000..db3e28f --- /dev/null +++ b/czsj-common/src/main/java/com/czsj/common/database/dialect/Oracle12cDialect.java @@ -0,0 +1,17 @@ +package com.czsj.common.database.dialect; + +/** + * ORACLE Oracle12c+数据库方言 + * + * @author yuwei + * @since 2020-03-14 + */ +public class Oracle12cDialect extends OracleDialect { + + @Override + public String buildPaginationSql(String originalSql, long offset, long count) { + StringBuilder sqlBuilder = new StringBuilder(originalSql); + sqlBuilder.append(" OFFSET ").append(offset).append(" ROWS FETCH NEXT ").append(count).append(" ROWS ONLY "); + return sqlBuilder.toString(); + } +} diff --git a/czsj-common/src/main/java/com/czsj/common/database/dialect/OracleDialect.java b/czsj-common/src/main/java/com/czsj/common/database/dialect/OracleDialect.java new file mode 100644 index 0000000..161eb04 --- /dev/null +++ b/czsj-common/src/main/java/com/czsj/common/database/dialect/OracleDialect.java @@ -0,0 +1,74 @@ +package com.czsj.common.database.dialect; + + + +import com.czsj.core.database.core.DbColumn; +import com.czsj.core.database.core.DbTable; +import org.springframework.jdbc.core.RowMapper; + +import java.sql.ResultSet; + +/** + * Oracle Oracle11g及以下数据库方言 + * + * @author yuwei + * @since 2020-03-14 + */ +public class OracleDialect extends AbstractDbDialect { + + @Override + public String columns(String dbName, String tableName) { + return "select columns.column_name AS colName, columns.data_type AS DATATYPE, columns.data_length AS DATALENGTH, columns.data_precision AS DATAPRECISION, " + + "columns.data_scale AS DATASCALE, columns.nullable AS NULLABLE, columns.column_id AS COLPOSITION, columns.data_default AS DATADEFAULT, comments.comments AS COLCOMMENT," + + "case when t.column_name is null then 0 else 1 end as COLKEY " + + "from sys.user_tab_columns columns LEFT JOIN sys.user_col_comments comments ON columns.table_name = comments.table_name AND columns.column_name = comments.column_name " + + "left join ( " + + "select col.column_name as column_name, con.table_name as table_name from user_constraints con, user_cons_columns col " + + "where con.constraint_name = col.constraint_name and con.constraint_type = 'P' " + + ") t on t.table_name = columns.table_name and columns.column_name = t.column_name " + + "where columns.table_name = UPPER('" + tableName + "') order by columns.column_id "; + } + + @Override + public String tables(String dbName) { + return "select tables.table_name AS TABLENAME, comments.comments AS TABLECOMMENT from sys.user_tables tables " + + "LEFT JOIN sys.user_tab_comments comments ON tables.table_name = comments.table_name "; + } + + @Override + public String buildPaginationSql(String originalSql, long offset, long count) { + StringBuilder sqlBuilder = new StringBuilder(); + sqlBuilder.append("SELECT * FROM ( SELECT TMP.*, ROWNUM ROW_ID FROM ( "); + sqlBuilder.append(originalSql).append(" ) TMP WHERE ROWNUM <=").append((offset >= 1) ? (offset + count) : count); + sqlBuilder.append(") WHERE ROW_ID > ").append(offset); + return sqlBuilder.toString(); + } + + @Override + public RowMapper columnMapper() { + return (ResultSet rs, int rowNum) -> { + DbColumn entity = new DbColumn(); + entity.setColName(rs.getString("COLNAME")); + entity.setDataType(rs.getString("DATATYPE")); + entity.setDataLength(rs.getString("DATALENGTH")); + entity.setDataPrecision(rs.getString("DATAPRECISION")); + entity.setDataScale(rs.getString("DATASCALE")); + entity.setColKey("1".equals(rs.getString("COLKEY")) ? true : false); + entity.setNullable("Y".equals(rs.getString("NULLABLE")) ? true : false); + entity.setColPosition(rs.getInt("COLPOSITION")); + // entity.setDataDefault(rs.getString("DATADEFAULT")); + entity.setColComment(rs.getString("COLCOMMENT")); + return entity; + }; + } + + @Override + public RowMapper tableMapper() { + return (ResultSet rs, int rowNum) -> { + DbTable entity = new DbTable(); + entity.setTableName(rs.getString("TABLENAME")); + entity.setTableComment(rs.getString("TABLECOMMENT")); + return entity; + }; + } +} diff --git a/czsj-common/src/main/java/com/czsj/common/database/dialect/PostgreDialect.java b/czsj-common/src/main/java/com/czsj/common/database/dialect/PostgreDialect.java new file mode 100644 index 0000000..1818faf --- /dev/null +++ b/czsj-common/src/main/java/com/czsj/common/database/dialect/PostgreDialect.java @@ -0,0 +1,72 @@ +package com.czsj.common.database.dialect; + + +import com.czsj.core.database.core.DbColumn; +import com.czsj.core.database.core.DbTable; +import org.springframework.jdbc.core.RowMapper; + +import java.sql.ResultSet; + +/** + * Postgre 数据库方言 + * + * @author yuwei + * @since 2020-03-14 + */ +public class PostgreDialect extends AbstractDbDialect { + + @Override + public String columns(String dbName, String tableName) { + return "select col.column_name AS COLNAME, col.ordinal_position AS COLPOSITION, col.column_default AS DATADEFAULT, col.is_nullable AS NULLABLE, col.udt_name AS DATATYPE, " + + "col.character_maximum_length AS DATALENGTH, col.numeric_precision AS DATAPRECISION, col.numeric_scale AS DATASCALE, des.description AS COLCOMMENT, " + + "case when t.colname is null then 0 else 1 end as COLKEY " + + "from information_schema.columns col left join pg_description des on col.table_name::regclass = des.objoid and col.ordinal_position = des.objsubid " + + "left join ( " + + "select pg_attribute.attname as colname from pg_constraint inner join pg_class on pg_constraint.conrelid = pg_class.oid " + + "inner join pg_attribute on pg_attribute.attrelid = pg_class.oid and pg_attribute.attnum = any(pg_constraint.conkey) " + + "where pg_class.relname = '" + tableName + "' and pg_constraint.contype = 'p' " + + ") t on t.colname = col.column_name " + + "where col.table_catalog = '" + dbName + "' and col.table_schema = 'public' and col.table_name = '" + tableName + "' order by col.ordinal_position "; + } + + @Override + public String tables(String dbName) { + return "select relname AS TABLENAME, cast(obj_description(relfilenode, 'pg_class') as varchar) AS TABLECOMMENT from pg_class " + + "where relname in (select tablename from pg_tables where schemaname = 'public' and tableowner = '" + dbName + "' and position('_2' in tablename) = 0) "; + } + + @Override + public String buildPaginationSql(String originalSql, long offset, long count) { + StringBuilder sqlBuilder = new StringBuilder(originalSql); + sqlBuilder.append(" LIMIT ").append(count).append(" offset ").append(offset); + return sqlBuilder.toString(); + } + + @Override + public RowMapper columnMapper() { + return (ResultSet rs, int rowNum) -> { + DbColumn entity = new DbColumn(); + entity.setColName(rs.getString("COLNAME")); + entity.setDataType(rs.getString("DATATYPE")); + entity.setDataLength(rs.getString("DATALENGTH")); + entity.setDataPrecision(rs.getString("DATAPRECISION")); + entity.setDataScale(rs.getString("DATASCALE")); + entity.setColKey("1".equals(rs.getString("COLKEY")) ? true : false); + entity.setNullable("YES".equals(rs.getString("NULLABLE")) ? true : false); + entity.setColPosition(rs.getInt("COLPOSITION")); + entity.setDataDefault(rs.getString("DATADEFAULT")); + entity.setColComment(rs.getString("COLCOMMENT")); + return entity; + }; + } + + @Override + public RowMapper tableMapper() { + return (ResultSet rs, int rowNum) -> { + DbTable entity = new DbTable(); + entity.setTableName(rs.getString("TABLENAME")); + entity.setTableComment(rs.getString("TABLECOMMENT")); + return entity; + }; + } +} diff --git a/czsj-common/src/main/java/com/czsj/common/database/dialect/SQLServer2008Dialect.java b/czsj-common/src/main/java/com/czsj/common/database/dialect/SQLServer2008Dialect.java new file mode 100644 index 0000000..56f12f6 --- /dev/null +++ b/czsj-common/src/main/java/com/czsj/common/database/dialect/SQLServer2008Dialect.java @@ -0,0 +1,106 @@ +package com.czsj.common.database.dialect; + + +import com.czsj.core.database.core.DbColumn; +import com.czsj.core.database.core.DbTable; +import org.springframework.jdbc.core.RowMapper; +import org.springframework.util.StringUtils; + +import java.sql.ResultSet; + +/** + * SQLServer 2005 数据库方言 + * + * @author yuwei + * @since 2020-03-14 + */ +public class SQLServer2008Dialect extends AbstractDbDialect { + + @Override + public String columns(String dbName, String tableName) { + return "select columns.name AS colName, columns.column_id AS COLPOSITION, columns.max_length AS DATALENGTH, columns.precision AS DATAPRECISION, columns.scale AS DATASCALE, " + + "columns.is_nullable AS NULLABLE, types.name AS DATATYPE, CAST(ep.value AS NVARCHAR(128)) AS COLCOMMENT, e.text AS DATADEFAULT, " + + "(select top 1 ind.is_primary_key from sys.index_columns ic left join sys.indexes ind on ic.object_id = ind.object_id and ic.index_id = ind.index_id and ind.name like 'PK_%' where ic.object_id=columns.object_id and ic.column_id=columns.column_id) AS COLKEY " + + "from sys.columns columns LEFT JOIN sys.types types ON columns.system_type_id = types.system_type_id " + + "LEFT JOIN syscomments e ON columns.default_object_id= e.id " + + "LEFT JOIN sys.extended_properties ep ON ep.major_id = columns.object_id AND ep.minor_id = columns.column_id AND ep.name = 'MS_Description' " + + "where columns.object_id = object_id('" + tableName + "') order by columns.column_id "; + } + + @Override + public String tables(String dbName) { + return "select tables.name AS TABLENAME, CAST(ep.value AS NVARCHAR(128)) AS TABLECOMMENT " + + "from sys.tables tables LEFT JOIN sys.extended_properties ep ON ep.major_id = tables.object_id AND ep.minor_id = 0"; + } + + private static String getOrderByPart(String sql) { + String loweredString = sql.toLowerCase(); + int orderByIndex = loweredString.indexOf("order by"); + if (orderByIndex != -1) { + return sql.substring(orderByIndex); + } else { + return ""; + } + } + + @Override + public String buildPaginationSql(String originalSql, long offset, long count) { + StringBuilder pagingBuilder = new StringBuilder(); + String orderby = getOrderByPart(originalSql); + String distinctStr = ""; + + String loweredString = originalSql.toLowerCase(); + String sqlPartString = originalSql; + if (loweredString.trim().startsWith("select")) { + int index = 6; + if (loweredString.startsWith("select distinct")) { + distinctStr = "DISTINCT "; + index = 15; + } + sqlPartString = sqlPartString.substring(index); + } + pagingBuilder.append(sqlPartString); + + // if no ORDER BY is specified use fake ORDER BY field to avoid errors + if (StringUtils.isEmpty(orderby)) { + orderby = "ORDER BY CURRENT_TIMESTAMP"; + } + StringBuilder sql = new StringBuilder(); + sql.append("WITH selectTemp AS (SELECT ").append(distinctStr).append("TOP 100 PERCENT ") + .append(" ROW_NUMBER() OVER (").append(orderby).append(") as __row_number__, ").append(pagingBuilder) + .append(") SELECT * FROM selectTemp WHERE __row_number__ BETWEEN ") + //FIX#299:原因:mysql中limit 10(offset,size) 是从第10开始(不包含10),;而这里用的BETWEEN是两边都包含,所以改为offset+1 + .append(offset + 1) + .append(" AND ") + .append(offset + count).append(" ORDER BY __row_number__"); + return sql.toString(); + } + + @Override + public RowMapper columnMapper() { + return (ResultSet rs, int rowNum) -> { + DbColumn entity = new DbColumn(); + entity.setColName(rs.getString("COLNAME")); + entity.setDataType(rs.getString("DATATYPE")); + entity.setDataLength(rs.getString("DATALENGTH")); + entity.setDataPrecision(rs.getString("DATAPRECISION")); + entity.setDataScale(rs.getString("DATASCALE")); + entity.setColKey("1".equals(rs.getString("COLKEY")) ? true : false); + entity.setNullable("1".equals(rs.getString("NULLABLE")) ? true : false); + entity.setColPosition(rs.getInt("COLPOSITION")); + entity.setDataDefault(rs.getString("DATADEFAULT")); + entity.setColComment(rs.getString("COLCOMMENT")); + return entity; + }; + } + + @Override + public RowMapper tableMapper() { + return (ResultSet rs, int rowNum) -> { + DbTable entity = new DbTable(); + entity.setTableName(rs.getString("TABLENAME")); + entity.setTableComment(rs.getString("TABLECOMMENT")); + return entity; + }; + } +} diff --git a/czsj-common/src/main/java/com/czsj/common/database/dialect/SQLServerDialect.java b/czsj-common/src/main/java/com/czsj/common/database/dialect/SQLServerDialect.java new file mode 100644 index 0000000..c65c408 --- /dev/null +++ b/czsj-common/src/main/java/com/czsj/common/database/dialect/SQLServerDialect.java @@ -0,0 +1,17 @@ +package com.czsj.common.database.dialect; + +/** + * SQLServer 数据库方言 + * + * @author yuwei + * @since 2020-03-14 + */ +public class SQLServerDialect extends SQLServer2008Dialect { + + @Override + public String buildPaginationSql(String originalSql, long offset, long count) { + StringBuilder sqlBuilder = new StringBuilder(originalSql); + sqlBuilder.append(" OFFSET ").append(offset).append(" ROWS FETCH NEXT ").append(count).append(" ROWS ONLY "); + return sqlBuilder.toString(); + } +} diff --git a/czsj-common/src/main/java/com/czsj/common/database/dialect/UnknownDialect.java b/czsj-common/src/main/java/com/czsj/common/database/dialect/UnknownDialect.java new file mode 100644 index 0000000..799b70f --- /dev/null +++ b/czsj-common/src/main/java/com/czsj/common/database/dialect/UnknownDialect.java @@ -0,0 +1,45 @@ +package com.czsj.common.database.dialect; + + +import com.czsj.core.database.core.DbColumn; +import com.czsj.core.database.core.DbTable; +import org.springframework.jdbc.core.RowMapper; + +/** + * 未知 数据库方言 + * + * @author yuwei + * @since 2020-03-14 + */ +public class UnknownDialect extends AbstractDbDialect { + + @Override + public String columns(String dbName, String tableName) { + throw new RuntimeException("不支持的数据库类型"); + } + + @Override + public String tables(String dbName) { + throw new RuntimeException("不支持的数据库类型"); + } + + @Override + public String buildPaginationSql(String sql, long offset, long count) { + throw new RuntimeException("不支持的数据库类型"); + } + + @Override + public String count(String sql) { + throw new RuntimeException("不支持的数据库类型"); + } + + @Override + public RowMapper columnMapper() { + throw new RuntimeException("不支持的数据库类型"); + } + + @Override + public RowMapper tableMapper() { + throw new RuntimeException("不支持的数据库类型"); + } +} diff --git a/czsj-common/src/main/java/com/czsj/common/database/query/AbstractDbQueryFactory.java b/czsj-common/src/main/java/com/czsj/common/database/query/AbstractDbQueryFactory.java new file mode 100644 index 0000000..d0d2cc7 --- /dev/null +++ b/czsj-common/src/main/java/com/czsj/common/database/query/AbstractDbQueryFactory.java @@ -0,0 +1,128 @@ +package com.czsj.common.database.query; + +import com.czsj.common.database.service.DbDialect; +import com.czsj.common.database.service.DbQuery; +import com.czsj.core.database.core.DbColumn; +import com.czsj.core.database.core.DbTable; +import com.czsj.core.database.core.PageResult; +import com.zaxxer.hikari.HikariDataSource; +import lombok.Setter; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; + +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.SQLException; +import java.util.List; +import java.util.Map; + +@Setter +public abstract class AbstractDbQueryFactory implements DbQuery { + + protected DataSource dataSource; + + protected JdbcTemplate jdbcTemplate; + + protected DbDialect dbDialect; + + @Override + public Connection getConnection() { + try { + return dataSource.getConnection(); + } catch (SQLException e) { + throw new RuntimeException("获取数据库连接出错"); + } + } + + @Override + public boolean valid() { + Connection conn = null; + try { + conn = dataSource.getConnection(); + return conn.isValid(0); + } catch (SQLException e) { + throw new RuntimeException("检测连通性出错"); + } finally { + if (conn != null) { + try { + conn.close(); + } catch (SQLException e) { + throw new RuntimeException("关闭数据库连接出错"); + } + } + } + + } + + @Override + public void close() { + if (dataSource instanceof HikariDataSource) { + ((HikariDataSource) dataSource).close(); + } else { + throw new RuntimeException("不合法数据源类型"); + } + } + + @Override + public List getTableColumns(String dbName, String tableName) { + String sql = dbDialect.columns(dbName, tableName); + return jdbcTemplate.query(sql, dbDialect.columnMapper()); + } + + @Override + public List getTables(String dbName) { + String sql = dbDialect.tables(dbName); + return jdbcTemplate.query(sql, dbDialect.tableMapper()); + } + + @Override + public int count(String sql) { + return jdbcTemplate.queryForObject(dbDialect.count(sql), Integer.class); + } + + @Override + public int count(String sql, Object[] args) { + return jdbcTemplate.queryForObject(dbDialect.count(sql), args, Integer.class); + } + + @Override + public int count(String sql, Map params) { + NamedParameterJdbcTemplate namedJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate); + return namedJdbcTemplate.queryForObject(dbDialect.count(sql), params, Integer.class); + } + + @Override + public List> queryList(String sql) { + return jdbcTemplate.queryForList(sql); + } + + @Override + public List> queryList(String sql, Object[] args) { + return jdbcTemplate.queryForList(sql, args); + } + + @Override + public PageResult> queryByPage(String sql, long offset, long size) { + int total = count(sql); + String pageSql = dbDialect.buildPaginationSql(sql, offset, size); + List> records = jdbcTemplate.queryForList(pageSql); + return new PageResult<>(total, records); + } + + @Override + public PageResult> queryByPage(String sql, Object[] args, long offset, long size) { + int total = count(sql, args); + String pageSql = dbDialect.buildPaginationSql(sql, offset, size); + List> records = jdbcTemplate.queryForList(pageSql, args); + return new PageResult<>(total, records); + } + + @Override + public PageResult> queryByPage(String sql, Map params, long offset, long size) { + int total = count(sql, params); + String pageSql = dbDialect.buildPaginationSql(sql, offset, size); + NamedParameterJdbcTemplate namedJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate); + List> records = namedJdbcTemplate.queryForList(pageSql, params); + return new PageResult<>(total, records); + } +} diff --git a/czsj-common/src/main/java/com/czsj/common/database/query/CacheDbQueryFactoryBean.java b/czsj-common/src/main/java/com/czsj/common/database/query/CacheDbQueryFactoryBean.java new file mode 100644 index 0000000..cb0a45e --- /dev/null +++ b/czsj-common/src/main/java/com/czsj/common/database/query/CacheDbQueryFactoryBean.java @@ -0,0 +1,105 @@ +package com.czsj.common.database.query; + + +import com.czsj.common.database.cache.DefaultSqlCache; +import com.czsj.core.database.core.DbColumn; +import com.czsj.core.database.core.DbTable; +import com.czsj.core.database.core.PageResult; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +public class CacheDbQueryFactoryBean extends AbstractDbQueryFactory { + + /** + * 默认缓存5分钟 + */ + private static long DEFAULT_EXPIRE = 5 * 60 * 1000; + private static DefaultSqlCache sqlCache = new DefaultSqlCache(100, DEFAULT_EXPIRE); + + private T putCacheValue(String key, T value, long ttl) { + sqlCache.put(key, value, ttl); + return value; + } + + @Override + public List getTableColumns(String dbName, String tableName) { + Object[] args = new Object[]{dbName, tableName}; + Optional.ofNullable(sqlCache.get(sqlCache.buildSqlCacheKey(super.dataSource.toString() + ":getTableColumns", args))); + return super.getTableColumns(dbName, tableName); + } + + @Override + public List getTables(String dbName) { + Object[] args = new Object[]{dbName}; + String cacheKey = sqlCache.buildSqlCacheKey(super.dataSource.toString() + ":getTables", args); + return (List) Optional.ofNullable(sqlCache.get(cacheKey)) + .orElse(putCacheValue(cacheKey, super.getTables(dbName), DEFAULT_EXPIRE)); + } + + @Override + public int count(String sql) { + String cacheKey = sqlCache.buildSqlCacheKey(super.dataSource.toString() + ":" + sql, null); + return (int) Optional.ofNullable(sqlCache.get(cacheKey)) + .orElse(putCacheValue(cacheKey, super.count(sql), DEFAULT_EXPIRE)); + } + + @Override + public int count(String sql, Object[] args) { + String cacheKey = sqlCache.buildSqlCacheKey(super.dataSource.toString() + ":" + sql, args); + return (int) Optional.ofNullable(sqlCache.get(cacheKey)) + .orElse(putCacheValue(cacheKey, super.count(sql, args), DEFAULT_EXPIRE)); + } + + @Override + public int count(String sql, Map params) { + String cacheKey = sqlCache.buildSqlCacheKey(super.dataSource.toString() + ":" + sql, params.values().toArray()); + return (int) Optional.ofNullable(sqlCache.get(cacheKey)) + .orElse(putCacheValue(cacheKey, super.count(sql, params), DEFAULT_EXPIRE)); + } + + @Override + public List> queryList(String sql) { + String cacheKey = sqlCache.buildSqlCacheKey(super.dataSource.toString() + ":" + sql, null); + return (List>) Optional.ofNullable(sqlCache.get(cacheKey)) + .orElse(putCacheValue(cacheKey, super.queryList(sql), DEFAULT_EXPIRE)); + } + + @Override + public List> queryList(String sql, Object[] args) { + String cacheKey = sqlCache.buildSqlCacheKey(super.dataSource.toString() + ":" + sql, args); + return (List>) Optional.ofNullable(sqlCache.get(cacheKey)) + .orElse(putCacheValue(cacheKey, super.queryList(sql, args), DEFAULT_EXPIRE)); + } + + @Override + public PageResult> queryByPage(String sql, long offset, long size) { + Object[] args = new Object[]{offset, size}; + String cacheKey = sqlCache.buildSqlCacheKey(super.dataSource.toString() + ":" + sql, args); + return (PageResult>) Optional.ofNullable(sqlCache.get(cacheKey)) + .orElse(putCacheValue(cacheKey, super.queryByPage(sql, offset, size), DEFAULT_EXPIRE)); + } + + @Override + public PageResult> queryByPage(String sql, Object[] args, long offset, long size) { + Object[] objects = Arrays.copyOf(args, args.length + 2); + objects[args.length] = offset; + objects[args.length + 1] = size; + String cacheKey = sqlCache.buildSqlCacheKey(super.dataSource.toString() + ":" + sql, objects); + return (PageResult>) Optional.ofNullable(sqlCache.get(cacheKey)) + .orElse(putCacheValue(cacheKey, super.queryByPage(sql, args, offset, size), DEFAULT_EXPIRE)); + } + + @Override + public PageResult> queryByPage(String sql, Map params, long offset, long size) { + Object[] args = params.values().toArray(); + Object[] objects = Arrays.copyOf(args, args.length + 2); + objects[args.length] = offset; + objects[args.length + 1] = size; + String cacheKey = sqlCache.buildSqlCacheKey(super.dataSource.toString() + ":" + sql, objects); + return (PageResult>) Optional.ofNullable(sqlCache.get(cacheKey)) + .orElse(putCacheValue(cacheKey, super.queryByPage(sql, params, offset, size), DEFAULT_EXPIRE)); + } +} diff --git a/czsj-common/src/main/java/com/czsj/common/database/query/DefaultDbQueryFactoryBean.java b/czsj-common/src/main/java/com/czsj/common/database/query/DefaultDbQueryFactoryBean.java new file mode 100644 index 0000000..61822fd --- /dev/null +++ b/czsj-common/src/main/java/com/czsj/common/database/query/DefaultDbQueryFactoryBean.java @@ -0,0 +1,5 @@ +package com.czsj.common.database.query; + +public class DefaultDbQueryFactoryBean extends AbstractDbQueryFactory { + +} diff --git a/czsj-common/src/main/java/com/czsj/common/database/service/DataSourceFactory.java b/czsj-common/src/main/java/com/czsj/common/database/service/DataSourceFactory.java new file mode 100644 index 0000000..7732862 --- /dev/null +++ b/czsj-common/src/main/java/com/czsj/common/database/service/DataSourceFactory.java @@ -0,0 +1,15 @@ +package com.czsj.common.database.service; + + +import com.czsj.common.database.constants.DbQueryProperty; + +public interface DataSourceFactory { + + /** + * 创建数据源实例 + * + * @param property + * @return + */ + public DbQuery createDbQuery(DbQueryProperty property); +} diff --git a/czsj-common/src/main/java/com/czsj/common/database/service/DbDialect.java b/czsj-common/src/main/java/com/czsj/common/database/service/DbDialect.java new file mode 100644 index 0000000..f126d66 --- /dev/null +++ b/czsj-common/src/main/java/com/czsj/common/database/service/DbDialect.java @@ -0,0 +1,55 @@ +package com.czsj.common.database.service; + + + +import com.czsj.core.database.core.DbColumn; +import com.czsj.core.database.core.DbTable; +import org.springframework.jdbc.core.RowMapper; + +/** + * 表数据查询接口 + * + * @author yuwei + * @since 2020-03-14 + */ +public interface DbDialect { + + RowMapper tableMapper(); + + RowMapper columnMapper(); + + /** + * 获取指定表的所有列 + * + * @param dbName + * @param tableName + * @return + */ + String columns(String dbName, String tableName); + + /** + * 获取数据库下的 所有表 + * + * @param dbName + * @return + */ + String tables(String dbName); + + /** + * 构建 分页 sql + * + * @param sql + * @param offset + * @param count + * @return + */ + String buildPaginationSql(String sql, long offset, long count); + + /** + * 包装 count sql + * + * @param sql + * @return + */ + String count(String sql); +} diff --git a/czsj-common/src/main/java/com/czsj/common/database/service/DbQuery.java b/czsj-common/src/main/java/com/czsj/common/database/service/DbQuery.java new file mode 100644 index 0000000..34029f5 --- /dev/null +++ b/czsj-common/src/main/java/com/czsj/common/database/service/DbQuery.java @@ -0,0 +1,123 @@ +package com.czsj.common.database.service; + + + + +import com.czsj.core.database.core.DbColumn; +import com.czsj.core.database.core.DbTable; +import com.czsj.core.database.core.PageResult; + +import java.sql.Connection; +import java.util.List; +import java.util.Map; + +/** + * 表数据查询接口 + * + * @author yuwei + * @since 2020-03-14 + */ +public interface DbQuery { + + /** + * 获取数据库连接 + */ + Connection getConnection(); + + /** + * 检测连通性 + */ + boolean valid(); + + /** + * 关闭数据源 + */ + void close(); + + /** + * 获取指定表 具有的所有字段列表 + * @param dbName + * @param tableName + * @return + */ + List getTableColumns(String dbName, String tableName); + + /** + * 获取指定数据库下 所有的表信息 + * + * @param dbName + * @return + */ + List getTables(String dbName); + + /** + * 获取总数 + * + * @param sql + * @return + */ + int count(String sql); + + /** + * 获取总数带查询参数 + * + * @param sql + * @return + */ + int count(String sql, Object[] args); + + /** + * 获取总数带查询参数 NamedParameterJdbcTemplate + * + * @param sql + * @return + */ + int count(String sql, Map params); + + /** + * 查询结果列表 + * + * @param sql + * @return + */ + List> queryList(String sql); + + /** + * 查询结果列表带查询参数 + * + * @param sql + * @param args + * @return + */ + List> queryList(String sql, Object[] args); + + /** + * 查询结果分页 + * + * @param sql + * @param offset + * @param size + * @return + */ + PageResult> queryByPage(String sql, long offset, long size); + + /** + * 查询结果分页带查询参数 + * @param sql + * @param args + * @param offset + * @param size + * @return + */ + PageResult> queryByPage(String sql, Object[] args, long offset, long size); + + /** + * 查询结果分页带查询参数 NamedParameterJdbcTemplate + * @param sql + * @param params + * @param offset + * @param size + * @return + */ + PageResult> queryByPage(String sql, Map params, long offset, long size); +} diff --git a/czsj-common/src/main/java/com/czsj/common/database/utils/MD5Util.java b/czsj-common/src/main/java/com/czsj/common/database/utils/MD5Util.java new file mode 100644 index 0000000..f12501f --- /dev/null +++ b/czsj-common/src/main/java/com/czsj/common/database/utils/MD5Util.java @@ -0,0 +1,46 @@ +package com.czsj.common.database.utils; + +import java.security.MessageDigest; +import java.util.Arrays; + +public class MD5Util { + + public static void main(String[] args) throws InterruptedException { + Object[] arr = new Object[]{"dbName"}; + Object[] objects = Arrays.copyOf(arr, arr.length + 2); + System.out.println(objects.length); + int length = arr.length; + objects[length] = 1; + objects[length+1] = 2; + System.out.println(Arrays.toString(objects)); +// String encrypt = MD5Util.encrypt("sql" + ":" + Arrays.toString(arr)); +// System.out.println(encrypt); + } + + private static final char[] HEX_CHARS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; + + /** + * MD5加密 + */ + public static String encrypt(String value){ + return encrypt(value.getBytes()); + } + + /** + * MD5加密 + */ + public static String encrypt(byte[] value){ + try { + byte[] bytes = MessageDigest.getInstance("MD5").digest(value); + char[] chars = new char[32]; + for (int i = 0; i < chars.length; i = i + 2) { + byte b = bytes[i / 2]; + chars[i] = HEX_CHARS[(b >>> 0x4) & 0xf]; + chars[i + 1] = HEX_CHARS[b & 0xf]; + } + return new String(chars); + } catch (Exception e) { + throw new RuntimeException("md5 encrypt error", e); + } + } +} diff --git a/czsj-common/src/main/java/com/czsj/common/database/utils/MapMailMergeDataSource.java b/czsj-common/src/main/java/com/czsj/common/database/utils/MapMailMergeDataSource.java new file mode 100644 index 0000000..a2631cb --- /dev/null +++ b/czsj-common/src/main/java/com/czsj/common/database/utils/MapMailMergeDataSource.java @@ -0,0 +1,96 @@ +package com.czsj.common.database.utils; + +import com.aspose.words.IMailMergeDataSource; +import com.aspose.words.ref.Ref; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class MapMailMergeDataSource implements IMailMergeDataSource { + + private List> dataList; + + private int index; + + /** + * word模板中的«TableStart:tableName»«TableEnd:tableName»对应 + */ + private String tableName = null; + + /** + * @param dataList 数据集 + * @param tableName 与模板中的Name对应 + */ + public MapMailMergeDataSource(List> dataList, String tableName) { + this.dataList = dataList; + this.tableName = tableName; + index = -1; + } + + /** + * @param data 单个数据集 + * @param tableName 与模板中的Name对应 + */ + public MapMailMergeDataSource(Map data, String tableName) { + if (this.dataList == null) { + this.dataList = new ArrayList>(); + this.dataList.add(data); + } + this.tableName = tableName; + index = -1; + } + + /** + * 获取结果集总数 + * + * @return + */ + private int getCount() { + return this.dataList.size(); + } + + @Override + public IMailMergeDataSource getChildDataSource(String arg0) + throws Exception { + return null; + } + + @Override + public String getTableName() throws Exception { + return this.tableName; + } + + /** + * 实现接口 + * 获取当前index指向数据行的数据 + * 将数据存入args数组中即可 + * + * @return ***返回false则不绑定数据*** + */ + @Override + public boolean getValue(String key, Ref args) throws Exception { + if (index < 0 || index >= this.getCount()) { + return false; + } + if (args != null) { + args.set(this.dataList.get(index).get(key)); + return true; + } else { + return false; + } + } + + /** + * 实现接口 + * 判断是否还有下一条记录 + */ + @Override + public boolean moveNext() throws Exception { + index += 1; + if (index >= this.getCount()) { + return false; + } + return true; + } +} diff --git a/czsj-common/src/main/java/com/czsj/common/database/utils/MergeDataSource.java b/czsj-common/src/main/java/com/czsj/common/database/utils/MergeDataSource.java new file mode 100644 index 0000000..725d8e8 --- /dev/null +++ b/czsj-common/src/main/java/com/czsj/common/database/utils/MergeDataSource.java @@ -0,0 +1,47 @@ +package com.czsj.common.database.utils; + +import com.aspose.words.Document; +import com.aspose.words.MailMerge; + +import java.util.List; +import java.util.Map; + +public class MergeDataSource { + + /** + * word模板普通数据填充 + * @param name + * @param value + * @param modelPath + * @return + * @throws Exception + */ + public Document load(String[] name, Object[] value, String modelPath) throws Exception { + Document doc = new Document(modelPath); + // 这里可以做特殊字段处理(如:图片插入、字符对应的特殊符号[https://wenku.baidu.com/view/81b41244336c1eb91a375dcb.html]) +// DocumentBuilder builder = new DocumentBuilder(doc); +// builder.moveToMergeField(key); +// builder.insertImage((BufferedImage) value); + MailMerge merge = doc.getMailMerge(); + merge.execute(name, value); + return doc; + } + + + /** + * word模板里有集合的表格填充 + * @param name + * @param value + * @param modelPath + * @param dataList + * @return + * @throws Exception + */ + public Document load(String[] name, Object[] value, String modelPath, List> dataList, String tableName) throws Exception { + Document doc = new Document(modelPath); + MailMerge merge = doc.getMailMerge(); + merge.execute(name, value); + merge.executeWithRegions(new MapMailMergeDataSource(dataList, tableName)); + return doc; + } +} diff --git a/czsj-common/src/main/java/com/czsj/common/database/utils/RedisService.java b/czsj-common/src/main/java/com/czsj/common/database/utils/RedisService.java new file mode 100644 index 0000000..f1e7f0e --- /dev/null +++ b/czsj-common/src/main/java/com/czsj/common/database/utils/RedisService.java @@ -0,0 +1,557 @@ +package com.czsj.common.database.utils;//package com.czsj.common.database.utils; +// +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.data.redis.core.RedisTemplate; +//import org.springframework.stereotype.Component; +// +//import java.util.Arrays; +//import java.util.List; +//import java.util.Map; +//import java.util.Set; +//import java.util.concurrent.TimeUnit; +// +///** +// * 定义常用的 Redis操作 +// */ +//@Component +//public class RedisService { +// +// @Autowired +// private RedisTemplate redisTemplate; +// +// /** +// * 指定缓存失效时间 +// * +// * @param key 键 +// * @param time 时间(秒) +// * @return Boolean +// */ +// public Boolean expire(String key, Long time) { +// try { +// if (time > 0) { +// redisTemplate.expire(key, time, TimeUnit.SECONDS); +// } +// return true; +// } catch (Exception e) { +// e.printStackTrace(); +// return false; +// } +// } +// +// /** +// * 根据key获取过期时间 +// * +// * @param key 键 不能为 null +// * @return 时间(秒) 返回 0代表为永久有效 +// */ +// public Long getExpire(String key) { +// return redisTemplate.getExpire(key, TimeUnit.SECONDS); +// } +// +// /** +// * 判断 key是否存在 +// * +// * @param key 键 +// * @return true 存在 false不存在 +// */ +// public Boolean hasKey(String key) { +// try { +// return redisTemplate.hasKey(key); +// } catch (Exception e) { +// e.printStackTrace(); +// return false; +// } +// } +// +// /** +// * 删除缓存 +// * +// * @param key 可以传一个值 或多个 +// */ +// public void del(String... key) { +// if (key != null && key.length > 0) { +// if (key.length == 1) { +// redisTemplate.delete(key[0]); +// } else { +// redisTemplate.delete(Arrays.asList(key)); +// } +// } +// } +// +// /** +// * 普通缓存获取 +// * +// * @param key 键 +// * @return 值 +// */ +// public Object get(String key) { +// return key == null ? null : redisTemplate.opsForValue().get(key); +// } +// +// /** +// * 普通缓存放入 +// * +// * @param key 键 +// * @param value 值 +// * @return true成功 false失败 +// */ +// public Boolean set(String key, Object value) { +// try { +// redisTemplate.opsForValue().set(key, value); +// return true; +// } catch (Exception e) { +// e.printStackTrace(); +// return false; +// } +// } +// +// /** +// * 普通缓存放入并设置时间 +// * +// * @param key 键 +// * @param value 值 +// * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 +// * @return true成功 false 失败 +// */ +// public Boolean set(String key, Object value, Long time) { +// try { +// if (time > 0) { +// redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS); +// } else { +// set(key, value); +// } +// return true; +// } catch (Exception e) { +// e.printStackTrace(); +// return false; +// } +// } +// +// /** +// * 递增 +// * +// * @param key 键 +// * @param delta 要增加几(大于0) +// * @return Long +// */ +// public Long incr(String key, Long delta) { +// if (delta < 0) { +// throw new RuntimeException("递增因子必须大于0"); +// } +// return redisTemplate.opsForValue().increment(key, delta); +// } +// +// /** +// * 递减 +// * +// * @param key 键 +// * @param delta 要减少几(小于0) +// * @return Long +// */ +// public Long decr(String key, Long delta) { +// if (delta < 0) { +// throw new RuntimeException("递减因子必须大于0"); +// } +// return redisTemplate.opsForValue().increment(key, -delta); +// } +// +// /** +// * HashGet +// * +// * @param key 键 不能为 null +// * @param item 项 不能为 null +// * @return 值 +// */ +// public Object hget(String key, String item) { +// return redisTemplate.opsForHash().get(key, item); +// } +// +// /** +// * 获取 hashKey对应的所有键值 +// * +// * @param key 键 +// * @return 对应的多个键值 +// */ +// public Map hmget(String key) { +// return redisTemplate.opsForHash().entries(key); +// } +// +// /** +// * HashSet +// * +// * @param key 键 +// * @param map 对应多个键值 +// * @return true 成功 false 失败 +// */ +// public Boolean hmset(String key, Map map) { +// try { +// redisTemplate.opsForHash().putAll(key, map); +// return true; +// } catch (Exception e) { +// e.printStackTrace(); +// return false; +// } +// } +// +// /** +// * HashSet 并设置时间 +// * +// * @param key 键 +// * @param map 对应多个键值 +// * @param time 时间(秒) +// * @return true成功 false失败 +// */ +// public Boolean hmset(String key, Map map, Long time) { +// try { +// redisTemplate.opsForHash().putAll(key, map); +// if (time > 0) { +// expire(key, time); +// } +// return true; +// } catch (Exception e) { +// e.printStackTrace(); +// return false; +// } +// } +// +// /** +// * 向一张hash表中放入数据,如果不存在将创建 +// * +// * @param key 键 +// * @param item 项 +// * @param value 值 +// * @return true 成功 false失败 +// */ +// public Boolean hset(String key, String item, Object value) { +// try { +// redisTemplate.opsForHash().put(key, item, value); +// return true; +// } catch (Exception e) { +// e.printStackTrace(); +// return false; +// } +// } +// +// /** +// * 向一张hash表中放入数据,如果不存在将创建 +// * +// * @param key 键 +// * @param item 项 +// * @param value 值 +// * @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间 +// * @return true 成功 false失败 +// */ +// public Boolean hset(String key, String item, Object value, Long time) { +// try { +// redisTemplate.opsForHash().put(key, item, value); +// if (time > 0) { +// expire(key, time); +// } +// return true; +// } catch (Exception e) { +// e.printStackTrace(); +// return false; +// } +// } +// +// /** +// * 删除hash表中的值 +// * +// * @param key 键 不能为 null +// * @param item 项 可以使多个不能为 null +// */ +// public void hdel(String key, Object... item) { +// redisTemplate.opsForHash().delete(key, item); +// } +// +// /** +// * 判断hash表中是否有该项的值 +// * +// * @param key 键 不能为 null +// * @param item 项 不能为 null +// * @return true 存在 false不存在 +// */ +// public Boolean hHasKey(String key, String item) { +// return redisTemplate.opsForHash().hasKey(key, item); +// } +// +// /** +// * hash递增 如果不存在,就会创建一个 并把新增后的值返回 +// * +// * @param key 键 +// * @param item 项 +// * @param by 要增加几(大于0) +// * @return Double +// */ +// public Double hincr(String key, String item, Double by) { +// return redisTemplate.opsForHash().increment(key, item, by); +// } +// +// /** +// * hash递减 +// * +// * @param key 键 +// * @param item 项 +// * @param by 要减少记(小于0) +// * @return Double +// */ +// public Double hdecr(String key, String item, Double by) { +// return redisTemplate.opsForHash().increment(key, item, -by); +// } +// +// /** +// * 根据 key获取 Set中的所有值 +// * +// * @param key 键 +// * @return Set +// */ +// public Set sGet(String key) { +// try { +// return redisTemplate.opsForSet().members(key); +// } catch (Exception e) { +// e.printStackTrace(); +// return null; +// } +// } +// +// /** +// * 根据value从一个set中查询,是否存在 +// * +// * @param key 键 +// * @param value 值 +// * @return true 存在 false不存在 +// */ +// public Boolean sHasKey(String key, Object value) { +// try { +// return redisTemplate.opsForSet().isMember(key, value); +// } catch (Exception e) { +// e.printStackTrace(); +// return false; +// } +// } +// +// /** +// * 将数据放入set缓存 +// * +// * @param key 键 +// * @param values 值 可以是多个 +// * @return 成功个数 +// */ +// public Long sSet(String key, Object... values) { +// try { +// return redisTemplate.opsForSet().add(key, values); +// } catch (Exception e) { +// e.printStackTrace(); +// return 0L; +// } +// } +// +// /** +// * 将set数据放入缓存 +// * +// * @param key 键 +// * @param time 时间(秒) +// * @param values 值 可以是多个 +// * @return 成功个数 +// */ +// public Long sSetAndTime(String key, Long time, Object... values) { +// try { +// Long count = redisTemplate.opsForSet().add(key, values); +// if (time > 0) +// expire(key, time); +// return count; +// } catch (Exception e) { +// e.printStackTrace(); +// return 0L; +// } +// } +// +// /** +// * 获取set缓存的长度 +// * +// * @param key 键 +// * @return Long +// */ +// public Long sGetSetSize(String key) { +// try { +// return redisTemplate.opsForSet().size(key); +// } catch (Exception e) { +// e.printStackTrace(); +// return 0L; +// } +// } +// +// /** +// * 移除值为value的 +// * +// * @param key 键 +// * @param values 值 可以是多个 +// * @return 移除的个数 +// */ +// public Long setRemove(String key, Object... values) { +// try { +// return redisTemplate.opsForSet().remove(key, values); +// } catch (Exception e) { +// e.printStackTrace(); +// return 0L; +// } +// } +// +// /** +// * 获取list缓存的内容 +// * +// * @param key 键 +// * @param start 开始 +// * @param end 结束 0 到 -1代表所有值 +// * @return List +// */ +// public List lGet(String key, int start, int end) { +// try { +// return redisTemplate.opsForList().range(key, start, end); +// } catch (Exception e) { +// e.printStackTrace(); +// return null; +// } +// } +// +// /** +// * 获取list缓存的长度 +// * +// * @param key 键 +// * @return Long +// */ +// public Long lGetListSize(String key) { +// try { +// return redisTemplate.opsForList().size(key); +// } catch (Exception e) { +// e.printStackTrace(); +// return 0L; +// } +// } +// +// /** +// * 通过索引 获取list中的值 +// * +// * @param key 键 +// * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推; +// * index<0时,-1,表尾,-2倒数第二个元素,依次类推 +// * @return Object +// */ +// public Object lGetIndex(String key, Long index) { +// try { +// return redisTemplate.opsForList().index(key, index); +// } catch (Exception e) { +// e.printStackTrace(); +// return null; +// } +// } +// +// /** +// * 将list放入缓存 +// * +// * @param key 键 +// * @param value 值 +// * @return Boolean +// */ +// public Boolean lSet(String key, Object value) { +// try { +// redisTemplate.opsForList().rightPush(key, value); +// return true; +// } catch (Exception e) { +// e.printStackTrace(); +// return false; +// } +// } +// +// /** +// * 将list放入缓存 +// * +// * @param key 键 +// * @param value 值 +// * @param time 时间(秒) +// * @return Boolean +// */ +// public Boolean lSet(String key, Object value, Long time) { +// try { +// redisTemplate.opsForList().rightPush(key, value); +// if (time > 0) +// expire(key, time); +// return true; +// } catch (Exception e) { +// e.printStackTrace(); +// return false; +// } +// } +// +// /** +// * 将list放入缓存 +// * +// * @param key 键 +// * @param value 值 +// * @return Boolean +// */ +// public Boolean lSet(String key, List value) { +// try { +// redisTemplate.opsForList().rightPushAll(key, value); +// return true; +// } catch (Exception e) { +// e.printStackTrace(); +// return false; +// } +// } +// +// /** +// * 将list放入缓存 +// * +// * @param key 键 +// * @param value 值 +// * @param time 时间(秒) +// * @return Boolean +// */ +// public Boolean lSet(String key, List value, Long time) { +// try { +// redisTemplate.opsForList().rightPushAll(key, value); +// if (time > 0) +// expire(key, time); +// return true; +// } catch (Exception e) { +// e.printStackTrace(); +// return false; +// } +// } +// +// /** +// * 根据索引修改list中的某条数据 +// * +// * @param key 键 +// * @param index 索引 +// * @param value 值 +// * @return Boolean +// */ +// public Boolean lUpdateIndex(String key, Long index, Object value) { +// try { +// redisTemplate.opsForList().set(key, index, value); +// return true; +// } catch (Exception e) { +// e.printStackTrace(); +// return false; +// } +// } +// +// /** +// * 移除N个值为value +// * +// * @param key 键 +// * @param count 移除多少个 +// * @param value 值 +// * @return 移除的个数 +// */ +// public Long lRemove(String key, Long count, Object value) { +// try { +// return redisTemplate.opsForList().remove(key, count, value); +// } catch (Exception e) { +// e.printStackTrace(); +// return 0L; +// } +// } +//} \ No newline at end of file diff --git a/czsj-common/src/main/java/com/czsj/common/database/utils/SecurityUtil.java b/czsj-common/src/main/java/com/czsj/common/database/utils/SecurityUtil.java new file mode 100644 index 0000000..7b82908 --- /dev/null +++ b/czsj-common/src/main/java/com/czsj/common/database/utils/SecurityUtil.java @@ -0,0 +1,109 @@ +package com.czsj.common.database.utils; + + +import com.czsj.core.database.core.DataRole; +import com.czsj.core.database.core.DataUser; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; + +import java.util.List; +import java.util.stream.Collectors; + +public class SecurityUtil { + + /** + * 获取用户 + * + * @return user + */ + public static DataUser getDataUser() { + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + if (authentication != null) { + Object principal = authentication.getPrincipal(); + if (principal instanceof DataUser) { + DataUser user = (DataUser) principal; + return user; + } + } + return null; + } + + /** + * 获取用户ID + * + * @return id + */ + public static String getUserId() { + DataUser user = getDataUser(); + if (user != null){ + return user.getId(); + } + return ""; + } + + /** + * 获取用户部门 + * + * @return id + */ + public static String getUserDeptId() { + DataUser user = getDataUser(); + if (user != null){ + return user.getDept(); + } + return ""; + } + + /** + * 获取用户名称 + * + * @return username + */ + public static String getUserName() { + DataUser user = getDataUser(); + if (user != null){ + return user.getUsername(); + } + return ""; + } + + /** + * 获取用户昵称 + * + * @return nickname + */ + public static String getNickname() { + DataUser user = getDataUser(); + if (user != null){ + return user.getNickname(); + } + return ""; + } + + /** + * 获取用户角色 + * + * @return username + */ + public static List getUserRoleIds() { + DataUser user = getDataUser(); + if (user != null){ + List roles = user.getRoles().stream().map(DataRole::getId).collect(Collectors.toList()); + return roles; + } + return null; + } + + /** + * 获取用户 + * + * @return user + */ + public static boolean isAdmin() { + DataUser user = getDataUser(); + if (user != null){ + return user.isAdmin(); + } + return false; + } +} diff --git a/czsj-common/src/main/java/com/czsj/common/database/utils/WordUtil.java b/czsj-common/src/main/java/com/czsj/common/database/utils/WordUtil.java new file mode 100644 index 0000000..a5ed3af --- /dev/null +++ b/czsj-common/src/main/java/com/czsj/common/database/utils/WordUtil.java @@ -0,0 +1,281 @@ +package com.czsj.common.database.utils; + +import com.aspose.words.*; + +import java.awt.*; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.util.List; +import java.util.Map; + +public class WordUtil { + + private WordUtil() {} + + private static volatile WordUtil instance; + + public static WordUtil getInstance() { + if(instance == null) { + synchronized (WordUtil.class) { + if(instance == null) { + instance = new WordUtil(); + } + } + } + return instance; + } + + /** + * 去除水印 + */ + static { + String license = + "\n" + + " \n" + + " \n" + + " Aspose.Cells for Java\n" + + " Aspose.Words for Java\n" + + " Aspose.Slides for Java\n" + + " \n" + + " Enterprise\n" + + " 20991231\n" + + " 20991231\n" + + " 8bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7\n" + + " \n" + + " datax\n" + + ""; + try { + new License().setLicense(new ByteArrayInputStream(license.getBytes("UTF-8"))); + } catch (Exception e) {} + } + + /** + * 获取文档 + * + * @param fileName 模板文件 F:\模板.docx + * @return + * @throws Exception + */ + public Document getDocument(String fileName) throws Exception { + return new Document(fileName); + } + + /** + * 获取文档 + * + * @param inputStream 模板文件输入流 + * @return + * @throws Exception + */ + public Document getDocument(InputStream inputStream) throws Exception { + return new Document(inputStream); + } + + /** + * 普通数据模板 返回缓冲输入流 + * + * @param name + * @param value + * @param modelPath 模板文件 F:\模板.docx + * @return 缓冲输入流 供controller层下载 + * @throws Exception + */ + public ByteArrayInputStream fillWordData(String[] name, Object[] value, String modelPath) throws Exception { + Document doc = new MergeDataSource().load(name, value, modelPath); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + doc.save(bos, SaveOptions.createSaveOptions(SaveFormat.DOCX)); + ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); + return bis; + } + + /** + * 普通数据模板 直接保存到指定位置 + * + * @param name + * @param value + * @param modelPath 模板文件 F:\模板.docx + * @param destPath 保存文件 F:\测试.docx + * @throws Exception + */ + public void fillWordData(String[] name, Object[] value, String modelPath, String destPath) throws Exception { + Document doc = new MergeDataSource().load(name, value, modelPath); + doc.save(destPath, SaveOptions.createSaveOptions(SaveFormat.DOCX)); + } + + /** + * 带集合的数据模板 返回缓冲输入流 + * + * @param name + * @param value + * @param modelPath 模板文件 F:\模板.docx + * @param dataList 集合数据 + * @param tableName 集合名称 + * @throws Exception + */ + public ByteArrayInputStream fillWordListData(String[] name, Object[] value, String modelPath, List> dataList, String tableName) throws Exception { + Document doc = new MergeDataSource().load(name, value, modelPath, dataList, tableName); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + doc.save(bos, SaveOptions.createSaveOptions(SaveFormat.DOCX)); + ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); + return bis; + } + + /** + * 带集合的数据模板 直接保存到指定位置 + * + * @param name + * @param value + * @param modelPath 模板文件 F:\模板.docx + * @param destPath 保存文件 F:\测试.docx + * @param dataList 集合数据 + * @param tableName 集合名称 + * @throws Exception + */ + public void fillWordListData(String[] name, Object[] value, String modelPath, String destPath, List> dataList, String tableName) throws Exception { + Document doc = new MergeDataSource().load(name, value, modelPath, dataList, tableName); + doc.save(destPath, SaveOptions.createSaveOptions(SaveFormat.DOCX)); + } + + /** + * word转pdf + * @param srcPath 文件路径 F:\\test\\审批流提交.docx + * @param destPath 目标路径 F:\\test\\20200420.pdf + * @throws Exception + */ + public void word2pdf(String srcPath, String destPath) throws Exception { + // 转换开始前时间 + long old = System.currentTimeMillis(); + // 要转换的word文档的路径 + Document doc = new Document(srcPath); + // 全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF, EPUB, XPS, SWF 相互转换 + doc.save(destPath, SaveOptions.createSaveOptions(SaveFormat.PDF)); + // 转换结束后时间 + long now = System.currentTimeMillis(); + System.out.println("共耗时:" + ((now - old) / 1000.0) + "秒"); + } + + /** + * 创建空文档 + * + * @param destPath 文件路径 F:\\test\\审批流提交.docx + * @return + */ + public void createWord(String destPath) throws Exception { + Document doc = new Document(); + doc.save(destPath, SaveOptions.createSaveOptions(SaveFormat.DOCX)); + } + + /** + * 加水印方法 + * + * @param doc word文件流 + * @param watermarkText 水印内容 + */ + public void insertWatermarkText(Document doc, String watermarkText) throws Exception { + Shape watermark = new Shape(doc, ShapeType.TEXT_PLAIN_TEXT); + watermark.setName("WaterMark"); + watermark.getTextPath().setText(watermarkText); + watermark.getTextPath().setFontFamily("Arial"); + watermark.setWidth(500); + watermark.setHeight(100); + watermark.setRotation(-40); + watermark.getFill().setColor(Color.GRAY); + watermark.setStrokeColor(Color.GRAY); + watermark.setRelativeHorizontalPosition(RelativeHorizontalPosition.PAGE); + watermark.setRelativeVerticalPosition(RelativeVerticalPosition.PAGE); + watermark.setWrapType(WrapType.NONE); + watermark.setVerticalAlignment(VerticalAlignment.CENTER); + watermark.setHorizontalAlignment(HorizontalAlignment.CENTER); + Paragraph watermarkPara = new Paragraph(doc); + watermarkPara.appendChild(watermark); + for (Section sect : doc.getSections()) { + insertWatermarkIntoHeader(watermarkPara, sect, HeaderFooterType.HEADER_PRIMARY); + insertWatermarkIntoHeader(watermarkPara, sect, HeaderFooterType.HEADER_FIRST); + insertWatermarkIntoHeader(watermarkPara, sect, HeaderFooterType.HEADER_EVEN); + } + } + + private void insertWatermarkIntoHeader(Paragraph watermarkPara, Section sect, int headerType) throws Exception { + HeaderFooter header = sect.getHeadersFooters().getByHeaderFooterType(headerType); + if (header == null) { + header = new HeaderFooter(sect.getDocument(), headerType); + sect.getHeadersFooters().add(header); + } + header.appendChild(watermarkPara.deepClone(true)); + } + + public static void main(String[] args) throws Exception { +// Map map = new HashMap<>(); +// map.put("companyName", "测试"); +// map.put("totalSalary", new BigDecimal("12.34")); +// List> list = new ArrayList<>(); +// Map map1 = new HashMap<>(); +// map1.put("id", "1"); +// map1.put("name", "测试1"); +// map1.put("age", 12); +// map1.put("sex", "男"); +// map1.put("salary", new BigDecimal("5.0")); +// list.add(map1); +// Map map2 = new HashMap<>(); +// map2.put("id", "2"); +// map2.put("name", "测试2"); +// map2.put("age", 14); +// map2.put("sex", "女"); +// map2.put("salary", new BigDecimal("7.34")); +// list.add(map2); +// List objects1 = new ArrayList<>(); +// List objects2 = new ArrayList<>(); +// for(Map.Entry entry : map.entrySet()){ +// objects1.add(entry.getKey()); +// objects2.add(entry.getValue()); +// } +// WordUtil.getInstance().fillWordListData(objects1.toArray(new String[objects1.size()]), objects2.toArray(new Object[objects2.size()]), "F:\\test\\模板.docx", "F:\\test\\123.docx", list, "workerList"); +// WordUtil.getInstance().word2pdf("F:\\test.docx", "F:\\20200420.pdf"); +// +// // 用户表(子表) TableStart:UserList TableEnd:UserList +// DataTable userTable = new DataTable("UserList"); +// userTable.getColumns().add("id"); +// userTable.getColumns().add("name"); +// userTable.getColumns().add("age"); +// userTable.getColumns().add("sex"); +// userTable.getColumns().add("salary"); +// for (int i = 1; i < 3; i++) { +// DataRow row = userTable.newRow(); +// row.set(0, i); +// row.set(1, "name" + i); +// row.set(2, "age" + i); +// row.set(3, "sex" + i); +// row.set(4, "salary" + i); +// userTable.getRows().add(row); +// } +// // 分数表(子表) TableStart:ScoreList TableEnd:ScoreList +// DataTable scoreTable = new DataTable("ScoreList"); +// scoreTable.getColumns().add("id"); +// scoreTable.getColumns().add("uid"); +// scoreTable.getColumns().add("score"); +// for (int i = 1; i < 3; i++) { +// DataRow row = scoreTable.newRow(); +// row.set(0, i); +// row.set(1, i); +// row.set(2, 10*i); +// scoreTable.getRows().add(row); +// } +// // 提供数据源 +// DataSet dataSet = new DataSet(); +// dataSet.getTables().add(userTable); +// dataSet.getTables().add(scoreTable); +// DataRelation dataRelation = new DataRelation("UserScoreRelation", userTable.getColumns().get("id"), scoreTable.getColumns().get("uid")); +// dataSet.getRelations().add(dataRelation); +// // 合并模版 +// Document doc = new Document("F:\\test.docx"); +// //提供数据源 +// String[] fieldNames = new String[] {"name", "address"}; +// Object[] fieldValues = new Object[] {"张三", "陕西咸阳"}; +// //合并模版,相当于页面的渲染 +// MailMerge mailMerge = doc.getMailMerge(); +// mailMerge.execute(fieldNames, fieldValues); +// mailMerge.executeWithRegions(dataSet); +// doc.save("F:\\test_r.docx", SaveOptions.createSaveOptions(SaveFormat.DOCX)); + } +} diff --git a/czsj-common/src/main/java/com/czsj/common/datasource/ClickhouseSource.java b/czsj-common/src/main/java/com/czsj/common/datasource/ClickhouseSource.java new file mode 100644 index 0000000..0d41744 --- /dev/null +++ b/czsj-common/src/main/java/com/czsj/common/datasource/ClickhouseSource.java @@ -0,0 +1,552 @@ +package com.czsj.common.datasource; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.dtstack.dtcenter.loader.client.ClientCache; +import com.dtstack.dtcenter.loader.client.IClient; +import com.dtstack.dtcenter.loader.dto.SqlQueryDTO; +import com.dtstack.dtcenter.loader.dto.source.ClickHouseSourceDTO; +import com.dtstack.dtcenter.loader.dto.source.OracleSourceDTO; +import com.dtstack.dtcenter.loader.source.DataSourceType; +import com.czsj.common.domian.CkTable; +import com.czsj.common.domian.Column; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.*; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class ClickhouseSource { + + private static Logger logger = LoggerFactory.getLogger(ClickhouseSource.class); + private static final String SQL = "SELECT * FROM ";// 数据库操作 + private static PreparedStatement pst = null;// 事务对象 + + public static Connection getconn(String url, String username, String password) { + ClickHouseSourceDTO sourceDTO = ClickHouseSourceDTO.builder() + .url(url) + .username(username) + .password(password) + .build(); + //获取连接 + IClient client = ClientCache.getClient(DataSourceType.Clickhouse.getVal()); + Boolean isConnected = client.testCon(sourceDTO); + if (Boolean.FALSE.equals(isConnected)) { + throw new RuntimeException("connection exception"); + } + return client.getCon(sourceDTO); + } + + public static Map getconns(String url, String username, String password) { + Map map = new HashMap<>(); + ClickHouseSourceDTO sourceDTO = ClickHouseSourceDTO.builder() + .url(url) + .username(username) + .password(password) + .build(); + //获取连接 + IClient client = ClientCache.getClient(DataSourceType.Clickhouse.getVal()); + Boolean isConnected = client.testCon(sourceDTO); + if (Boolean.FALSE.equals(isConnected)) { + throw new RuntimeException("connection exception"); + } + map.put("client",client); + map.put("source",sourceDTO); + return map; + } + + //关闭数据库连接 + public static void CloseCon(Connection con) throws Exception { + if (con != null) { + con.close(); + logger.info("已断开与数据库的连接!"); + } + } + + public static boolean cttable(Connection conn, String sql) { + try { + Statement state = conn.createStatement(); + state.executeUpdate(sql); + return true; + } catch (SQLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return false; + } + } + + /** + * 自定义查询 + */ + public static List> customQuery(IClient client, ClickHouseSourceDTO source, String sql,List parameters) { + + // 预编译查询 + List preFields = new ArrayList<>(); + if(parameters!=null&¶meters.size()>0){ + for(String parameter : parameters){ + preFields.add(parameter); + } + } + SqlQueryDTO queryDTO = SqlQueryDTO.builder().sql(sql).preFields(preFields).build(); + List> result = client.executeQuery(source, queryDTO); + return result; + } + + /** + * 自定义查询 + */ + public static List> customQuery(IClient client, OracleSourceDTO source, String sql) { + SqlQueryDTO queryDTO = SqlQueryDTO.builder().sql(sql).build(); + List> result = client.executeQuery(source, queryDTO); + return result; + } + + + /** + * 修改CK数据库的字段名 + * + * @param conn 数据库连接对象 + * @param colonystate 是否是集群 + * @param colonyname 集群名 没有填null + * @param database 库名 + * @param table 表名 + * @param name 当前字段名 + * @param toname 修改字段名 + * @return + */ + public static boolean updateCkFieldName(Connection conn, String colonystate, String colonyname, String database, String table, String name, String toname) { + try { + Statement state = conn.createStatement(); + if ("0".equals(colonystate)) { + System.out.println("执行语句:" + "ALTER TABLE " + database + "." + table + " RENAME COLUMN " + name + " TO " + toname + ";"); + state.executeUpdate("ALTER TABLE " + database + "." + table + " RENAME COLUMN " + name + " TO " + toname + ";"); + } else if ("1".equals(colonystate)) { + System.out.println("执行语句:" + "ALTER TABLE " + database + "." + table + "on cluster" + colonyname + " RENAME COLUMN " + name + " TO " + toname); + state.executeUpdate("ALTER TABLE " + database + "." + table + "on cluster" + colonyname + " RENAME COLUMN " + name + " TO " + toname + ";"); + } else { + return false; + } + System.out.println("操作成功!"); + return true; + } catch (SQLException e) { + // TODO Auto-generated catch block + System.out.println("操作失败!"); + e.printStackTrace(); + return false; + } + } + + /** + * 修改CK数据库的字段类型 + * + * @param conn 数据库连接对象 + * @param colonystate 是否是集群 + * @param colonyname 集群名 没有填null + * @param database 库名 + * @param table 表名 + * @param name 当前字段名 + * @param type 字段类型 + * @return + */ + public static boolean updateCkFieldType(Connection conn, String colonystate, String colonyname, String database, String table, String name, String type) { + try { + Statement state = conn.createStatement(); + if ("0".equals(colonystate)) { + System.out.println("执行语句:" + "ALTER TABLE " + database + "." + table + " modify COLUMN " + name + " " + type + ";"); + state.executeUpdate("ALTER TABLE " + database + "." + table + " modify COLUMN " + name + " " + type + ";"); + } else if ("1".equals(colonystate)) { + System.out.println("执行语句:" + "ALTER TABLE " + database + "." + table + "on cluster" + colonyname + " modify COLUMN " + name + " " + type + ";"); + state.executeUpdate("ALTER TABLE " + database + "." + table + "on cluster" + colonyname + " modify COLUMN " + name + " " + type + ";"); + } else { + return false; + } + System.out.println("操作成功!"); + return true; + } catch (SQLException e) { + // TODO Auto-generated catch block + System.out.println("操作失败!"); + e.printStackTrace(); + return false; + } + } + + + /** + * 修改CK数据库的注释 + * + * @param conn 数据库连接对象 + * @param colonystate 是否是集群 + * @param colonyname 集群名 没有填null + * @param database 库名 + * @param table 表名 + * @param name 字段名 + * @param comment 注释 + * @return + */ + public static boolean updateCkFieldComment(Connection conn, String colonystate, String colonyname, String database, String table, String name, String comment) { + try { + Statement state = conn.createStatement(); + if ("0".equals(colonystate)) { + System.out.println("执行语句:" + "ALTER TABLE " + database + "." + table + " COMMENT COLUMN " + name + " '" + comment + "'" + " ;"); + state.executeUpdate("ALTER TABLE " + database + "." + table + " COMMENT COLUMN " + name + " '" + comment + "'" + " ;"); + } else if ("1".equals(colonystate)) { + System.out.println("执行语句:" + "ALTER TABLE " + database + "." + table + "on cluster" + colonyname + " COMMENT COLUMN " + name + " '" + comment + "'" + " ;"); + state.executeUpdate("ALTER TABLE " + database + "." + table + "on cluster" + colonyname + " COMMENT COLUMN " + name + " '" + comment + "'" + " ;"); + } else { + return false; + } + System.out.println("操作成功!"); + return true; + } catch (SQLException e) { + // TODO Auto-generated catch block + System.out.println("操作失败!"); + e.printStackTrace(); + return false; + } + } + + + /** + * 添加CK数据库的字段 + * + * @param conn 数据库连接对象 + * @param colonystate 是否是集群 + * @param colonyname 集群名 没有填null + * @param database 库名 + * @param table 表名 + * @param name 字段名 + * @param type 字段类型 + * @param comment 注释 + * @return + */ + public static boolean insertCkField(Connection conn, String colonystate, String colonyname, String database, String table, String name, String type, String comment) { + try { + Statement state = conn.createStatement(); + if ("0".equals(colonystate)) { + System.out.println("执行语句:" + "ALTER TABLE " + database + "." + table + " ADD COLUMN " + name + " " + type + " comment '" + comment + "'" + " ;"); + state.executeUpdate("ALTER TABLE " + database + "." + table + " ADD COLUMN " + name + " " + type + " comment '" + comment + "'" + " ;"); + } else if ("1".equals(colonystate)) { + System.out.println("执行语句:" + "ALTER TABLE " + database + "." + table + "on cluster" + colonyname + " ADD COLUMN " + name + " " + type + " comment '" + comment + "'" + " ;"); + state.executeUpdate("ALTER TABLE " + database + "." + table + "on cluster" + colonyname + " ADD COLUMN " + name + " " + type + " comment '" + comment + "'" + " ;"); + } else { + return false; + } + System.out.println("操作成功!"); + return true; + } catch (SQLException e) { + // TODO Auto-generated catch block + System.out.println("操作失败!"); + e.printStackTrace(); + return false; + } + } + + + /** + * 删除CK数据库的字段 + * + * @param conn 数据库连接对象 + * @param colonystate 是否是集群 + * @param colonyname 集群名 没有填null + * @param database 库名 + * @param table 表名 + * @param name 字段名 + * @return + */ + public static boolean deleteCkField(Connection conn, String colonystate, String colonyname, String database, String table, String name) { + try { + Statement state = conn.createStatement(); + if ("0".equals(colonystate)) { + System.out.println("执行语句:" + "ALTER TABLE " + database + "." + table + " DROP COLUMN " + name + " ;"); + state.executeUpdate("ALTER TABLE " + database + "." + table + " DROP COLUMN " + name + " ;"); + } else if ("1".equals(colonystate)) { + System.out.println("执行语句:" + "ALTER TABLE " + database + "." + table + "on cluster" + colonyname + " DROP COLUMN " + name + " ;"); + state.executeUpdate("ALTER TABLE " + database + "." + table + "on cluster" + colonyname + " DROP COLUMN " + name + " ;"); + } else { + return false; + } + System.out.println("操作成功!"); + return true; + } catch (SQLException e) { + // TODO Auto-generated catch block + System.out.println("操作失败!"); + e.printStackTrace(); + return false; + } + } + + + /** + * 获取表中字段的所有注释 + * + * @param tableName + * @return + */ + public static List getCkColumnComment(Connection conn, String tableName, String database) { + List columnTypes = new ArrayList<>(); + //与数据库的连接 + PreparedStatement pStemt = null; + String tableSql = SQL + tableName; + List columnComments = new ArrayList<>();//列名注释集合 + ResultSet rs = null; + try { + pStemt = conn.prepareStatement(tableSql); + rs = pStemt.executeQuery("select table,name,type,comment from `system`.columns where table ='" + tableName + "' and database = '" + database + "'"); + while (rs.next()) { + Column Column = new Column(); + Column.setName(rs.getString("name")); + Column.setType(rs.getString("type")); + Column.setComment(rs.getString("comment")); + columnComments.add(Column); + } + } catch (SQLException e) { + e.printStackTrace(); + } finally { + if (rs != null) { + try { + rs.close(); + CloseCon(conn); + } catch (SQLException e) { + e.printStackTrace(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + return columnComments; + } + + /** + * 获取库中所有表名 + * + * @param baseName + * @return + */ + public static List getCkColumnComments(Connection conn, String baseName) { + List columnTypes = new ArrayList<>(); + PreparedStatement pStemt = null; + String tableSql = SQL + baseName; + List columnComments = new ArrayList<>();//列名注释集合 + ResultSet rs = null; + try { + pStemt = conn.prepareStatement(tableSql); + rs = pStemt.executeQuery("select database,name,create_table_query from `system`.tables where database = '" + baseName + "'"); + while (rs.next()) { + CkTable CkTable = new CkTable(); + CkTable.setDatabase(rs.getString("database")); + CkTable.setTableName(rs.getString("name")); + CkTable.setCreateTableQuery(rs.getString("create_table_query")); + columnComments.add(CkTable); + } + } catch (SQLException e) { + e.printStackTrace(); + } finally { + if (rs != null) { + try { + rs.close(); + CloseCon(conn); + } catch (SQLException e) { + e.printStackTrace(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + return columnComments; + } + + + /** + * 執行sql查詢 + * + * @auther xinjingczsj + * @time 2022年7月20日 + */ + public static Map executeQuerySql(Connection conn, String sql, int pageNum, int pageSize) throws Exception { + + if (pageNum == 1) { + pageNum = 0; + } + int start = pageNum * pageSize; + StringBuilder sql1 = new StringBuilder();// 拼接sql + sql1.append(sql + "\n"); + sql1.append("limit " + start + "," + pageSize + "\n"); + System.out.println(sql1.toString()); + pst = conn.prepareStatement(sql1.toString()); + ResultSet result = pst.executeQuery();// 查询结果 + ResultSetMetaData rsmd = result.getMetaData(); + JSONArray tableTitle = new JSONArray();// 表格头 + for (int i = 1; i <= rsmd.getColumnCount(); i++) { + JSONObject tableTitle_Th = new JSONObject();// 表格头单元格 + tableTitle_Th.put("columnname", rsmd.getColumnName(i));// 字段名 + tableTitle_Th.put("tablename", rsmd.getTableName(i));// 表名 + tableTitle_Th.put("columnclassname", rsmd.getColumnClassName(i));// JAVA_数据类型 + tableTitle_Th.put("columntypename", rsmd.getColumnTypeName(i) + "(" + rsmd.getColumnDisplaySize(i) + ")");// DB_数据类型 + tableTitle.add(tableTitle_Th);// 保存到数组 + } + JSONObject table = new JSONObject();// 所有查詢的數據 + JSONArray tableBody = new JSONArray();// 表格内容 + while (result.next()) { + JSONArray tableRow = new JSONArray();// 表内容单元格 + for (int i = 1; i <= rsmd.getColumnCount(); i++) { + String classname = rsmd.getColumnClassName(i);// 数据类型 + switch (classname) { + case "java.math.BigDecimal": { + tableRow.add(result.getBigDecimal(i)); + break; + } + case "java.lang.Boolean": { + tableRow.add(result.getBoolean(i)); + break; + } + case "java.lang.Byte": { + tableRow.add(result.getByte(i)); + break; + } + case "java.util.Date": { + Date date = result.getDate(i); + String time = ""; + if (date != null) { + time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date); + } + tableRow.add(time); + break; + } + case "java.sql.Date": { + Date date = result.getDate(i); + String time = ""; + if (date != null) { + time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date); + } + tableRow.add(time); + break; + } + case "java.lang.Double": { + tableRow.add(result.getDouble(i)); + break; + } + case "java.lang.Float": { + tableRow.add(result.getFloat(i)); + break; + } + case "java.lang.Integer": { + tableRow.add(result.getInt(i)); + break; + } + case "java.lang.Long": { + tableRow.add(result.getLong(i)); + break; + } + case "java.lang.String": { + tableRow.add(result.getString(i)); + break; + } + case "java.sql.Timestamp": { + String str = "9999-12-12 00:00:00"; + if (!"".equals(result.getString(i)) && result.getString(i) != null) { + str = result.getString(i); + } + tableRow.add(stampToDate(Double.valueOf(dateToStamp(str)))); + break; + } + case "java.math.BigInteger": { + tableRow.add(result.getBigDecimal(i)); + break; + } + default: + tableRow.add(result.getString(i)); + } + } + tableBody.add(tableRow); + } + + table.put("tableTitle", tableTitle); + table.put("tableBody", tableBody); + + Map remap = new HashMap<>(); + JSONArray tableTitle1 = table.getJSONArray("tableTitle"); + JSONArray tableBody1 = table.getJSONArray("tableBody"); + List> list = new ArrayList<>(); + List> Datalist = new ArrayList<>(); + Object[] str = new String[tableTitle1.size()]; + for (int j = 0; j < tableTitle1.size(); j++) { + JSONObject tableTitle_Th = (JSONObject) tableTitle1.get(j); + Map tableData = new HashMap<>(); + tableData.put("dataItem", tableTitle_Th.get("columnname")); + Datalist.add(tableData); + str[j] = tableTitle_Th.get("columnname"); + System.out.print(tableTitle_Th.get("columnname") + "\t"); + } + System.out.println("\n------------------------------------------------------------------------------------------------------------------------"); + for (Object o : tableBody1) { + Map tables = new HashMap<>(); + JSONArray row = (JSONArray) o; + for (int j = 0; j < row.size(); j++) { + tables.put(str[j], row.get(j)); + System.out.print(row.get(j) + "\t"); + } + list.add(tables); + System.out.println(); + } + Long x = executeQuerySqlNum(conn, sql); + remap.put("tables", list); + remap.put("tableData", Datalist); + remap.put("total", x); + return remap; + } + + + /** + * 查詢數據縂數量 + * + * @auther xinjingczsj + * @time 2022年7月20日 + */ + public static Long executeQuerySqlNum(Connection conn, String sql) throws Exception { + StringBuilder sql1 = new StringBuilder();// 拼接sql + sql1.append("select count(*) statistics from ("); + sql1.append(sql); + sql1.append(")"); + pst = conn.prepareStatement(sql1.toString()); + ResultSet result = pst.executeQuery();// 查询结果 + Long i = 0L; + while (result.next()) { + i = result.getLong("statistics"); + } + conn.close();// 关闭 + return i; + } + + + public static String stampToDate(Double time) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String time_Date = sdf.format(new java.util.Date((long) (time * 1000L))); + return time_Date; + + } + + /* + * 将时间转换为时间戳 + */ + public static String dateToStamp(String time) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String stamp = ""; + if (!"".equals(time)) {//时间不为空 + try { + stamp = String.valueOf(sdf.parse(time).getTime() / 1000); + } catch (Exception e) { + System.out.println("参数为空!"); + } + } else { //时间为空 + long current_time = System.currentTimeMillis(); //获取当前时间 + stamp = String.valueOf(current_time / 1000); + } + return stamp; + } + + +} diff --git a/czsj-common/src/main/java/com/czsj/common/datasource/HiveSourse.java b/czsj-common/src/main/java/com/czsj/common/datasource/HiveSourse.java new file mode 100644 index 0000000..d6fee75 --- /dev/null +++ b/czsj-common/src/main/java/com/czsj/common/datasource/HiveSourse.java @@ -0,0 +1,84 @@ +package com.czsj.common.datasource; + +import com.dtstack.dtcenter.loader.cache.pool.config.PoolConfig; +import com.dtstack.dtcenter.loader.client.ClientCache; +import com.dtstack.dtcenter.loader.client.IClient; +import com.dtstack.dtcenter.loader.dto.SqlQueryDTO; +import com.dtstack.dtcenter.loader.dto.source.HiveSourceDTO; +import com.dtstack.dtcenter.loader.source.DataSourceType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.util.HashMap; +import java.util.Map; + +public class HiveSourse { + private static Logger logger = LoggerFactory.getLogger(HiveSourse.class); + private static final String SQL = "SELECT * FROM ";// 数据库操作 + private static PreparedStatement pst = null;// 事务对象 + + public static Connection getconn(String url, String username, String password,String schema,String defaultFS,String config){ + HiveSourceDTO sourceDTO = HiveSourceDTO.builder() + .url(url) + .username(username) + .password(password) + .schema(schema) + .defaultFS(defaultFS) + .config(config) + .poolConfig(PoolConfig.builder().build()) + .build(); + IClient client = ClientCache.getClient(DataSourceType.HIVE.getVal()); + Boolean isConnected = client.testCon(sourceDTO); + if (Boolean.FALSE.equals(isConnected)) { + throw new RuntimeException("connection exception"); + } + return client.getCon(sourceDTO); + } + + public static Map getconns(String url, String username, String password,String schema,String defaultFS,String config) { + Map map = new HashMap<>(); + HiveSourceDTO sourceDTO = HiveSourceDTO.builder() + .url(url) + .username(username) + .password(password) + .schema(schema) + .defaultFS(defaultFS) + .config(config) + .poolConfig(PoolConfig.builder().build()) + .build(); + IClient client = ClientCache.getClient(DataSourceType.HIVE.getVal()); + Boolean isConnected = client.testCon(sourceDTO); + if (Boolean.FALSE.equals(isConnected)) { + throw new RuntimeException("connection exception"); + } + map.put("client",client); + map.put("source",sourceDTO); + return map; + } + + //关闭数据库连接 + public static void CloseCon(Connection con) throws Exception { + if (con != null) { + con.close(); + logger.info("已断开与数据库的连接!"); + } + } + + /** + * 无结果查询 + */ + public static Boolean executeSqlWithoutResultSet(IClient client, HiveSourceDTO source, String sql) { + SqlQueryDTO queryDTO = SqlQueryDTO.builder().sql(sql).build(); + Boolean aBoolean = client.executeSqlWithoutResultSet(source, queryDTO); + if (!aBoolean) { + logger.error("自定义sql执行:" + sql + " 失败\n"); + throw new RuntimeException("执行失败"); + } + return aBoolean; + } + + + +} diff --git a/czsj-common/src/main/java/com/czsj/common/datasource/MySqlSource.java b/czsj-common/src/main/java/com/czsj/common/datasource/MySqlSource.java new file mode 100644 index 0000000..1a52217 --- /dev/null +++ b/czsj-common/src/main/java/com/czsj/common/datasource/MySqlSource.java @@ -0,0 +1,551 @@ +package com.czsj.common.datasource; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.dtstack.dtcenter.loader.cache.pool.config.PoolConfig; +import com.dtstack.dtcenter.loader.client.ClientCache; +import com.dtstack.dtcenter.loader.client.IClient; +import com.dtstack.dtcenter.loader.dto.SqlQueryDTO; +import com.dtstack.dtcenter.loader.dto.source.Mysql8SourceDTO; +import com.dtstack.dtcenter.loader.source.DataSourceType; +import com.czsj.common.domian.Column; +import com.czsj.common.domian.MySqlTable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.*; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class MySqlSource { + + private static Logger logger = LoggerFactory.getLogger(MySqlSource.class); + private static final String SQL = "SELECT * FROM ";// 数据库操作 + private static PreparedStatement pst = null;// 事务对象 + + public static Connection getconn(String url, String username, String password) { + Mysql8SourceDTO source = Mysql8SourceDTO.builder() + .url(url) + .username(username) + .password(password) + .poolConfig(PoolConfig.builder().build()) + .build(); + //获取连接 + IClient client = ClientCache.getClient(DataSourceType.MySQL8.getVal()); + Boolean isConnected = client.testCon(source); + if (Boolean.FALSE.equals(isConnected)) { + throw new RuntimeException("connection exception"); + } + return client.getCon(source); + } + + public static Map getconns(String url, String username, String password) { + Map map = new HashMap<>(); + Mysql8SourceDTO source = Mysql8SourceDTO.builder() + .url(url) + .username(username) + .password(password) + .poolConfig(PoolConfig.builder().build()) + .build(); + //获取连接 + IClient client = ClientCache.getClient(DataSourceType.MySQL8.getVal()); + Boolean isConnected = client.testCon(source); + if (Boolean.FALSE.equals(isConnected)) { + throw new RuntimeException("connection exception"); + } + map.put("client",client); + map.put("source",source); + return map; + } + + //关闭数据库连接 + public static void CloseCon(Connection con) throws Exception { + if (con != null) { + con.close(); + logger.info("已断开与数据库的连接!"); + } + } + + public static boolean cttable(Connection conn, String sql) { + try { + Statement state = conn.createStatement(); + state.executeUpdate(sql); + System.out.println("操作成功!"); + return true; + } catch (SQLException e) { + // TODO Auto-generated catch bloMySql + System.out.println("操作失败!"); + e.printStackTrace(); + return false; + } + } + + /** + * 自定义查询 + */ + public static List> customQuery(IClient client, Mysql8SourceDTO source, String sql,List parameters) { + + // 预编译查询 + List preFields = new ArrayList<>(); + if(parameters!=null&¶meters.size()>0){ + for(String parameter : parameters){ + preFields.add(parameter); + } + } + SqlQueryDTO queryDTO = SqlQueryDTO.builder().sql(sql).preFields(preFields).build(); + List> result = client.executeQuery(source, queryDTO); + return result; + } + + + /** + * 修改MySql数据库的字段名 + * + * @param conn 数据库连接对象 + * @param colonystate 是否是集群 + * @param colonyname 集群名 没有填null + * @param database 库名 + * @param table 表名 + * @param name 当前字段名 + * @param toname 修改字段名 + * @return + */ + public static boolean updateMySqlFieldName(Connection conn, String colonystate, String colonyname, String database, String table, String name, String toname) { + try { + Statement state = conn.createStatement(); + if ("0".equals(colonystate)) { + System.out.println("执行语句:" + "ALTER TABLE " + database + "." + table + " CHANGE " + name + " TO " + toname + ";"); + state.executeUpdate("ALTER TABLE " + database + "." + table + " CHANGE " + name + " TO " + toname + ";"); + } else if ("1".equals(colonystate)) { + System.out.println("执行语句:" + "ALTER TABLE " + database + "." + table + "on cluster" + colonyname + " CHANGE " + name + " TO " + toname); + state.executeUpdate("ALTER TABLE " + database + "." + table + "on cluster" + colonyname + " CHANGE " + name + " TO " + toname + ";"); + } else { + return false; + } + System.out.println("操作成功!"); + return true; + } catch (SQLException e) { + // TODO Auto-generated catch bloMySql + System.out.println("操作失败!"); + e.printStackTrace(); + return false; + } + } + + /** + * 修改MySql数据库的字段类型 + * + * @param conn 数据库连接对象 + * @param colonystate 是否是集群 + * @param colonyname 集群名 没有填null + * @param database 库名 + * @param table 表名 + * @param name 当前字段名 + * @param type 字段类型 + * @return + */ + public static boolean updateMySqlFieldType(Connection conn, String colonystate, String colonyname, String database, String table, String name, String type) { + try { + Statement state = conn.createStatement(); + if ("0".equals(colonystate)) { + System.out.println("执行语句:" + "ALTER TABLE " + database + "." + table + " modify " + name + " " + type + ";"); + state.executeUpdate("ALTER TABLE " + database + "." + table + " modify " + name + " " + type + ";"); + } else if ("1".equals(colonystate)) { + System.out.println("执行语句:" + "ALTER TABLE " + database + "." + table + "on cluster" + colonyname + " modify " + name + " " + type + ";"); + state.executeUpdate("ALTER TABLE " + database + "." + table + "on cluster" + colonyname + " modify " + name + " " + type + ";"); + } else { + return false; + } + System.out.println("操作成功!"); + return true; + } catch (SQLException e) { + // TODO Auto-generated catch bloMySql + System.out.println("操作失败!"); + e.printStackTrace(); + return false; + } + } + + + /** + * 修改MySql数据库的注释 + * + * @param conn 数据库连接对象 + * @param colonystate 是否是集群 + * @param colonyname 集群名 没有填null + * @param database 库名 + * @param table 表名 + * @param name 字段名 + * @param comment 注释 + * @return + */ + public static boolean updateMySqlFieldComment(Connection conn, String colonystate, String colonyname, String database, String table, String name,String type, String comment) { + try { + Statement state = conn.createStatement(); + if ("0".equals(colonystate)) { + System.out.println("执行语句:" + "ALTER TABLE " + database + "." + table + " modify column " + name + " " + type + "comment '" + comment + "'" + " ;"); + state.executeUpdate("ALTER TABLE " + database + "." + table + " modify column " + name + " " + type +" comment '" + comment + "'" + " ;"); + } else if ("1".equals(colonystate)) { + System.out.println("执行语句:" + "ALTER TABLE " + database + "." + table + "on cluster" + colonyname + " modify column " + name + " " + type + "comment '" + comment + "'" + " ;"); + state.executeUpdate("ALTER TABLE " + database + "." + table + "on cluster" + colonyname + " modify column " + name + " " + type + "comment '" + comment + "'" + " ;"); + } else { + return false; + } + System.out.println("操作成功!"); + return true; + } catch (SQLException e) { + // TODO Auto-generated catch bloMySql + System.out.println("操作失败!"); + e.printStackTrace(); + return false; + } + } + + + /** + * 添加MySql数据库的字段 + * + * @param conn 数据库连接对象 + * @param colonystate 是否是集群 + * @param colonyname 集群名 没有填null + * @param database 库名 + * @param table 表名 + * @param name 字段名 + * @param type 字段类型 + * @param comment 注释 + * @return + */ + public static boolean insertMySqlField(Connection conn, String colonystate, String colonyname, String database, String table, String name, String type, String comment) { + try { + Statement state = conn.createStatement(); + if ("0".equals(colonystate)) { + System.out.println("执行语句:" + "ALTER TABLE " + database + "." + table + " ADD " + name + " " + type + " comment '" + comment + "'" + " ;"); + state.executeUpdate("ALTER TABLE " + database + "." + table + " ADD " + name + " " + type + " comment '" + comment + "'" + " ;"); + } else if ("1".equals(colonystate)) { + System.out.println("执行语句:" + "ALTER TABLE " + database + "." + table + "on cluster" + colonyname + " ADD " + name + " " + type + " comment '" + comment + "'" + " ;"); + state.executeUpdate("ALTER TABLE " + database + "." + table + "on cluster" + colonyname + " ADD " + name + " " + type + " comment '" + comment + "'" + " ;"); + } else { + return false; + } + System.out.println("操作成功!"); + return true; + } catch (SQLException e) { + // TODO Auto-generated catch bloMySql + System.out.println("操作失败!"); + e.printStackTrace(); + return false; + } + } + + + /** + * 删除MySql数据库的字段 + * + * @param conn 数据库连接对象 + * @param colonystate 是否是集群 + * @param colonyname 集群名 没有填null + * @param database 库名 + * @param table 表名 + * @param name 字段名 + * @return + */ + public static boolean deleteMySqlField(Connection conn, String colonystate, String colonyname, String database, String table, String name) { + try { + Statement state = conn.createStatement(); + if ("0".equals(colonystate)) { + System.out.println("执行语句:" + "ALTER TABLE " + database + "." + table + " DROP COLUMN " + name + " ;"); + state.executeUpdate("ALTER TABLE " + database + "." + table + " DROP COLUMN " + name + " ;"); + } else if ("1".equals(colonystate)) { + System.out.println("执行语句:" + "ALTER TABLE " + database + "." + table + "on cluster" + colonyname + " DROP COLUMN " + name + " ;"); + state.executeUpdate("ALTER TABLE " + database + "." + table + "on cluster" + colonyname + " DROP COLUMN " + name + " ;"); + } else { + return false; + } + System.out.println("操作成功!"); + return true; + } catch (SQLException e) { + // TODO Auto-generated catch bloMySql + System.out.println("操作失败!"); + e.printStackTrace(); + return false; + } + } + + + /** + * 获取表中字段的所有注释 + * + * @param tableName + * @return + */ + public static List getMySqlColumnComment(Connection conn, String tableName, String database) { + List columnTypes = new ArrayList<>(); + //与数据库的连接 + PreparedStatement pStemt = null; + String tableSql = SQL + tableName; + List columnComments = new ArrayList<>();//列名注释集合 + ResultSet rs = null; + try { + pStemt = conn.prepareStatement(tableSql); + rs = pStemt.executeQuery("select COLUMN_NAME,DATA_TYPE,COLUMN_COMMENT ,NUMERIC_PRECISION ,NUMERIC_SCALE ,CHARACTER_MAXIMUM_LENGTH from information_schema.columns where table_schema ='" + database + "' and table_name = '" + tableName + "'" + "ORDER BY ORDINAL_POSITION "); + while (rs.next()) { + Column Column = new Column(); + Column.setName(rs.getString("COLUMN_NAME")); + Column.setType(rs.getString("DATA_TYPE")); + Column.setComment(rs.getString("COLUMN_COMMENT")); + Column.setDataPrecision(rs.getString("NUMERIC_PRECISION")); + Column.setDataScale(rs.getString("NUMERIC_SCALE")); + Column.setCharLength(rs.getString("CHARACTER_MAXIMUM_LENGTH")); + columnComments.add(Column); + } + } catch (SQLException e) { + e.printStackTrace(); + } finally { + if (rs != null) { + try { + rs.close(); + CloseCon(conn); + } catch (SQLException e) { + e.printStackTrace(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + return columnComments; + } + + /** + * 获取库中所有表名 + * + * @param baseName + * @return + */ + public static List getMySqlColumnComments(Connection conn, String baseName) { + List columnTypes = new ArrayList<>(); + PreparedStatement pStemt = null; + String tableSql = SQL + baseName; + List columnComments = new ArrayList<>();//列名注释集合 + ResultSet rs = null; + try { + pStemt = conn.prepareStatement(tableSql); + rs = pStemt.executeQuery("SELECT table_name , table_comment FROM information_schema.TABLES WHERE table_schema = '" + baseName + "'"); + while (rs.next()) { + MySqlTable MySqlTable = new MySqlTable(); + MySqlTable.setDatabase(baseName); + MySqlTable.setTableName(rs.getString("table_name")); + MySqlTable.setComment(rs.getString("table_comment")); + columnComments.add(MySqlTable); + } + } catch (SQLException e) { + e.printStackTrace(); + } finally { + if (rs != null) { + try { + rs.close(); + CloseCon(conn); + } catch (SQLException e) { + e.printStackTrace(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + return columnComments; + } + + + /** + * 執行sql查詢 + * + * @auther xinjingczsj + * @time 2022年7月20日 + */ + public static Map executeQuerySql(Connection conn, String sql, int pageNum, int pageSize) throws Exception { + + if (pageNum == 1) { + pageNum = 0; + } + int start = pageNum * pageSize; + StringBuilder sql1 = new StringBuilder();// 拼接sql + sql1.append(sql + "\n"); + sql1.append("limit " + start + "," + pageSize + "\n"); + System.out.println(sql1.toString()); + pst = conn.prepareStatement(sql1.toString()); + ResultSet result = pst.executeQuery();// 查询结果 + ResultSetMetaData rsmd = result.getMetaData(); + JSONArray tableTitle = new JSONArray();// 表格头 + for (int i = 1; i <= rsmd.getColumnCount(); i++) { + JSONObject tableTitle_Th = new JSONObject();// 表格头单元格 + tableTitle_Th.put("columnname", rsmd.getColumnName(i));// 字段名 + tableTitle_Th.put("tablename", rsmd.getTableName(i));// 表名 + tableTitle_Th.put("columnclassname", rsmd.getColumnClassName(i));// JAVA_数据类型 + tableTitle_Th.put("columntypename", rsmd.getColumnTypeName(i) + "(" + rsmd.getColumnDisplaySize(i) + ")");// DB_数据类型 + tableTitle.add(tableTitle_Th);// 保存到数组 + } + JSONObject table = new JSONObject();// 所有查詢的數據 + JSONArray tableBody = new JSONArray();// 表格内容 + while (result.next()) { + JSONArray tableRow = new JSONArray();// 表内容单元格 + for (int i = 1; i <= rsmd.getColumnCount(); i++) { + String classname = rsmd.getColumnClassName(i);// 数据类型 + switch (classname) { + case "java.math.BigDecimal": { + tableRow.add(result.getBigDecimal(i)); + break; + } + case "java.lang.Boolean": { + tableRow.add(result.getBoolean(i)); + break; + } + case "java.lang.Byte": { + tableRow.add(result.getByte(i)); + break; + } + case "java.util.Date": { + Date date = result.getDate(i); + String time = ""; + if (date != null) { + time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date); + } + tableRow.add(time); + break; + } + case "java.sql.Date": { + Date date = result.getDate(i); + String time = ""; + if (date != null) { + time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date); + } + tableRow.add(time); + break; + } + case "java.lang.Double": { + tableRow.add(result.getDouble(i)); + break; + } + case "java.lang.Float": { + tableRow.add(result.getFloat(i)); + break; + } + case "java.lang.Integer": { + tableRow.add(result.getInt(i)); + break; + } + case "java.lang.Long": { + tableRow.add(result.getLong(i)); + break; + } + case "java.lang.String": { + tableRow.add(result.getString(i)); + break; + } + case "java.sql.Timestamp": { + String str = "9999-12-12 00:00:00"; + if (!"".equals(result.getString(i)) && result.getString(i) != null) { + str = result.getString(i); + } + tableRow.add(stampToDate(Double.valueOf(dateToStamp(str)))); + break; + } + case "java.math.BigInteger": { + tableRow.add(result.getBigDecimal(i)); + break; + } + default: + tableRow.add(result.getString(i)); + } + } + tableBody.add(tableRow); + } + + table.put("tableTitle", tableTitle); + table.put("tableBody", tableBody); + + Map remap = new HashMap<>(); + JSONArray tableTitle1 = table.getJSONArray("tableTitle"); + JSONArray tableBody1 = table.getJSONArray("tableBody"); + List> list = new ArrayList<>(); + List> Datalist = new ArrayList<>(); + Object[] str = new String[tableTitle1.size()]; + for (int j = 0; j < tableTitle1.size(); j++) { + JSONObject tableTitle_Th = (JSONObject) tableTitle1.get(j); + Map tableData = new HashMap<>(); + tableData.put("dataItem", tableTitle_Th.get("columnname")); + Datalist.add(tableData); + str[j] = tableTitle_Th.get("columnname"); + System.out.print(tableTitle_Th.get("columnname") + "\t"); + } + System.out.println("\n------------------------------------------------------------------------------------------------------------------------"); + for (Object o : tableBody1) { + Map tables = new HashMap<>(); + JSONArray row = (JSONArray) o; + for (int j = 0; j < row.size(); j++) { + tables.put(str[j], row.get(j)); + System.out.print(row.get(j) + "\t"); + } + list.add(tables); + System.out.println(); + } + Long x = executeQuerySqlNum(conn, sql); + remap.put("tables", list); + remap.put("tableData", Datalist); + remap.put("total", x); + return remap; + } + + + /** + * 查詢數據縂數量 + * + * @auther xinjingczsj + * @time 2022年7月20日 + */ + public static Long executeQuerySqlNum(Connection conn, String sql) throws Exception { + StringBuilder sql1 = new StringBuilder();// 拼接sql + sql1.append("select count(*) statistics from ("); + sql1.append(sql); + sql1.append(") A"); + pst = conn.prepareStatement(sql1.toString()); + ResultSet result = pst.executeQuery();// 查询结果 + Long i = 0L; + while (result.next()) { + i = result.getLong("statistics"); + } + conn.close();// 关闭 + return i; + } + + + public static String stampToDate(Double time) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String time_Date = sdf.format(new java.util.Date((long) (time * 1000L))); + return time_Date; + + } + + /* + * 将时间转换为时间戳 + */ + public static String dateToStamp(String time) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String stamp = ""; + if (!"".equals(time)) {//时间不为空 + try { + stamp = String.valueOf(sdf.parse(time).getTime() / 1000); + } catch (Exception e) { + System.out.println("参数为空!"); + } + } else { //时间为空 + long current_time = System.currentTimeMillis(); //获取当前时间 + stamp = String.valueOf(current_time / 1000); + } + return stamp; + } + + + +} diff --git a/czsj-common/src/main/java/com/czsj/common/datasource/OracleSourse.java b/czsj-common/src/main/java/com/czsj/common/datasource/OracleSourse.java new file mode 100644 index 0000000..9d33812 --- /dev/null +++ b/czsj-common/src/main/java/com/czsj/common/datasource/OracleSourse.java @@ -0,0 +1,482 @@ +package com.czsj.common.datasource; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.dtstack.dtcenter.loader.cache.pool.config.PoolConfig; +import com.dtstack.dtcenter.loader.client.ClientCache; +import com.dtstack.dtcenter.loader.client.IClient; +import com.dtstack.dtcenter.loader.dto.SqlQueryDTO; +import com.dtstack.dtcenter.loader.dto.source.OracleSourceDTO; +import com.dtstack.dtcenter.loader.source.DataSourceType; +import com.czsj.common.domian.Column; +import com.czsj.common.domian.OrcTable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.sql.*; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class OracleSourse { + + private static Logger logger = LoggerFactory.getLogger(ClickhouseSource.class); + private static final String SQL = "SELECT * FROM ";// 数据库操作 + private static PreparedStatement pst = null;// 事务对象 + + public static Connection getconn(String url, String username, String password,String schema) { + OracleSourceDTO source = OracleSourceDTO.builder() + .url(url) + .username(username) + .password(password) + .schema(schema) + .poolConfig(new PoolConfig()) + .build(); + //获取连接 + IClient client = ClientCache.getClient(DataSourceType.Oracle.getVal()); + Boolean isConnected = client.testCon(source); + if (Boolean.FALSE.equals(isConnected)) { + throw new RuntimeException("connection exception"); + } + return client.getCon(source); + } + + public static Map getconns(String url, String username, String password,String schema) { + Map map = new HashMap<>(); + OracleSourceDTO source = OracleSourceDTO.builder() + .url(url) + .username(username) + .password(password) + .schema(schema) + .poolConfig(new PoolConfig()) + .build(); + //获取连接 + IClient client = ClientCache.getClient(DataSourceType.Oracle.getVal()); + Boolean isConnected = client.testCon(source); + if (Boolean.FALSE.equals(isConnected)) { + throw new RuntimeException("connection exception"); + } + map.put("client",client); + map.put("source",source); + return map; + } + + //关闭数据库连接 + public static void CloseCon(Connection con) throws Exception { + if (con != null) { + con.close(); + logger.info("已断开与数据库的连接!"); + } + } + + /** + * 无结果查询 + */ + public static Boolean executeSqlWithoutResultSet(IClient client, OracleSourceDTO source, String sql) { + SqlQueryDTO queryDTO = SqlQueryDTO.builder().sql(sql).build(); + Boolean aBoolean = client.executeSqlWithoutResultSet(source, queryDTO); + if (!aBoolean) { + logger.error("自定义sql执行:" + sql + " 失败\n"); + throw new RuntimeException("执行失败"); + } + return aBoolean; + } + + /** + * 自定义查询 + */ + public static List> customQuery(IClient client, OracleSourceDTO source, String sql,List parameters) { + + // 预编译查询 + List preFields = new ArrayList<>(); + if(parameters!=null&¶meters.size()>0){ + for(String parameter : parameters){ + preFields.add(parameter); + } + } + SqlQueryDTO queryDTO = SqlQueryDTO.builder().sql(sql).preFields(preFields).build(); + List> result = client.executeQuery(source, queryDTO); + return result; + } + + /** + * 修改ORC数据库的注释 + * + * @param client 数据库连接对象 + * @param source 数据库连接对象 + * @param table 表名 + * @param name 字段名 + * @param comment 注释 + * @return + */ + public static boolean updateFieldComment(IClient client, OracleSourceDTO source, String table, String name, String comment) { + String sql = "comment on column " + table + "." + name + " is " + " '" + comment + "'" + " ;"; + SqlQueryDTO queryDTO = SqlQueryDTO.builder().sql(sql).build(); + Boolean aBoolean = client.executeSqlWithoutResultSet(source, queryDTO); + if (!aBoolean) { + logger.error("修改Orc数据库的字段类型:" + sql + " 失败\n"); + throw new RuntimeException("执行失败"); + } + return true; + } + + /** + * 修改orc数据库的字段名 + * + * @param client 数据库连接对象 + * @param source 数据库连接对象 + * @param database 库名 + * @param table 表名 + * @param name 当前字段名 + * @param toname 修改字段名 + * @return + */ + public static boolean updateFieldName(IClient client, OracleSourceDTO source, String database, String table, String name, String toname) { + String sql = "ALTER TABLE " + database + "." + table + " RENAME COLUMN " + name + " TO " + toname + ";"; + SqlQueryDTO queryDTO = SqlQueryDTO.builder().sql(sql).build(); + Boolean aBoolean = client.executeSqlWithoutResultSet(source, queryDTO); + if (!aBoolean) { + logger.error("修改Orc数据库的字段名:" + sql + " 失败\n"); + throw new RuntimeException("执行失败"); + } + return true; + } + + /** + * 修改ORC数据库的字段类型 + * + * @param client 数据库连接对象 + * @param source 数据库连接对象 + * @param database 库名 + * @param table 表名 + * @param name 当前字段名 + * @param type 字段类型 + * @return + */ + public static boolean updateFieldType(IClient client, OracleSourceDTO source, String database, String table, String name, String type) { + String sql = "ALTER TABLE " + database + "." + table + " modify ( " + name + " " + type + ");"; + SqlQueryDTO queryDTO = SqlQueryDTO.builder().sql(sql).build(); + Boolean aBoolean = client.executeSqlWithoutResultSet(source, queryDTO); + if (!aBoolean) { + logger.error("修改CK数据库的字段类型:" + sql + " 失败\n"); + throw new RuntimeException("执行失败"); + } + return true; + } + + /** + * 添加ORC数据库的字段 + * + * @param client 数据库连接对象 + * @param source 数据库连接对象 + * @param database 库名 + * @param table 表名 + * @param name 字段名 + * @param type 字段类型 + * @return + */ + public static boolean insertField(IClient client, OracleSourceDTO source, String database, String table, String name, String type) { + String sql = "ALTER TABLE " + database + "." + table + " ADD " + name + " " + type + ";"; + SqlQueryDTO queryDTO = SqlQueryDTO.builder().sql(sql).build(); + Boolean aBoolean = client.executeSqlWithoutResultSet(source, queryDTO); + if (!aBoolean) { + logger.error("添加Orc数据库的字段:" + sql + " 失败\n"); + throw new RuntimeException("执行失败"); + } + return true; + } + + /** + * 删除Orc数据库的字段 + * + * @param client 数据库连接对象 + * @param source 数据库连接对象 + * @param database 库名 + * @param table 表名 + * @param name 字段名 + * @return + */ + public static boolean deleteField(IClient client, OracleSourceDTO source, String database, String table, String name) { + String sql = "ALTER TABLE " + database + "." + table + " DROP COLUMN " + name + " ;"; + SqlQueryDTO queryDTO = SqlQueryDTO.builder().sql(sql).build(); + Boolean aBoolean = client.executeSqlWithoutResultSet(source, queryDTO); + if (!aBoolean) { + logger.error("添加Orc数据库的字段:" + sql + " 失败\n"); + throw new RuntimeException("执行失败"); + } + return true; + } + + /** + * 获取表中字段的所有注释 + * + * @param tableName + * @return + */ + public static List getColumnComment(Connection conn, String tableName) { + List columnTypes = new ArrayList<>(); + //与数据库的连接 + PreparedStatement pStemt = null; + String tableSql = SQL + tableName; + List columnComments = new ArrayList<>();//列名注释集合 + ResultSet rs = null; + try { + pStemt = conn.prepareStatement(tableSql); + rs = pStemt.executeQuery("select a.COLUMN_NAME, a.COMMENTS,b.DATA_TYPE,b.DATA_PRECISION, b.DATA_SCALE,b.CHAR_LENGTH from user_col_comments a left join user_tab_columns b on b.COLUMN_NAME=a.column_name and b.TABLE_NAME = a.table_name where a.TABLE_NAME = '" + tableName + "' ORDER BY COLUMN_ID"); + while (rs.next()) { + Column Column = new Column(); + Column.setName(rs.getString("COLUMN_NAME")); + Column.setType(rs.getString("DATA_TYPE")); + Column.setComment(rs.getString("COMMENTS")); + Column.setDataPrecision(rs.getString("DATA_PRECISION")); + Column.setDataScale(rs.getString("DATA_SCALE")); + Column.setCharLength(rs.getString("CHAR_LENGTH")); + columnComments.add(Column); + } + } catch (SQLException e) { + e.printStackTrace(); + } finally { + if (rs != null) { + try { + rs.close(); + CloseCon(conn); + } catch (SQLException e) { + e.printStackTrace(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + return columnComments; + } + + /** + * 获取库中所有表名 + * + * @param baseName + * @return + */ + public static List getColumnComments(Connection conn, String baseName) { + PreparedStatement pStemt = null; + String tableSql = SQL + baseName; + List columnComments = new ArrayList<>();//列名注释集合 + ResultSet rs = null; + try { + pStemt = conn.prepareStatement(tableSql); + rs = pStemt.executeQuery("select table_name,comments from user_tab_comments "); + while (rs.next()) { + OrcTable OrcTable = new OrcTable(); + OrcTable.setDatabase(baseName); + OrcTable.setTableName(rs.getString("table_name")); + OrcTable.setComments(rs.getString("comments")); + OrcTable.setCreateTableQuery("--"); + columnComments.add(OrcTable); + } + } catch (SQLException e) { + e.printStackTrace(); + } finally { + if (rs != null) { + try { + rs.close(); + CloseCon(conn); + } catch (SQLException e) { + e.printStackTrace(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + return columnComments; + } + + /** + * 執行sql查詢 + * + * @auther xinjingczsj + * @time 2022年7月20日 + */ + public static Map executeQuerySql(Connection conn, String sql, int pageNum, int pageSize) throws Exception { + + if (pageNum == 1) { + pageNum = 0; + } + int start = pageNum * pageSize; + StringBuilder sql1 = new StringBuilder();// 拼接sql + sql1.append(sql + "\n"); + sql1.append("limit " + start + "," + pageSize + "\n"); + System.out.println(sql1.toString()); + pst = conn.prepareStatement(sql1.toString()); + ResultSet result = pst.executeQuery();// 查询结果 + ResultSetMetaData rsmd = result.getMetaData(); + JSONArray tableTitle = new JSONArray();// 表格头 + for (int i = 1; i <= rsmd.getColumnCount(); i++) { + JSONObject tableTitle_Th = new JSONObject();// 表格头单元格 + tableTitle_Th.put("columnname", rsmd.getColumnName(i));// 字段名 + tableTitle_Th.put("tablename", rsmd.getTableName(i));// 表名 + tableTitle_Th.put("columnclassname", rsmd.getColumnClassName(i));// JAVA_数据类型 + tableTitle_Th.put("columntypename", rsmd.getColumnTypeName(i) + "(" + rsmd.getColumnDisplaySize(i) + ")");// DB_数据类型 + tableTitle.add(tableTitle_Th);// 保存到数组 + } + JSONObject table = new JSONObject();// 所有查詢的數據 + JSONArray tableBody = new JSONArray();// 表格内容 + while (result.next()) { + JSONArray tableRow = new JSONArray();// 表内容单元格 + for (int i = 1; i <= rsmd.getColumnCount(); i++) { + String classname = rsmd.getColumnClassName(i);// 数据类型 + switch (classname) { + case "java.math.BigDecimal": { + tableRow.add(result.getBigDecimal(i)); + break; + } + case "java.lang.Boolean": { + tableRow.add(result.getBoolean(i)); + break; + } + case "java.lang.Byte": { + tableRow.add(result.getByte(i)); + break; + } + case "java.util.Date": { + Date date = result.getDate(i); + String time = ""; + if (date != null) { + time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date); + } + tableRow.add(time); + break; + } + case "java.sql.Date": { + Date date = result.getDate(i); + String time = ""; + if (date != null) { + time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date); + } + tableRow.add(time); + break; + } + case "java.lang.Double": { + tableRow.add(result.getDouble(i)); + break; + } + case "java.lang.Float": { + tableRow.add(result.getFloat(i)); + break; + } + case "java.lang.Integer": { + tableRow.add(result.getInt(i)); + break; + } + case "java.lang.Long": { + tableRow.add(result.getLong(i)); + break; + } + case "java.lang.String": { + tableRow.add(result.getString(i)); + break; + } + case "java.sql.Timestamp": { + String str = "9999-12-12 00:00:00"; + if (!"".equals(result.getString(i)) && result.getString(i) != null) { + str = result.getString(i); + } + tableRow.add(stampToDate(Double.valueOf(dateToStamp(str)))); + break; + } + case "java.math.BigInteger": { + tableRow.add(result.getBigDecimal(i)); + break; + } + default: + tableRow.add(result.getString(i)); + } + } + tableBody.add(tableRow); + } + + table.put("tableTitle", tableTitle); + table.put("tableBody", tableBody); + + Map remap = new HashMap<>(); + JSONArray tableTitle1 = table.getJSONArray("tableTitle"); + JSONArray tableBody1 = table.getJSONArray("tableBody"); + List> list = new ArrayList<>(); + List> Datalist = new ArrayList<>(); + Object[] str = new String[tableTitle1.size()]; + for (int j = 0; j < tableTitle1.size(); j++) { + JSONObject tableTitle_Th = (JSONObject) tableTitle1.get(j); + Map tableData = new HashMap<>(); + tableData.put("dataItem", tableTitle_Th.get("columnname")); + Datalist.add(tableData); + str[j] = tableTitle_Th.get("columnname"); + System.out.print(tableTitle_Th.get("columnname") + "\t"); + } + logger.info("\n------------------------------------------------------------------------------------------------------------------------"); + for (Object o : tableBody1) { + Map tables = new HashMap<>(); + JSONArray row = (JSONArray) o; + for (int j = 0; j < row.size(); j++) { + tables.put(str[j], row.get(j)); + System.out.print(row.get(j) + "\t"); + } + list.add(tables); + System.out.println(); + } + Long x = executeQuerySqlNum(conn, sql); + remap.put("tables", list); + remap.put("tableData", Datalist); + remap.put("total", x); + return remap; + } + + + /** + * 查詢數據縂數量 + * + * @auther xinjingczsj + * @time 2022年7月20日 + */ + public static Long executeQuerySqlNum(Connection conn, String sql) throws Exception { + StringBuilder sql1 = new StringBuilder();// 拼接sql + sql1.append("select count(*) statistics from ("); + sql1.append(sql); + sql1.append(")"); + pst = conn.prepareStatement(sql1.toString()); + ResultSet result = pst.executeQuery();// 查询结果 + Long i = 0L; + while (result.next()) { + i = result.getLong("statistics"); + } + conn.close();// 关闭 + return i; + } + + + public static String stampToDate(Double time) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String time_Date = sdf.format(new java.util.Date((long) (time * 1000L))); + return time_Date; + + } + + /* + * 将时间转换为时间戳 + */ + public static String dateToStamp(String time) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String stamp = ""; + if (!"".equals(time)) {//时间不为空 + try { + stamp = String.valueOf(sdf.parse(time).getTime() / 1000); + } catch (Exception e) { + System.out.println("参数为空!"); + } + } else { //时间为空 + long current_time = System.currentTimeMillis(); //获取当前时间 + stamp = String.valueOf(current_time / 1000); + } + return stamp; + } + +} diff --git a/czsj-common/src/main/java/com/czsj/common/domian/CkTable.java b/czsj-common/src/main/java/com/czsj/common/domian/CkTable.java new file mode 100644 index 0000000..5a0bf2e --- /dev/null +++ b/czsj-common/src/main/java/com/czsj/common/domian/CkTable.java @@ -0,0 +1,54 @@ +package com.czsj.common.domian; + +import java.util.List; + +public class CkTable { + + private String database; + + private String tableName; + + private String createTableQuery; + + private List ColumnList; + + public String getTableName() { + return tableName; + } + + public void setTableName(String tableName) { + this.tableName = tableName; + } + + public List getColumnList() { + return ColumnList; + } + + public void setColumnList(List columnList) { + ColumnList = columnList; + } + + public String getDatabase() { + return database; + } + + public void setDatabase(String database) { + this.database = database; + } + + public String getCreateTableQuery() { + return createTableQuery; + } + + public void setCreateTableQuery(String createTableQuery) { + this.createTableQuery = createTableQuery; + } + + @Override + public String toString() { + return "CkTable{" + + "tableName='" + tableName + '\'' + + ", ColumnList=" + ColumnList + + '}'; + } +} diff --git a/czsj-common/src/main/java/com/czsj/common/domian/Column.java b/czsj-common/src/main/java/com/czsj/common/domian/Column.java new file mode 100644 index 0000000..1f040de --- /dev/null +++ b/czsj-common/src/main/java/com/czsj/common/domian/Column.java @@ -0,0 +1,58 @@ +package com.czsj.common.domian; + +public class Column { + private String name; + private String type; + private String comment; + private String dataPrecision; + private String DataScale; + private String charLength; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getComment() { + return comment; + } + + public void setComment(String comment) { + this.comment = comment; + } + + public String getDataPrecision() { + return dataPrecision; + } + + public void setDataPrecision(String dataPrecision) { + this.dataPrecision = dataPrecision; + } + + public String getDataScale() { + return DataScale; + } + + public void setDataScale(String dataScale) { + DataScale = dataScale; + } + + public String getCharLength() { + return charLength; + } + + public void setCharLength(String charLength) { + this.charLength = charLength; + } +} diff --git a/czsj-common/src/main/java/com/czsj/common/domian/MySqlTable.java b/czsj-common/src/main/java/com/czsj/common/domian/MySqlTable.java new file mode 100644 index 0000000..3e306bd --- /dev/null +++ b/czsj-common/src/main/java/com/czsj/common/domian/MySqlTable.java @@ -0,0 +1,64 @@ +package com.czsj.common.domian; + +import java.util.List; + +public class MySqlTable { + + private String database; + + private String tableName; + + private String createTableQuery; + + private String comment; + + private List ColumnList; + + public String getComment() { + return comment; + } + + public void setComment(String comment) { + this.comment = comment; + } + + public String getTableName() { + return tableName; + } + + public void setTableName(String tableName) { + this.tableName = tableName; + } + + public List getColumnList() { + return ColumnList; + } + + public void setColumnList(List columnList) { + ColumnList = columnList; + } + + public String getDatabase() { + return database; + } + + public void setDatabase(String database) { + this.database = database; + } + + public String getCreateTableQuery() { + return createTableQuery; + } + + public void setCreateTableQuery(String createTableQuery) { + this.createTableQuery = createTableQuery; + } + + @Override + public String toString() { + return "CkTable{" + + "tableName='" + tableName + '\'' + + ", ColumnList=" + ColumnList + + '}'; + } +} diff --git a/czsj-common/src/main/java/com/czsj/common/domian/OrcTable.java b/czsj-common/src/main/java/com/czsj/common/domian/OrcTable.java new file mode 100644 index 0000000..1dc5fe5 --- /dev/null +++ b/czsj-common/src/main/java/com/czsj/common/domian/OrcTable.java @@ -0,0 +1,66 @@ +package com.czsj.common.domian; + +import java.util.List; + +public class OrcTable { + private String database; + + private String tableName; + + private String comments; + + private String createTableQuery; + + private List ColumnList; + + public String getCreateTableQuery() { + return createTableQuery; + } + + public void setCreateTableQuery(String createTableQuery) { + this.createTableQuery = createTableQuery; + } + + public String getDatabase() { + return database; + } + + public void setDatabase(String database) { + this.database = database; + } + + public String getTableName() { + return tableName; + } + + public void setTableName(String tableName) { + this.tableName = tableName; + } + + public String getComments() { + return comments; + } + + public void setComments(String comments) { + this.comments = comments; + } + + public List getColumnList() { + return ColumnList; + } + + public void setColumnList(List columnList) { + ColumnList = columnList; + } + + @Override + public String toString() { + return "OrcTable{" + + "database='" + database + '\'' + + ", tableName='" + tableName + '\'' + + ", comments='" + comments + '\'' + + ", createTableQuery='" + createTableQuery + '\'' + + ", ColumnList=" + ColumnList + + '}'; + } +} diff --git a/czsj-common/src/main/java/com/czsj/common/handler/MybatisMetaObjectHandler.java b/czsj-common/src/main/java/com/czsj/common/handler/MybatisMetaObjectHandler.java new file mode 100644 index 0000000..da1719f --- /dev/null +++ b/czsj-common/src/main/java/com/czsj/common/handler/MybatisMetaObjectHandler.java @@ -0,0 +1,37 @@ +package com.czsj.common.handler; + +import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; +import lombok.extern.slf4j.Slf4j; +import org.apache.ibatis.reflection.MetaObject; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Component; + +import java.util.Date; + +import static com.czsj.common.utils.SecurityUtils.getUsername; + +/** + * 通用的字段填充,如createBy createDate这些字段的自动填充 + * + * @author huzekang + */ +@Component +@Slf4j +public class MybatisMetaObjectHandler implements MetaObjectHandler { + + @Override + public void insertFill(MetaObject metaObject) { + setFieldValByName("createTime", new Date(), metaObject); + setFieldValByName("createBy", getUsername(), metaObject); + } + + @Override + public void updateFill(MetaObject metaObject) { + setFieldValByName("updateTime", new Date(), metaObject); + setFieldValByName("updateBy", getUsername(), metaObject); + } + + private String getCurrentUser() { + return SecurityContextHolder.getContext().getAuthentication().getPrincipal().toString(); + } +} \ No newline at end of file diff --git a/pom.xml b/pom.xml index 0ba4990..14ee134 100644 --- a/pom.xml +++ b/pom.xml @@ -56,7 +56,6 @@ 1.8 1.8 true - 3.3.2 1.7.28 1.2.2 2.4