From 670cd52c4051dfc0afafbdd98fb0fa5edd1e4067 Mon Sep 17 00:00:00 2001 From: yanghuanglin Date: Thu, 30 May 2024 10:39:09 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=20=E6=94=AF=E6=8C=81pgsql?= =?UTF-8?q?=E3=80=81kingbasees=E3=80=81mysql=E4=B8=89=E7=A7=8D=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 32 ++++++- .../yanghuanglin/seq/config/BaseConfig.java | 9 +- .../seq/config/GeneratorConfig.java | 24 +++++ .../yanghuanglin/seq/dao/SequencesDao.java | 3 + .../seq/dao/SequencesUnlockDao.java | 3 + .../seq/dao/SequencesUnusedDao.java | 3 + .../seq/dao/impl/SequencesBase.java | 87 +++++++++++++++++++ .../seq/dao/impl/SequencesDaoImpl.java | 30 ++----- .../seq/dao/impl/SequencesUnlockDaoImpl.java | 49 ++++------- .../seq/dao/impl/SequencesUnusedDaoImpl.java | 45 +++------- .../com/yanghuanglin/seq/enums/DbType.java | 35 ++++++++ .../yanghuanglin/seq/generator/Generator.java | 5 ++ .../generator/impl/SequencesGenerator.java | 6 +- .../mysql/create_table_sequences.sql | 7 ++ .../mysql/create_table_sequences_unlock.sql | 8 ++ .../mysql/create_table_sequences_unused.sql | 8 ++ .../pgsql/create_table_sequences.sql | 11 +++ .../pgsql/create_table_sequences_unlock.sql | 13 +++ .../pgsql/create_table_sequences_unused.sql | 13 +++ src/test/java/SeqTest.java | 39 ++++++++- 20 files changed, 332 insertions(+), 98 deletions(-) create mode 100644 src/main/java/com/yanghuanglin/seq/dao/impl/SequencesBase.java create mode 100644 src/main/java/com/yanghuanglin/seq/enums/DbType.java create mode 100644 src/main/resources/mysql/create_table_sequences.sql create mode 100644 src/main/resources/mysql/create_table_sequences_unlock.sql create mode 100644 src/main/resources/mysql/create_table_sequences_unused.sql create mode 100644 src/main/resources/pgsql/create_table_sequences.sql create mode 100644 src/main/resources/pgsql/create_table_sequences_unlock.sql create mode 100644 src/main/resources/pgsql/create_table_sequences_unused.sql diff --git a/pom.xml b/pom.xml index f0e108f..a8d4ce6 100644 --- a/pom.xml +++ b/pom.xml @@ -4,22 +4,35 @@ 4.0.0 com.yanghuanglin seq - 1.9.2 + 1.10.0 seq seq - 1.9 + 1.8 org.springframework spring-jdbc - 5.3.15 + 5.3.36 mysql mysql-connector-java - 8.0.28 + 8.0.33 + test + + + cn.com.kingbase + kingbase8 + 8.6.0 + test + + + org.postgresql + postgresql + 42.7.3 + test junit @@ -30,6 +43,16 @@ + + + src/main/resources + + rebel.xml + rebel-remote.xml + + + + org.apache.maven.plugins @@ -40,6 +63,7 @@ 8 + org.apache.maven.plugins maven-source-plugin diff --git a/src/main/java/com/yanghuanglin/seq/config/BaseConfig.java b/src/main/java/com/yanghuanglin/seq/config/BaseConfig.java index 2cb90c0..7c546ca 100644 --- a/src/main/java/com/yanghuanglin/seq/config/BaseConfig.java +++ b/src/main/java/com/yanghuanglin/seq/config/BaseConfig.java @@ -6,6 +6,7 @@ import com.yanghuanglin.seq.dao.SequencesUnusedDao; import com.yanghuanglin.seq.dao.impl.SequencesDaoImpl; import com.yanghuanglin.seq.dao.impl.SequencesUnlockDaoImpl; import com.yanghuanglin.seq.dao.impl.SequencesUnusedDaoImpl; +import com.yanghuanglin.seq.enums.DbType; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.transaction.support.TransactionTemplate; @@ -30,6 +31,7 @@ public class BaseConfig { private Integer minLength; private Boolean monthZeroFilling; private Boolean dayZeroFilling; + private DbType dbType; private BaseConfig() { } @@ -161,13 +163,14 @@ public class BaseConfig { JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(dataSource); this.transactionTemplate = new TransactionTemplate(transactionManager); - this.sequencesDao = new SequencesDaoImpl(jdbcTemplate, generatorConfig.getTableConfig()); - this.sequencesUnusedDao = new SequencesUnusedDaoImpl(jdbcTemplate, generatorConfig.getTableConfig()); - this.sequencesUnlockDao = new SequencesUnlockDaoImpl(jdbcTemplate, generatorConfig.getTableConfig()); + this.sequencesDao = new SequencesDaoImpl(jdbcTemplate, generatorConfig.getTableConfig(), generatorConfig.getDbType()); + this.sequencesUnusedDao = new SequencesUnusedDaoImpl(jdbcTemplate, generatorConfig.getTableConfig(), generatorConfig.getDbType()); + this.sequencesUnlockDao = new SequencesUnlockDaoImpl(jdbcTemplate, generatorConfig.getTableConfig(), generatorConfig.getDbType()); this.step = generatorConfig.getStep(); this.type = generatorConfig.getType(); this.minLength = generatorConfig.getMinLength(); this.monthZeroFilling = generatorConfig.getMonthZeroFilling(); this.dayZeroFilling = generatorConfig.getDayZeroFilling(); + this.dbType = generatorConfig.getDbType(); } } diff --git a/src/main/java/com/yanghuanglin/seq/config/GeneratorConfig.java b/src/main/java/com/yanghuanglin/seq/config/GeneratorConfig.java index 556f85c..b20e175 100644 --- a/src/main/java/com/yanghuanglin/seq/config/GeneratorConfig.java +++ b/src/main/java/com/yanghuanglin/seq/config/GeneratorConfig.java @@ -1,6 +1,9 @@ package com.yanghuanglin.seq.config; +import com.yanghuanglin.seq.enums.DbType; + import javax.sql.DataSource; +import java.sql.SQLException; /** * 生成器配置 @@ -49,6 +52,11 @@ public class GeneratorConfig { */ private TableConfig tableConfig = new TableConfig(); + /** + * 数据库类型,默认情况下,根据dataSource中的DatabaseProductName自动获取 + */ + private DbType dbType = null; + public GeneratorConfig() { } @@ -121,4 +129,20 @@ public class GeneratorConfig { public void setTableConfig(TableConfig tableConfig) { this.tableConfig = tableConfig; } + + public DbType getDbType() { + if (this.dbType == null) { + try { + String productName = this.dataSource.getConnection().getMetaData().getDatabaseProductName(); + this.dbType = DbType.of(productName); + } catch (SQLException e) { + throw new RuntimeException("获取数据库类型失败", e); + } + } + return dbType; + } + + public void setDbType(DbType dbType) { + this.dbType = dbType; + } } diff --git a/src/main/java/com/yanghuanglin/seq/dao/SequencesDao.java b/src/main/java/com/yanghuanglin/seq/dao/SequencesDao.java index b841d97..f2d1c16 100644 --- a/src/main/java/com/yanghuanglin/seq/dao/SequencesDao.java +++ b/src/main/java/com/yanghuanglin/seq/dao/SequencesDao.java @@ -22,5 +22,8 @@ public interface SequencesDao { */ boolean update(Sequences sequences); + /** + * 创建表 + */ void createTable(); } diff --git a/src/main/java/com/yanghuanglin/seq/dao/SequencesUnlockDao.java b/src/main/java/com/yanghuanglin/seq/dao/SequencesUnlockDao.java index 8b71ea7..c9ab8bd 100644 --- a/src/main/java/com/yanghuanglin/seq/dao/SequencesUnlockDao.java +++ b/src/main/java/com/yanghuanglin/seq/dao/SequencesUnlockDao.java @@ -40,5 +40,8 @@ public interface SequencesUnlockDao { */ boolean deleteByDate(Date begin, Date end); + /** + * 创建表 + */ void createTable(); } diff --git a/src/main/java/com/yanghuanglin/seq/dao/SequencesUnusedDao.java b/src/main/java/com/yanghuanglin/seq/dao/SequencesUnusedDao.java index ea81308..d44dc56 100644 --- a/src/main/java/com/yanghuanglin/seq/dao/SequencesUnusedDao.java +++ b/src/main/java/com/yanghuanglin/seq/dao/SequencesUnusedDao.java @@ -36,6 +36,9 @@ public interface SequencesUnusedDao { */ boolean saveBatch(List sequencesUnusedList); + /** + * 创建表 + */ void createTable(); /** diff --git a/src/main/java/com/yanghuanglin/seq/dao/impl/SequencesBase.java b/src/main/java/com/yanghuanglin/seq/dao/impl/SequencesBase.java new file mode 100644 index 0000000..ab0890a --- /dev/null +++ b/src/main/java/com/yanghuanglin/seq/dao/impl/SequencesBase.java @@ -0,0 +1,87 @@ +package com.yanghuanglin.seq.dao.impl; + +import com.yanghuanglin.seq.config.TableConfig; +import com.yanghuanglin.seq.enums.DbType; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.InputStreamResource; +import org.springframework.core.io.Resource; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; + +import javax.sql.DataSource; +import java.io.*; +import java.nio.charset.StandardCharsets; + +public abstract class SequencesBase { + protected DbType dbType; + protected JdbcTemplate jdbcTemplate; + protected DataSource dataSource; + protected TableConfig tableConfig; + + public SequencesBase(JdbcTemplate jdbcTemplate, TableConfig tableConfig, DbType dbType) { + this.jdbcTemplate = jdbcTemplate; + this.dataSource = jdbcTemplate.getDataSource(); + this.tableConfig = tableConfig; + this.dbType = dbType; + } + + /** + * 执行sql文件来创建表 + * + * @param fileName 文件名,在 resources/数据库类型/ 下 + */ + public void createTableByFile(String fileName) { + try { + Resource resource = new ClassPathResource(dbType.getSeries() + "/" + fileName); + + BufferedReader reader = new BufferedReader(new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8)); + StringBuilder content = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + content.append(line).append(System.lineSeparator()); + } + String sql = content.toString(); + switch (dbType) { + case MySQL: + sql = sql.replaceAll("`sequences(_unused|_unlock)`", String.format("%s$1", tableConfig.getTable())); + sql = sql.replaceAll("`key`", String.format("`%s`", tableConfig.getKeyColumn())); + sql = sql.replaceAll("`type`", String.format("`%s`", tableConfig.getTypeColumn())); + sql = sql.replaceAll("`seq`", String.format("`%s`", tableConfig.getSeqColumn())); + sql = sql.replaceAll("`create_time`", String.format("`%s`", tableConfig.getCreateTimeColumn())); + break; + case PostgreSQL: + case KingbaseES: + sql = sql.replaceAll("\"sequences(_unused|_unlock)\"", String.format("%s$1", tableConfig.getTable())); + sql = sql.replaceAll("\"key\"", String.format("\"%s\"", tableConfig.getKeyColumn())); + sql = sql.replaceAll("\"type\"", String.format("\"%s\"", tableConfig.getTypeColumn())); + sql = sql.replaceAll("\"seq\"", String.format("\"%s\"", tableConfig.getSeqColumn())); + sql = sql.replaceAll("\"create_time\"", String.format("\"%s\"", tableConfig.getCreateTimeColumn())); + break; + } + InputStream inputStream = new ByteArrayInputStream(sql.getBytes(StandardCharsets.UTF_8)); + ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator(new InputStreamResource(inputStream)); + databasePopulator.execute(dataSource); + } catch (IOException e) { + System.err.println("执行SQL文件" + fileName + "失败"); + } + } + + /** + * 根据数据库类型,简单处理sql语句 + * + * @param sqlString sql语句 + * @return 处理后的语句 + */ + protected String adapter(String sqlString) { + switch (dbType) { + case MySQL: + break; + case PostgreSQL: + case KingbaseES: + sqlString = sqlString.replaceAll("`(.+?)`", "\"$1\""); + break; + } + return sqlString; + } + +} diff --git a/src/main/java/com/yanghuanglin/seq/dao/impl/SequencesDaoImpl.java b/src/main/java/com/yanghuanglin/seq/dao/impl/SequencesDaoImpl.java index 5e54f60..5f5720e 100644 --- a/src/main/java/com/yanghuanglin/seq/dao/impl/SequencesDaoImpl.java +++ b/src/main/java/com/yanghuanglin/seq/dao/impl/SequencesDaoImpl.java @@ -2,6 +2,7 @@ package com.yanghuanglin.seq.dao.impl; import com.yanghuanglin.seq.config.TableConfig; import com.yanghuanglin.seq.dao.SequencesDao; +import com.yanghuanglin.seq.enums.DbType; import com.yanghuanglin.seq.po.Sequences; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.jdbc.core.JdbcTemplate; @@ -12,13 +13,10 @@ import org.springframework.jdbc.core.JdbcTemplate; * @since 2022/1/28 */ @SuppressWarnings("SqlResolve") -public class SequencesDaoImpl implements SequencesDao { - private final JdbcTemplate jdbcTemplate; - private final TableConfig tableConfig; +public class SequencesDaoImpl extends SequencesBase implements SequencesDao { - public SequencesDaoImpl(JdbcTemplate jdbcTemplate, TableConfig tableConfig) { - this.jdbcTemplate = jdbcTemplate; - this.tableConfig = tableConfig; + public SequencesDaoImpl(JdbcTemplate jdbcTemplate, TableConfig tableConfig, DbType dbType) { + super(jdbcTemplate, tableConfig, dbType); } @Override @@ -26,7 +24,7 @@ public class SequencesDaoImpl implements SequencesDao { String sql = "select * from `%s` where `%s`=? and `%s`=?"; sql = String.format(sql, tableConfig.getTable(), tableConfig.getKeyColumn(), tableConfig.getTypeColumn()); try { - return this.jdbcTemplate.queryForObject(sql, (rs, rowNum) -> { + return this.jdbcTemplate.queryForObject(adapter(sql), (rs, rowNum) -> { Sequences result = new Sequences(); result.setKey(rs.getString(tableConfig.getKeyColumn())); result.setType(rs.getString(tableConfig.getTypeColumn())); @@ -42,7 +40,7 @@ public class SequencesDaoImpl implements SequencesDao { public boolean save(Sequences sequences) { String sql = "insert into `%s`(`%s`,`%s`,`%s`) values(?,?,?)"; sql = String.format(sql, tableConfig.getTable(), tableConfig.getKeyColumn(), tableConfig.getTypeColumn(), tableConfig.getSeqColumn()); - int result = this.jdbcTemplate.update(sql, sequences.getKey(), sequences.getType(), sequences.getSeq()); + int result = this.jdbcTemplate.update(adapter(sql), sequences.getKey(), sequences.getType(), sequences.getSeq()); return result != 0; } @@ -50,24 +48,12 @@ public class SequencesDaoImpl implements SequencesDao { public boolean update(Sequences sequences) { String sql = "update `%s` set `%s`=? where `%s`=? and `%s`=?"; sql = String.format(sql, tableConfig.getTable(), tableConfig.getSeqColumn(), tableConfig.getKeyColumn(), tableConfig.getTypeColumn()); - int result = this.jdbcTemplate.update(sql, sequences.getSeq(), sequences.getKey(), sequences.getType()); + int result = this.jdbcTemplate.update(adapter(sql), sequences.getSeq(), sequences.getKey(), sequences.getType()); return result != 0; } @Override public void createTable() { - String sql = "CREATE TABLE IF NOT EXISTS `%s` ( " + - " `%s` VARCHAR ( 64 ) NOT NULL COMMENT '序号英文名称'," + - " `%s` VARCHAR ( 64 ) NOT NULL COMMENT '序号类型'," + - " `%s` BIGINT ( 20 ) NOT NULL COMMENT '已使用到的序号'," + - " PRIMARY KEY ( `%s`, `%s` ) " + - " ) COMMENT '当前序号表'"; - sql = String.format(sql, tableConfig.getTable(), - tableConfig.getKeyColumn(), - tableConfig.getTypeColumn(), - tableConfig.getSeqColumn(), - tableConfig.getKeyColumn(), - tableConfig.getTypeColumn()); - this.jdbcTemplate.execute(sql); + this.createTableByFile("create_table_sequences.sql"); } } diff --git a/src/main/java/com/yanghuanglin/seq/dao/impl/SequencesUnlockDaoImpl.java b/src/main/java/com/yanghuanglin/seq/dao/impl/SequencesUnlockDaoImpl.java index b49a280..2cde9ee 100644 --- a/src/main/java/com/yanghuanglin/seq/dao/impl/SequencesUnlockDaoImpl.java +++ b/src/main/java/com/yanghuanglin/seq/dao/impl/SequencesUnlockDaoImpl.java @@ -2,6 +2,7 @@ package com.yanghuanglin.seq.dao.impl; import com.yanghuanglin.seq.config.TableConfig; import com.yanghuanglin.seq.dao.SequencesUnlockDao; +import com.yanghuanglin.seq.enums.DbType; import com.yanghuanglin.seq.po.SequencesUnlock; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; @@ -14,20 +15,17 @@ import java.util.List; * @since 2022/1/28 */ @SuppressWarnings("SqlResolve") -public class SequencesUnlockDaoImpl implements SequencesUnlockDao { - private final JdbcTemplate jdbcTemplate; - private final TableConfig tableConfig; +public class SequencesUnlockDaoImpl extends SequencesBase implements SequencesUnlockDao { - public SequencesUnlockDaoImpl(JdbcTemplate jdbcTemplate, TableConfig tableConfig) { - this.jdbcTemplate = jdbcTemplate; - this.tableConfig = tableConfig; + public SequencesUnlockDaoImpl(JdbcTemplate jdbcTemplate, TableConfig tableConfig, DbType dbType) { + super(jdbcTemplate, tableConfig, dbType); } @Override public boolean save(SequencesUnlock sequencesUnlock) { String sql = "insert into `%s_unlock`(`%s`,`%s`,`%s`,`%s`) values(?,?,?,?)"; sql = String.format(sql, tableConfig.getTable(), tableConfig.getKeyColumn(), tableConfig.getTypeColumn(), tableConfig.getSeqColumn(), tableConfig.getCreateTimeColumn()); - int result = this.jdbcTemplate.update(sql, sequencesUnlock.getKey(), sequencesUnlock.getType(), sequencesUnlock.getSeq(), sequencesUnlock.getCreateTime()); + int result = this.jdbcTemplate.update(adapter(sql), sequencesUnlock.getKey(), sequencesUnlock.getType(), sequencesUnlock.getSeq(), sequencesUnlock.getCreateTime()); return result != 0; } @@ -38,9 +36,9 @@ public class SequencesUnlockDaoImpl implements SequencesUnlockDao { if (sequencesUnlock.getSeq() != null) { sql += " and `%s`=?"; sql = String.format(sql, tableConfig.getSeqColumn()); - return this.jdbcTemplate.update(sql, sequencesUnlock.getKey(), sequencesUnlock.getType(), sequencesUnlock.getSeq()) != 0; + return this.jdbcTemplate.update(adapter(sql), sequencesUnlock.getKey(), sequencesUnlock.getType(), sequencesUnlock.getSeq()) != 0; } else { - return this.jdbcTemplate.update(sql, sequencesUnlock.getKey(), sequencesUnlock.getType()) != 0; + return this.jdbcTemplate.update(adapter(sql), sequencesUnlock.getKey(), sequencesUnlock.getType()) != 0; } } @@ -48,7 +46,7 @@ public class SequencesUnlockDaoImpl implements SequencesUnlockDao { public List listAll() { String sql = "select * from `%s_unlock`"; sql = String.format(sql, tableConfig.getTable()); - return this.jdbcTemplate.query(sql, rowMapper()); + return this.jdbcTemplate.query(adapter(sql), rowMapper()); } @Override @@ -57,15 +55,15 @@ public class SequencesUnlockDaoImpl implements SequencesUnlockDao { if (begin != null && end != null) { sql = "select * from `%s_unlock` where `%s`>=? and `%s`<=?"; sql = String.format(sql, tableConfig.getTable(), tableConfig.getCreateTimeColumn(), tableConfig.getCreateTimeColumn()); - return this.jdbcTemplate.query(sql, rowMapper(), begin, end); + return this.jdbcTemplate.query(adapter(sql), rowMapper(), begin, end); } else if (begin != null) { sql = "select * from `%s_unlock` where `%s`>=?"; sql = String.format(sql, tableConfig.getTable(), tableConfig.getCreateTimeColumn()); - return this.jdbcTemplate.query(sql, rowMapper(), begin); + return this.jdbcTemplate.query(adapter(sql), rowMapper(), begin); } else if (end != null) { sql = "select * from `%s_unlock` where `%s`<=?"; sql = String.format(sql, tableConfig.getTable(), tableConfig.getCreateTimeColumn()); - return this.jdbcTemplate.query(sql, rowMapper(), end); + return this.jdbcTemplate.query(adapter(sql), rowMapper(), end); } else { return listAll(); } @@ -75,7 +73,7 @@ public class SequencesUnlockDaoImpl implements SequencesUnlockDao { public boolean deleteAll() { String sql = "delete from `%s_unlock`"; sql = String.format(sql, tableConfig.getTable()); - int result = this.jdbcTemplate.update(sql); + int result = this.jdbcTemplate.update(adapter(sql)); return result != 0; } @@ -85,15 +83,15 @@ public class SequencesUnlockDaoImpl implements SequencesUnlockDao { if (begin != null && end != null) { sql = "delete from `%s_unlock` where `%s`>=? and `%s`<=?"; sql = String.format(sql, tableConfig.getTable(), tableConfig.getCreateTimeColumn(), tableConfig.getCreateTimeColumn()); - return this.jdbcTemplate.update(sql, begin, end) != 0; + return this.jdbcTemplate.update(adapter(sql), begin, end) != 0; } else if (begin != null) { sql = "delete from `%s_unlock` where `%s`>=?"; sql = String.format(sql, tableConfig.getTable(), tableConfig.getCreateTimeColumn()); - return this.jdbcTemplate.update(sql, begin) != 0; + return this.jdbcTemplate.update(adapter(sql), begin) != 0; } else if (end != null) { sql = "delete from `%s_unlock` where `%s`<=?"; sql = String.format(sql, tableConfig.getTable(), tableConfig.getCreateTimeColumn()); - return this.jdbcTemplate.update(sql, end) != 0; + return this.jdbcTemplate.update(adapter(sql), end) != 0; } else { return deleteAll(); } @@ -101,22 +99,7 @@ public class SequencesUnlockDaoImpl implements SequencesUnlockDao { @Override public void createTable() { - String sql = "CREATE TABLE IF NOT EXISTS `%s_unlock` ( " + - " `%s` VARCHAR ( 64 ) NOT NULL COMMENT '序号英文名称'," + - " `%s` VARCHAR ( 64 ) NOT NULL COMMENT '序号类型'," + - " `%s` BIGINT ( 20 ) NOT NULL COMMENT '尚未锁定的序号'," + - " `%s` DATETIME NOT NULL COMMENT '使用时间'," + - " PRIMARY KEY ( `%s`, `%s` ,`%s` ) " + - " ) COMMENT '未锁定序号表'"; - sql = String.format(sql, tableConfig.getTable(), - tableConfig.getKeyColumn(), - tableConfig.getTypeColumn(), - tableConfig.getSeqColumn(), - tableConfig.getCreateTimeColumn(), - tableConfig.getKeyColumn(), - tableConfig.getTypeColumn(), - tableConfig.getSeqColumn()); - this.jdbcTemplate.execute(sql); + this.createTableByFile("create_table_sequences_unlock.sql"); } private RowMapper rowMapper() { diff --git a/src/main/java/com/yanghuanglin/seq/dao/impl/SequencesUnusedDaoImpl.java b/src/main/java/com/yanghuanglin/seq/dao/impl/SequencesUnusedDaoImpl.java index fc0de5e..582e5cd 100644 --- a/src/main/java/com/yanghuanglin/seq/dao/impl/SequencesUnusedDaoImpl.java +++ b/src/main/java/com/yanghuanglin/seq/dao/impl/SequencesUnusedDaoImpl.java @@ -2,6 +2,7 @@ package com.yanghuanglin.seq.dao.impl; import com.yanghuanglin.seq.config.TableConfig; import com.yanghuanglin.seq.dao.SequencesUnusedDao; +import com.yanghuanglin.seq.enums.DbType; import com.yanghuanglin.seq.po.SequencesUnused; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.jdbc.core.BatchPreparedStatementSetter; @@ -19,13 +20,10 @@ import java.util.List; * @since 2022/1/28 */ @SuppressWarnings("SqlResolve") -public class SequencesUnusedDaoImpl implements SequencesUnusedDao { - private final JdbcTemplate jdbcTemplate; - private final TableConfig tableConfig; +public class SequencesUnusedDaoImpl extends SequencesBase implements SequencesUnusedDao { - public SequencesUnusedDaoImpl(JdbcTemplate jdbcTemplate, TableConfig tableConfig) { - this.jdbcTemplate = jdbcTemplate; - this.tableConfig = tableConfig; + public SequencesUnusedDaoImpl(JdbcTemplate jdbcTemplate, TableConfig tableConfig, DbType dbType) { + super(jdbcTemplate, tableConfig, dbType); } @Override @@ -33,7 +31,7 @@ public class SequencesUnusedDaoImpl implements SequencesUnusedDao { String sql = "select * from `%s_unused` where `%s`=? and `%s`=? order by `%s` asc limit 0,1"; sql = String.format(sql, tableConfig.getTable(), tableConfig.getKeyColumn(), tableConfig.getTypeColumn(), tableConfig.getSeqColumn()); try { - return this.jdbcTemplate.queryForObject(sql, rowMapper(), sequencesUnused.getKey(), sequencesUnused.getType()); + return this.jdbcTemplate.queryForObject(adapter(sql), rowMapper(), sequencesUnused.getKey(), sequencesUnused.getType()); } catch (EmptyResultDataAccessException ignored) { return null; } @@ -44,7 +42,7 @@ public class SequencesUnusedDaoImpl implements SequencesUnusedDao { try { String sql = "select * from `%s_unused` where `%s`=? and `%s`=? order by `%s` desc limit 0,1"; sql = String.format(sql, tableConfig.getTable(), tableConfig.getKeyColumn(), tableConfig.getTypeColumn(), tableConfig.getSeqColumn()); - return this.jdbcTemplate.queryForObject(sql, rowMapper(), sequencesUnused.getKey(), sequencesUnused.getType()); + return this.jdbcTemplate.queryForObject(adapter(sql), rowMapper(), sequencesUnused.getKey(), sequencesUnused.getType()); } catch (EmptyResultDataAccessException ignored) { return null; } @@ -54,7 +52,7 @@ public class SequencesUnusedDaoImpl implements SequencesUnusedDao { public boolean delete(SequencesUnused sequencesUnused) { String sql = "delete from `%s_unused` where `%s`=? and `%s`=? and `%s`=?"; sql = String.format(sql, tableConfig.getTable(), tableConfig.getKeyColumn(), tableConfig.getTypeColumn(), tableConfig.getSeqColumn()); - int result = this.jdbcTemplate.update(sql, sequencesUnused.getKey(), sequencesUnused.getType(), sequencesUnused.getSeq()); + int result = this.jdbcTemplate.update(adapter(sql), sequencesUnused.getKey(), sequencesUnused.getType(), sequencesUnused.getSeq()); return result != 0; } @@ -62,7 +60,7 @@ public class SequencesUnusedDaoImpl implements SequencesUnusedDao { public boolean save(SequencesUnused sequencesUnused) { String sql = "insert into `%s_unused`(`%s`,`%s`,`%s`,`%s`) values(?,?,?,?)"; sql = String.format(sql, tableConfig.getTable(), tableConfig.getKeyColumn(), tableConfig.getTypeColumn(), tableConfig.getSeqColumn(), tableConfig.getCreateTimeColumn()); - int result = this.jdbcTemplate.update(sql, sequencesUnused.getKey(), sequencesUnused.getType(), sequencesUnused.getSeq(), sequencesUnused.getCreateTime()); + int result = this.jdbcTemplate.update(adapter(sql), sequencesUnused.getKey(), sequencesUnused.getType(), sequencesUnused.getSeq(), sequencesUnused.getCreateTime()); return result != 0; } @@ -70,7 +68,7 @@ public class SequencesUnusedDaoImpl implements SequencesUnusedDao { public boolean saveBatch(List sequencesUnusedList) { String sql = "insert into `%s_unused`(`%s`,`%s`,`%s`,`%s`) values(?,?,?,?)"; sql = String.format(sql, tableConfig.getTable(), tableConfig.getKeyColumn(), tableConfig.getTypeColumn(), tableConfig.getSeqColumn(), tableConfig.getCreateTimeColumn()); - int[] result = this.jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() { + int[] result = this.jdbcTemplate.batchUpdate(adapter(sql), new BatchPreparedStatementSetter() { @Override public void setValues(PreparedStatement ps, int i) throws SQLException { SequencesUnused sequencesUnused = sequencesUnusedList.get(i); @@ -90,29 +88,14 @@ public class SequencesUnusedDaoImpl implements SequencesUnusedDao { @Override public void createTable() { - String sql = "CREATE TABLE IF NOT EXISTS `%s_unused` ( " + - " `%s` VARCHAR ( 64 ) NOT NULL COMMENT '序号英文名称'," + - " `%s` VARCHAR ( 64 ) NOT NULL COMMENT '序号类型'," + - " `%s` BIGINT ( 20 ) NOT NULL COMMENT '闲置的的序号'," + - " `%s` DATETIME NOT NULL COMMENT '设为闲置序号的时间'," + - " PRIMARY KEY ( `%s`, `%s`, `%s` ) " + - " ) COMMENT '闲置序号表'"; - sql = String.format(sql, tableConfig.getTable(), - tableConfig.getKeyColumn(), - tableConfig.getTypeColumn(), - tableConfig.getSeqColumn(), - tableConfig.getCreateTimeColumn(), - tableConfig.getKeyColumn(), - tableConfig.getTypeColumn(), - tableConfig.getSeqColumn()); - this.jdbcTemplate.execute(sql); + this.createTableByFile("create_table_sequences_unused.sql"); } @Override public boolean deleteAll() { String sql = "delete from `%s_unused`"; sql = String.format(sql, tableConfig.getTable()); - int result = this.jdbcTemplate.update(sql); + int result = this.jdbcTemplate.update(adapter(sql)); return result != 0; } @@ -122,15 +105,15 @@ public class SequencesUnusedDaoImpl implements SequencesUnusedDao { if (begin != null && end != null) { sql = "delete from `%s_unused` where `%s`>=? and `%s`<=?"; sql = String.format(sql, tableConfig.getTable(), tableConfig.getCreateTimeColumn(), tableConfig.getCreateTimeColumn()); - return this.jdbcTemplate.update(sql, begin, end) != 0; + return this.jdbcTemplate.update(adapter(sql), begin, end) != 0; } else if (begin != null) { sql = "delete from `%s_unused` where `%s`>=?"; sql = String.format(sql, tableConfig.getTable(), tableConfig.getCreateTimeColumn()); - return this.jdbcTemplate.update(sql, begin) != 0; + return this.jdbcTemplate.update(adapter(sql), begin) != 0; } else if (end != null) { sql = "delete from `%s_unused` where `%s`<=?"; sql = String.format(sql, tableConfig.getTable(), tableConfig.getCreateTimeColumn()); - return this.jdbcTemplate.update(sql, end) != 0; + return this.jdbcTemplate.update(adapter(sql), end) != 0; } else { return deleteAll(); } diff --git a/src/main/java/com/yanghuanglin/seq/enums/DbType.java b/src/main/java/com/yanghuanglin/seq/enums/DbType.java new file mode 100644 index 0000000..cbacebf --- /dev/null +++ b/src/main/java/com/yanghuanglin/seq/enums/DbType.java @@ -0,0 +1,35 @@ +package com.yanghuanglin.seq.enums; + +public enum DbType { + //MySQL数据库 + MySQL("mysql"), + //人大金仓数据库 + KingbaseES("pgsql"), + //PostgreSQL数据库 + PostgreSQL("pgsql"); + + private final String series; + + DbType(String series) { + this.series = series; + } + + public String getSeries() { + return series; + } + + /** + * 根据数据库类型获取对应枚举 + * + * @param productName 数据库类型 + * @return 枚举 + */ + public static DbType of(String productName) { + for (DbType value : DbType.values()) { + if (value.name().equalsIgnoreCase(productName)) { + return value; + } + } + throw new RuntimeException("不支持的数据库类型"); + } +} diff --git a/src/main/java/com/yanghuanglin/seq/generator/Generator.java b/src/main/java/com/yanghuanglin/seq/generator/Generator.java index ad3dbf5..f4194ca 100644 --- a/src/main/java/com/yanghuanglin/seq/generator/Generator.java +++ b/src/main/java/com/yanghuanglin/seq/generator/Generator.java @@ -315,4 +315,9 @@ public interface Generator { * @param end 结束时间 */ void clearBefore(Date end); + + /** + * 创建表 + */ + void createTable(); } diff --git a/src/main/java/com/yanghuanglin/seq/generator/impl/SequencesGenerator.java b/src/main/java/com/yanghuanglin/seq/generator/impl/SequencesGenerator.java index 39c97ce..e76ae7a 100644 --- a/src/main/java/com/yanghuanglin/seq/generator/impl/SequencesGenerator.java +++ b/src/main/java/com/yanghuanglin/seq/generator/impl/SequencesGenerator.java @@ -57,12 +57,16 @@ public class SequencesGenerator implements Generator { private synchronized void createTable(Boolean autoCreate) { if (!autoCreate) return; + this.createTable(); + } + + @Override + public synchronized void createTable() { this.sequencesDao.createTable(); this.sequencesUnusedDao.createTable(); this.sequencesUnlockDao.createTable(); } - @Override public boolean containSeq(String pattern) { return StringUtils.hasLength(pattern) && pattern.contains(SEQ.getPlaceholder()); diff --git a/src/main/resources/mysql/create_table_sequences.sql b/src/main/resources/mysql/create_table_sequences.sql new file mode 100644 index 0000000..aa2b45d --- /dev/null +++ b/src/main/resources/mysql/create_table_sequences.sql @@ -0,0 +1,7 @@ +CREATE TABLE IF NOT EXISTS `sequences` +( + `key` VARCHAR(64) NOT NULL COMMENT '序号英文名称', + `type` VARCHAR(64) NOT NULL COMMENT '序号类型', + `seq` BIGINT(20) NOT NULL COMMENT '已使用到的序号', + PRIMARY KEY (`key`, `type`) +) COMMENT '当前序号表'; \ No newline at end of file diff --git a/src/main/resources/mysql/create_table_sequences_unlock.sql b/src/main/resources/mysql/create_table_sequences_unlock.sql new file mode 100644 index 0000000..165c90d --- /dev/null +++ b/src/main/resources/mysql/create_table_sequences_unlock.sql @@ -0,0 +1,8 @@ +CREATE TABLE IF NOT EXISTS `sequences_unlock` +( + `key` VARCHAR(64) NOT NULL COMMENT '序号英文名称', + `type` VARCHAR(64) NOT NULL COMMENT '序号类型', + `seq` BIGINT(20) NOT NULL COMMENT '尚未锁定的序号', + `create_time` DATETIME NOT NULL COMMENT '使用时间', + PRIMARY KEY (`key`, `type`, `seq`) +) COMMENT '未锁定序号表'; \ No newline at end of file diff --git a/src/main/resources/mysql/create_table_sequences_unused.sql b/src/main/resources/mysql/create_table_sequences_unused.sql new file mode 100644 index 0000000..a34da18 --- /dev/null +++ b/src/main/resources/mysql/create_table_sequences_unused.sql @@ -0,0 +1,8 @@ +CREATE TABLE IF NOT EXISTS `sequences_unused` +( + `key` VARCHAR(64) NOT NULL COMMENT '序号英文名称', + `type` VARCHAR(64) NOT NULL COMMENT '序号类型', + `seq` BIGINT(20) NOT NULL COMMENT '闲置的的序号', + `create_time` DATETIME NOT NULL COMMENT '设为闲置序号的时间', + PRIMARY KEY (`key`, `type`, `seq`) +) COMMENT '闲置序号表'; \ No newline at end of file diff --git a/src/main/resources/pgsql/create_table_sequences.sql b/src/main/resources/pgsql/create_table_sequences.sql new file mode 100644 index 0000000..b964399 --- /dev/null +++ b/src/main/resources/pgsql/create_table_sequences.sql @@ -0,0 +1,11 @@ +CREATE TABLE IF NOT EXISTS "sequences" +( + "key" VARCHAR(64) NOT NULL, + "type" VARCHAR(64) NOT NULL, + "seq" INT8 NOT NULL, + PRIMARY KEY ("key", "type") +); +COMMENT ON TABLE "sequences" IS '当前序号表'; +COMMENT ON COLUMN "sequences"."key" IS '序号英文名称'; +COMMENT ON COLUMN "sequences"."type" IS '序号类型'; +COMMENT ON COLUMN "sequences"."seq" IS '已使用到的序号'; \ No newline at end of file diff --git a/src/main/resources/pgsql/create_table_sequences_unlock.sql b/src/main/resources/pgsql/create_table_sequences_unlock.sql new file mode 100644 index 0000000..d37c7e4 --- /dev/null +++ b/src/main/resources/pgsql/create_table_sequences_unlock.sql @@ -0,0 +1,13 @@ +CREATE TABLE IF NOT EXISTS "sequences_unlock" +( + "key" VARCHAR(64) NOT NULL, + "type" VARCHAR(64) NOT NULL, + "seq" INT8 NOT NULL, + "create_time" TIMESTAMP NOT NULL, + PRIMARY KEY ("key", "type", "seq") +); +COMMENT ON TABLE "sequences_unlock" IS '未锁定序号表'; +COMMENT ON COLUMN "sequences_unlock"."key" IS '序号英文名称'; +COMMENT ON COLUMN "sequences_unlock"."type" IS '序号类型'; +COMMENT ON COLUMN "sequences_unlock"."seq" IS '尚未锁定的序号'; +COMMENT ON COLUMN "sequences_unlock"."create_time" IS '使用时间'; \ No newline at end of file diff --git a/src/main/resources/pgsql/create_table_sequences_unused.sql b/src/main/resources/pgsql/create_table_sequences_unused.sql new file mode 100644 index 0000000..b190c24 --- /dev/null +++ b/src/main/resources/pgsql/create_table_sequences_unused.sql @@ -0,0 +1,13 @@ +CREATE TABLE IF NOT EXISTS "sequences_unused" +( + "key" VARCHAR(64) NOT NULL, + "type" VARCHAR(64) NOT NULL, + "seq" INT8 NOT NULL, + "create_time" TIMESTAMP NOT NULL, + PRIMARY KEY ("key", "type", "seq") +); +COMMENT ON TABLE "sequences_unused" IS '闲置序号表'; +COMMENT ON COLUMN "sequences_unused"."key" IS '序号英文名称'; +COMMENT ON COLUMN "sequences_unused"."type" IS '序号类型'; +COMMENT ON COLUMN "sequences_unused"."seq" IS '闲置的的序号'; +COMMENT ON COLUMN "sequences_unused"."create_time" IS '设为闲置序号的时间'; \ No newline at end of file diff --git a/src/test/java/SeqTest.java b/src/test/java/SeqTest.java index e75e215..94496a5 100644 --- a/src/test/java/SeqTest.java +++ b/src/test/java/SeqTest.java @@ -1,3 +1,4 @@ +import com.kingbase8.ds.KBSimpleDataSource; import com.mysql.cj.jdbc.MysqlDataSource; import com.yanghuanglin.seq.config.GeneratorConfig; import com.yanghuanglin.seq.config.TableConfig; @@ -5,7 +6,9 @@ import com.yanghuanglin.seq.generator.Generator; import com.yanghuanglin.seq.generator.impl.SequencesGenerator; import com.yanghuanglin.seq.po.Sequences; import org.junit.Test; +import org.postgresql.ds.PGSimpleDataSource; +import javax.sql.DataSource; import java.util.HashSet; import java.util.Set; import java.util.concurrent.ArrayBlockingQueue; @@ -17,15 +20,14 @@ import java.util.concurrent.TimeUnit; * @since 2022/1/28 */ public class SeqTest { - private static final MysqlDataSource dataSource = new MysqlDataSource(); + private static final DataSource dataSource; private static final Generator generator; static { - dataSource.setURL("jdbc:mysql://127.0.0.1:3306/sequence"); - dataSource.setUser("root"); - dataSource.setPassword("root"); + dataSource = pgsql(); GeneratorConfig generatorConfig = new GeneratorConfig(dataSource); + System.out.println("DbType: " + generatorConfig.getDbType()); TableConfig tableConfig = new TableConfig(); tableConfig.setTable("sequences"); @@ -39,6 +41,35 @@ public class SeqTest { generator = new SequencesGenerator(generatorConfig); } + private static DataSource mysql() { + MysqlDataSource mysqlDataSource = new MysqlDataSource(); + mysqlDataSource.setURL("jdbc:mysql://127.0.0.1:3306/sequence"); + mysqlDataSource.setUser("root"); + mysqlDataSource.setPassword("root"); + return mysqlDataSource; + } + + private static DataSource kingbase8() { + KBSimpleDataSource kbDataSource = new KBSimpleDataSource(); + kbDataSource.setURL("jdbc:kingbase8://127.0.0.1:54321/cemis?currentSchema=sequence"); + kbDataSource.setUser("kingbase"); + kbDataSource.setPassword("kingbase"); + return kbDataSource; + } + + private static DataSource pgsql() { + PGSimpleDataSource pgDataSource = new PGSimpleDataSource(); + pgDataSource.setURL("jdbc:postgresql://127.0.0.1:54321/cemis?currentSchema=sequence"); + pgDataSource.setUser("kingbase"); + pgDataSource.setPassword("kingbase"); + return pgDataSource; + } + + @Test + public void createTable() { + generator.createTable(); + } + @Test public void generateTest() { //释放未锁定序列号