diff --git a/pom.xml b/pom.xml
index a8d4ce6..9d17db9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -4,7 +4,7 @@
4.0.0
com.yanghuanglin
seq
- 1.10.0
+ 1.11.0
seq
seq
diff --git a/src/main/java/com/yanghuanglin/seq/config/TableConfig.java b/src/main/java/com/yanghuanglin/seq/config/TableConfig.java
index dbac42a..10705ac 100644
--- a/src/main/java/com/yanghuanglin/seq/config/TableConfig.java
+++ b/src/main/java/com/yanghuanglin/seq/config/TableConfig.java
@@ -32,6 +32,11 @@ public class TableConfig {
*/
private String createTimeColumn = "create_time";
+ /**
+ * 序号表中最后使用时间
+ */
+ private String updateTimeColumn = "update_time";
+
public String getTable() {
return table;
}
@@ -71,4 +76,12 @@ public class TableConfig {
public void setCreateTimeColumn(String createTimeColumn) {
this.createTimeColumn = createTimeColumn.toLowerCase();
}
+
+ public String getUpdateTimeColumn() {
+ return updateTimeColumn;
+ }
+
+ public void setUpdateTimeColumn(String updateTimeColumn) {
+ this.updateTimeColumn = updateTimeColumn;
+ }
}
\ No newline at end of file
diff --git a/src/main/java/com/yanghuanglin/seq/dao/SequencesUnlockDao.java b/src/main/java/com/yanghuanglin/seq/dao/SequencesUnlockDao.java
index c9ab8bd..49baebc 100644
--- a/src/main/java/com/yanghuanglin/seq/dao/SequencesUnlockDao.java
+++ b/src/main/java/com/yanghuanglin/seq/dao/SequencesUnlockDao.java
@@ -10,6 +10,11 @@ import java.util.List;
* @since 2022/1/28
*/
public interface SequencesUnlockDao {
+ /**
+ * 查找某个未被锁定的序号
+ */
+ SequencesUnlock find(SequencesUnlock sequencesUnlock);
+
/**
* 保存使用中的序号
*/
diff --git a/src/main/java/com/yanghuanglin/seq/dao/SequencesUnusedDao.java b/src/main/java/com/yanghuanglin/seq/dao/SequencesUnusedDao.java
index d44dc56..af1eb23 100644
--- a/src/main/java/com/yanghuanglin/seq/dao/SequencesUnusedDao.java
+++ b/src/main/java/com/yanghuanglin/seq/dao/SequencesUnusedDao.java
@@ -11,6 +11,11 @@ import java.util.List;
*/
public interface SequencesUnusedDao {
+ /**
+ * 查找某个未被使用的序号
+ */
+ SequencesUnused find(SequencesUnused sequencesUnused);
+
/**
* 根据key,type查找seq最小的空闲序号
*/
diff --git a/src/main/java/com/yanghuanglin/seq/dao/impl/SequencesBase.java b/src/main/java/com/yanghuanglin/seq/dao/impl/SequencesBase.java
index ab0890a..22f208c 100644
--- a/src/main/java/com/yanghuanglin/seq/dao/impl/SequencesBase.java
+++ b/src/main/java/com/yanghuanglin/seq/dao/impl/SequencesBase.java
@@ -49,6 +49,7 @@ public abstract class SequencesBase {
sql = sql.replaceAll("`seq`", String.format("`%s`", tableConfig.getSeqColumn()));
sql = sql.replaceAll("`create_time`", String.format("`%s`", tableConfig.getCreateTimeColumn()));
break;
+ case Dameng:
case PostgreSQL:
case KingbaseES:
sql = sql.replaceAll("\"sequences(_unused|_unlock)\"", String.format("%s$1", tableConfig.getTable()));
@@ -72,11 +73,12 @@ public abstract class SequencesBase {
* @param sqlString sql语句
* @return 处理后的语句
*/
- protected String adapter(String sqlString) {
+ protected String dbAdapter(String sqlString) {
switch (dbType) {
case MySQL:
break;
case PostgreSQL:
+ case Dameng:
case KingbaseES:
sqlString = sqlString.replaceAll("`(.+?)`", "\"$1\"");
break;
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 5f5720e..c50d720 100644
--- a/src/main/java/com/yanghuanglin/seq/dao/impl/SequencesDaoImpl.java
+++ b/src/main/java/com/yanghuanglin/seq/dao/impl/SequencesDaoImpl.java
@@ -12,7 +12,7 @@ import org.springframework.jdbc.core.JdbcTemplate;
* @author yanghuanglin
* @since 2022/1/28
*/
-@SuppressWarnings("SqlResolve")
+@SuppressWarnings({"SqlResolve", "SqlSourceToSinkFlow"})
public class SequencesDaoImpl extends SequencesBase implements SequencesDao {
public SequencesDaoImpl(JdbcTemplate jdbcTemplate, TableConfig tableConfig, DbType dbType) {
@@ -24,11 +24,12 @@ public class SequencesDaoImpl extends SequencesBase 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(adapter(sql), (rs, rowNum) -> {
+ return this.jdbcTemplate.queryForObject(dbAdapter(sql), (rs, rowNum) -> {
Sequences result = new Sequences();
result.setKey(rs.getString(tableConfig.getKeyColumn()));
result.setType(rs.getString(tableConfig.getTypeColumn()));
result.setSeq(rs.getLong(tableConfig.getSeqColumn()));
+ result.setUpdateTime(rs.getDate(tableConfig.getUpdateTimeColumn()));
return result;
}, sequences.getKey(), sequences.getType());
} catch (EmptyResultDataAccessException ignored) {
@@ -40,7 +41,7 @@ public class SequencesDaoImpl extends SequencesBase 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(adapter(sql), sequences.getKey(), sequences.getType(), sequences.getSeq());
+ int result = this.jdbcTemplate.update(dbAdapter(sql), sequences.getKey(), sequences.getType(), sequences.getSeq());
return result != 0;
}
@@ -48,7 +49,7 @@ public class SequencesDaoImpl extends SequencesBase 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(adapter(sql), sequences.getSeq(), sequences.getKey(), sequences.getType());
+ int result = this.jdbcTemplate.update(dbAdapter(sql), sequences.getSeq(), sequences.getKey(), sequences.getType());
return result != 0;
}
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 2cde9ee..bed5255 100644
--- a/src/main/java/com/yanghuanglin/seq/dao/impl/SequencesUnlockDaoImpl.java
+++ b/src/main/java/com/yanghuanglin/seq/dao/impl/SequencesUnlockDaoImpl.java
@@ -4,6 +4,7 @@ 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.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
@@ -14,18 +15,36 @@ import java.util.List;
* @author yanghuanglin
* @since 2022/1/28
*/
-@SuppressWarnings("SqlResolve")
+@SuppressWarnings({"SqlResolve", "SqlSourceToSinkFlow"})
public class SequencesUnlockDaoImpl extends SequencesBase implements SequencesUnlockDao {
public SequencesUnlockDaoImpl(JdbcTemplate jdbcTemplate, TableConfig tableConfig, DbType dbType) {
super(jdbcTemplate, tableConfig, dbType);
}
+ @Override
+ public SequencesUnlock find(SequencesUnlock sequencesUnlock) {
+ String sql = "select * from `%s_unlock` where `%s`=? and `%s`=? and `%s`=?";
+ sql = String.format(sql, tableConfig.getTable(), tableConfig.getKeyColumn(), tableConfig.getTypeColumn(), tableConfig.getSeqColumn());
+ try {
+ return this.jdbcTemplate.queryForObject(dbAdapter(sql), (rs, rowNum) -> {
+ SequencesUnlock result = new SequencesUnlock();
+ result.setKey(rs.getString(tableConfig.getKeyColumn()));
+ result.setType(rs.getString(tableConfig.getTypeColumn()));
+ result.setSeq(rs.getLong(tableConfig.getSeqColumn()));
+ result.setCreateTime(rs.getDate(tableConfig.getCreateTimeColumn()));
+ return result;
+ }, sequencesUnlock.getKey(), sequencesUnlock.getType(), sequencesUnlock.getSeq());
+ } catch (EmptyResultDataAccessException ignored) {
+ return null;
+ }
+ }
+
@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(adapter(sql), sequencesUnlock.getKey(), sequencesUnlock.getType(), sequencesUnlock.getSeq(), sequencesUnlock.getCreateTime());
+ int result = this.jdbcTemplate.update(dbAdapter(sql), sequencesUnlock.getKey(), sequencesUnlock.getType(), sequencesUnlock.getSeq(), sequencesUnlock.getCreateTime());
return result != 0;
}
@@ -36,9 +55,9 @@ public class SequencesUnlockDaoImpl extends SequencesBase implements SequencesUn
if (sequencesUnlock.getSeq() != null) {
sql += " and `%s`=?";
sql = String.format(sql, tableConfig.getSeqColumn());
- return this.jdbcTemplate.update(adapter(sql), sequencesUnlock.getKey(), sequencesUnlock.getType(), sequencesUnlock.getSeq()) != 0;
+ return this.jdbcTemplate.update(dbAdapter(sql), sequencesUnlock.getKey(), sequencesUnlock.getType(), sequencesUnlock.getSeq()) != 0;
} else {
- return this.jdbcTemplate.update(adapter(sql), sequencesUnlock.getKey(), sequencesUnlock.getType()) != 0;
+ return this.jdbcTemplate.update(dbAdapter(sql), sequencesUnlock.getKey(), sequencesUnlock.getType()) != 0;
}
}
@@ -46,7 +65,7 @@ public class SequencesUnlockDaoImpl extends SequencesBase implements SequencesUn
public List listAll() {
String sql = "select * from `%s_unlock`";
sql = String.format(sql, tableConfig.getTable());
- return this.jdbcTemplate.query(adapter(sql), rowMapper());
+ return this.jdbcTemplate.query(dbAdapter(sql), rowMapper());
}
@Override
@@ -55,15 +74,15 @@ public class SequencesUnlockDaoImpl extends SequencesBase implements SequencesUn
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(adapter(sql), rowMapper(), begin, end);
+ return this.jdbcTemplate.query(dbAdapter(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(adapter(sql), rowMapper(), begin);
+ return this.jdbcTemplate.query(dbAdapter(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(adapter(sql), rowMapper(), end);
+ return this.jdbcTemplate.query(dbAdapter(sql), rowMapper(), end);
} else {
return listAll();
}
@@ -73,7 +92,7 @@ public class SequencesUnlockDaoImpl extends SequencesBase implements SequencesUn
public boolean deleteAll() {
String sql = "delete from `%s_unlock`";
sql = String.format(sql, tableConfig.getTable());
- int result = this.jdbcTemplate.update(adapter(sql));
+ int result = this.jdbcTemplate.update(dbAdapter(sql));
return result != 0;
}
@@ -83,15 +102,15 @@ public class SequencesUnlockDaoImpl extends SequencesBase implements SequencesUn
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(adapter(sql), begin, end) != 0;
+ return this.jdbcTemplate.update(dbAdapter(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(adapter(sql), begin) != 0;
+ return this.jdbcTemplate.update(dbAdapter(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(adapter(sql), end) != 0;
+ return this.jdbcTemplate.update(dbAdapter(sql), end) != 0;
} else {
return deleteAll();
}
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 582e5cd..322b27f 100644
--- a/src/main/java/com/yanghuanglin/seq/dao/impl/SequencesUnusedDaoImpl.java
+++ b/src/main/java/com/yanghuanglin/seq/dao/impl/SequencesUnusedDaoImpl.java
@@ -19,19 +19,37 @@ import java.util.List;
* @author yanghuanglin
* @since 2022/1/28
*/
-@SuppressWarnings("SqlResolve")
+@SuppressWarnings({"SqlResolve", "SqlSourceToSinkFlow"})
public class SequencesUnusedDaoImpl extends SequencesBase implements SequencesUnusedDao {
public SequencesUnusedDaoImpl(JdbcTemplate jdbcTemplate, TableConfig tableConfig, DbType dbType) {
super(jdbcTemplate, tableConfig, dbType);
}
+ @Override
+ public SequencesUnused find(SequencesUnused sequencesUnused) {
+ String sql = "select * from `%s_unused` where `%s`=? and `%s`=? and `%s`=?";
+ sql = String.format(sql, tableConfig.getTable(), tableConfig.getKeyColumn(), tableConfig.getTypeColumn(), tableConfig.getSeqColumn());
+ try {
+ return this.jdbcTemplate.queryForObject(dbAdapter(sql), (rs, rowNum) -> {
+ SequencesUnused result = new SequencesUnused();
+ result.setKey(rs.getString(tableConfig.getKeyColumn()));
+ result.setType(rs.getString(tableConfig.getTypeColumn()));
+ result.setSeq(rs.getLong(tableConfig.getSeqColumn()));
+ result.setCreateTime(rs.getDate(tableConfig.getCreateTimeColumn()));
+ return result;
+ }, sequencesUnused.getKey(), sequencesUnused.getType(), sequencesUnused.getSeq());
+ } catch (EmptyResultDataAccessException ignored) {
+ return null;
+ }
+ }
+
@Override
public SequencesUnused findMinSeq(SequencesUnused sequencesUnused) {
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(adapter(sql), rowMapper(), sequencesUnused.getKey(), sequencesUnused.getType());
+ return this.jdbcTemplate.queryForObject(dbAdapter(sql), rowMapper(), sequencesUnused.getKey(), sequencesUnused.getType());
} catch (EmptyResultDataAccessException ignored) {
return null;
}
@@ -42,7 +60,7 @@ public class SequencesUnusedDaoImpl extends SequencesBase implements SequencesUn
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(adapter(sql), rowMapper(), sequencesUnused.getKey(), sequencesUnused.getType());
+ return this.jdbcTemplate.queryForObject(dbAdapter(sql), rowMapper(), sequencesUnused.getKey(), sequencesUnused.getType());
} catch (EmptyResultDataAccessException ignored) {
return null;
}
@@ -52,7 +70,7 @@ public class SequencesUnusedDaoImpl extends SequencesBase implements SequencesUn
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(adapter(sql), sequencesUnused.getKey(), sequencesUnused.getType(), sequencesUnused.getSeq());
+ int result = this.jdbcTemplate.update(dbAdapter(sql), sequencesUnused.getKey(), sequencesUnused.getType(), sequencesUnused.getSeq());
return result != 0;
}
@@ -60,7 +78,7 @@ public class SequencesUnusedDaoImpl extends SequencesBase implements SequencesUn
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(adapter(sql), sequencesUnused.getKey(), sequencesUnused.getType(), sequencesUnused.getSeq(), sequencesUnused.getCreateTime());
+ int result = this.jdbcTemplate.update(dbAdapter(sql), sequencesUnused.getKey(), sequencesUnused.getType(), sequencesUnused.getSeq(), sequencesUnused.getCreateTime());
return result != 0;
}
@@ -68,7 +86,7 @@ public class SequencesUnusedDaoImpl extends SequencesBase implements SequencesUn
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(adapter(sql), new BatchPreparedStatementSetter() {
+ int[] result = this.jdbcTemplate.batchUpdate(dbAdapter(sql), new BatchPreparedStatementSetter() {
@Override
public void setValues(PreparedStatement ps, int i) throws SQLException {
SequencesUnused sequencesUnused = sequencesUnusedList.get(i);
@@ -95,7 +113,7 @@ public class SequencesUnusedDaoImpl extends SequencesBase implements SequencesUn
public boolean deleteAll() {
String sql = "delete from `%s_unused`";
sql = String.format(sql, tableConfig.getTable());
- int result = this.jdbcTemplate.update(adapter(sql));
+ int result = this.jdbcTemplate.update(dbAdapter(sql));
return result != 0;
}
@@ -105,15 +123,15 @@ public class SequencesUnusedDaoImpl extends SequencesBase implements SequencesUn
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(adapter(sql), begin, end) != 0;
+ return this.jdbcTemplate.update(dbAdapter(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(adapter(sql), begin) != 0;
+ return this.jdbcTemplate.update(dbAdapter(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(adapter(sql), end) != 0;
+ return this.jdbcTemplate.update(dbAdapter(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
index cbacebf..b512cfe 100644
--- a/src/main/java/com/yanghuanglin/seq/enums/DbType.java
+++ b/src/main/java/com/yanghuanglin/seq/enums/DbType.java
@@ -3,6 +3,8 @@ package com.yanghuanglin.seq.enums;
public enum DbType {
//MySQL数据库
MySQL("mysql"),
+ //达梦数据库
+ Dameng("dm"),
//人大金仓数据库
KingbaseES("pgsql"),
//PostgreSQL数据库
diff --git a/src/main/java/com/yanghuanglin/seq/generator/Generator.java b/src/main/java/com/yanghuanglin/seq/generator/Generator.java
index f4194ca..70e0638 100644
--- a/src/main/java/com/yanghuanglin/seq/generator/Generator.java
+++ b/src/main/java/com/yanghuanglin/seq/generator/Generator.java
@@ -221,6 +221,14 @@ public interface Generator {
*/
Sequences parse(String formatted, String pattern, Integer fixLength);
+ /**
+ * 查询序号是否已被锁定
+ *
+ * @param sequences 需要查询的序号
+ * @return 锁定结果
+ */
+ boolean locked(Sequences sequences);
+
/**
* 锁定指定序号,在序号生成后,调用该序号的逻辑完成后需要执行此方法
*
@@ -244,6 +252,14 @@ public interface Generator {
*/
boolean lock(Sequences sequences, boolean ignoreSeq);
+ /**
+ * 将序号设为未使用
+ *
+ * @param sequences 需要设为未使用的序号
+ * @return 设置结果
+ */
+ boolean unused(Sequences sequences);
+
/**
* 释放所有未使用的序号
*
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 e76ae7a..c9a64ee 100644
--- a/src/main/java/com/yanghuanglin/seq/generator/impl/SequencesGenerator.java
+++ b/src/main/java/com/yanghuanglin/seq/generator/impl/SequencesGenerator.java
@@ -22,6 +22,7 @@ import java.util.regex.Pattern;
import static com.yanghuanglin.seq.enums.FormatPlaceholder.*;
+@SuppressWarnings("CallToPrintStackTrace")
public class SequencesGenerator implements Generator {
private final TransactionTemplate transactionTemplate;
private final SequencesDao sequencesDao;
@@ -89,7 +90,11 @@ public class SequencesGenerator implements Generator {
//根据传入的key和type新生成查询条件对象
Sequences condition = new Sequences(key, type);
- if (!withOutSeq) {
+ if (Boolean.TRUE.equals(withOutSeq)) {
+ //不包含序号
+ condition.setWithOutSeq(true);
+ return condition;
+ } else {
//不是不包含序号的序号对象(有可能格式中只配置了#year##month##day#,序号就不用自增,也不用入库,直接返回即可)
//找到正在使用的最大序号
Sequences sequences = sequencesDao.find(condition);
@@ -123,9 +128,6 @@ public class SequencesGenerator implements Generator {
}
sequences.setWithOutSeq(false);
return result ? sequences : null;
- } else {
- condition.setWithOutSeq(true);
- return condition;
}
} catch (Exception e) {
e.printStackTrace();
@@ -305,10 +307,30 @@ public class SequencesGenerator implements Generator {
}
@Override
- public synchronized boolean lock(Sequences sequences) {
- if (sequences == null || sequences.getWithOutSeq())
+ public boolean locked(Sequences sequences) {
+ if (sequences == null || Boolean.TRUE.equals(sequences.getWithOutSeq()))
return true;
SequencesUnlock condition = new SequencesUnlock(sequences);
+
+ //将使用中表的对应数据删除,空闲表中数据在生成时会删除,因此这里不需要处理该表
+ return Boolean.TRUE.equals(transactionTemplate.execute(status -> {
+ try {
+ SequencesUnlock sequencesUnlock = sequencesUnlockDao.find(condition);
+ return sequencesUnlock == null;
+ } catch (Exception e) {
+ e.printStackTrace();
+ status.setRollbackOnly();
+ return false;
+ }
+ }));
+ }
+
+ @Override
+ public synchronized boolean lock(Sequences sequences) {
+ if (sequences == null || Boolean.TRUE.equals(sequences.getWithOutSeq()))
+ return true;
+ SequencesUnlock condition = new SequencesUnlock(sequences);
+
//将使用中表的对应数据删除,空闲表中数据在生成时会删除,因此这里不需要处理该表
return Boolean.TRUE.equals(transactionTemplate.execute(status -> {
try {
@@ -325,7 +347,7 @@ public class SequencesGenerator implements Generator {
public synchronized boolean lock(Sequences sequences, boolean ignoreSeq) {
if (!ignoreSeq)
return lock(sequences);
- if (sequences == null || sequences.getWithOutSeq())
+ if (sequences == null || Boolean.TRUE.equals(sequences.getWithOutSeq()))
return true;
SequencesUnlock condition = new SequencesUnlock(sequences);
condition.setSeq(null);
@@ -341,6 +363,24 @@ public class SequencesGenerator implements Generator {
}));
}
+ @Override
+ public boolean unused(Sequences sequences) {
+ if (sequences == null)
+ return true;
+ SequencesUnused condition = new SequencesUnused(sequences);
+ condition.setCreateTime(new Date());
+ //在未使用中表增加需要设为未使用的序号
+ return Boolean.TRUE.equals(transactionTemplate.execute(status -> {
+ try {
+ return sequencesUnusedDao.save(condition);
+ } catch (Exception e) {
+ e.printStackTrace();
+ status.setRollbackOnly();
+ return false;
+ }
+ }));
+ }
+
@Override
public synchronized boolean release() {
//列出所有使用中表存在的序号
diff --git a/src/main/java/com/yanghuanglin/seq/po/Sequences.java b/src/main/java/com/yanghuanglin/seq/po/Sequences.java
index 4ccd225..bdc114b 100644
--- a/src/main/java/com/yanghuanglin/seq/po/Sequences.java
+++ b/src/main/java/com/yanghuanglin/seq/po/Sequences.java
@@ -2,6 +2,8 @@ package com.yanghuanglin.seq.po;
import com.yanghuanglin.seq.config.BaseConfig;
+import java.util.Date;
+
/**
* 当前序号
*
@@ -24,6 +26,11 @@ public class Sequences {
*/
protected Long seq = 0L;
+ /**
+ * 最后使用时间
+ */
+ private Date updateTime;
+
/**
* 临时字段,序号对应的年份(如2022年)(如果能获取到的话)。
* 该字段仅用于解析序号字符串时,解析出对应年份,用于合成key(如:序号对应的key为SNT+年份,返回的为其年份)
@@ -101,6 +108,14 @@ public class Sequences {
this.seq = seq;
}
+ public Date getUpdateTime() {
+ return updateTime;
+ }
+
+ public void setUpdateTime(Date updateTime) {
+ this.updateTime = updateTime;
+ }
+
public Integer getYear() {
return year;
}
@@ -180,10 +195,11 @@ public class Sequences {
"key='" + key + '\'' +
", type='" + type + '\'' +
", seq=" + seq +
+ ", updateTime=" + updateTime +
", year=" + year +
", month=" + month +
", day=" + day +
- ", fix=" + fix +
+ ", fix='" + fix + '\'' +
", withOutSeq=" + withOutSeq +
'}';
}
diff --git a/src/main/resources/dm/create_table_sequences.sql b/src/main/resources/dm/create_table_sequences.sql
new file mode 100644
index 0000000..7f92767
--- /dev/null
+++ b/src/main/resources/dm/create_table_sequences.sql
@@ -0,0 +1,26 @@
+CREATE TABLE IF NOT EXISTS "sequences"
+(
+ "key" VARCHAR(64) NOT NULL,
+ "type" VARCHAR(64) NOT NULL,
+ "seq" BIGINT NOT NULL,
+ "update_time" TIMESTAMP,
+ 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 '已使用到的序号';
+COMMENT ON COLUMN "sequences"."update_time" IS '最后使用时间';
+
+/*
+@触发器设置,功能:自动记录更新时间
+@触发器名为 SEQUENCES_UPDATE_TIME
+@触发器执行范围为每行生效
+*/
+CREATE OR REPLACE TRIGGER SEQUENCES_UPDATE_TIME BEFORE UPDATE ON "sequences" FOR EACH ROW
+BEGIN
+ NEW."update_time":=SYSDATE;
+END;
+
+/*启动触发器*/
+ALTER TRIGGER SEQUENCES_UPDATE_TIME ENABLE;
\ No newline at end of file
diff --git a/src/main/resources/dm/create_table_sequences_unlock.sql b/src/main/resources/dm/create_table_sequences_unlock.sql
new file mode 100644
index 0000000..c766f58
--- /dev/null
+++ b/src/main/resources/dm/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" BIGINT 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/dm/create_table_sequences_unused.sql b/src/main/resources/dm/create_table_sequences_unused.sql
new file mode 100644
index 0000000..a5ec720
--- /dev/null
+++ b/src/main/resources/dm/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" BIGINT 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/main/resources/mysql/create_table_sequences.sql b/src/main/resources/mysql/create_table_sequences.sql
index aa2b45d..ff8c9a4 100644
--- a/src/main/resources/mysql/create_table_sequences.sql
+++ b/src/main/resources/mysql/create_table_sequences.sql
@@ -3,5 +3,6 @@ CREATE TABLE IF NOT EXISTS `sequences`
`key` VARCHAR(64) NOT NULL COMMENT '序号英文名称',
`type` VARCHAR(64) NOT NULL COMMENT '序号类型',
`seq` BIGINT(20) NOT NULL COMMENT '已使用到的序号',
+ `update_time` DATETIME NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '最后使用时间',
PRIMARY KEY (`key`, `type`)
) 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
index b964399..ffc36ef 100644
--- a/src/main/resources/pgsql/create_table_sequences.sql
+++ b/src/main/resources/pgsql/create_table_sequences.sql
@@ -1,11 +1,32 @@
CREATE TABLE IF NOT EXISTS "sequences"
(
- "key" VARCHAR(64) NOT NULL,
- "type" VARCHAR(64) NOT NULL,
- "seq" INT8 NOT NULL,
+ "key" VARCHAR(64) NOT NULL,
+ "type" VARCHAR(64) NOT NULL,
+ "seq" INT8 NOT NULL,
+ "update_time" TIMESTAMP,
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
+COMMENT ON COLUMN "sequences"."seq" IS '已使用到的序号';
+COMMENT ON COLUMN "sequences"."update_time" IS '最后使用时间';
+
+
+/*
+触发器函数,用户更新update_time字段
+*/
+CREATE OR REPLACE FUNCTION SEQUENCES_UPDATE_TIME() RETURNS TRIGGER AS $$
+BEGIN
+ NEW."update_time" := current_timestamp;
+ RETURN NEW;
+END;
+$$ LANGUAGE plpgsql;
+
+/*
+@触发器设置,功能:自动记录更新时间
+@触发器名为 SEQUENCES_UPDATE_TIME
+@触发器执行范围为每行生效
+*/
+DROP TRIGGER IF EXISTS SEQUENCES_UPDATE_TIME ON "sequences" CASCADE;
+CREATE TRIGGER SEQUENCES_UPDATE_TIME BEFORE UPDATE ON "sequences" FOR EACH ROW EXECUTE FUNCTION SEQUENCES_UPDATE_TIME();
\ No newline at end of file
diff --git a/src/test/java/SeqTest.java b/src/test/java/SeqTest.java
index 94496a5..29b4d1b 100644
--- a/src/test/java/SeqTest.java
+++ b/src/test/java/SeqTest.java
@@ -24,7 +24,7 @@ public class SeqTest {
private static final Generator generator;
static {
- dataSource = pgsql();
+ dataSource = mysql();
GeneratorConfig generatorConfig = new GeneratorConfig(dataSource);
System.out.println("DbType: " + generatorConfig.getDbType());
@@ -124,4 +124,34 @@ public class SeqTest {
sequences.setType("MISSION");
System.out.println(sequences);
}
+
+ @Test
+ public void unusedTest() {
+ Sequences sequences = new Sequences();
+ sequences.setKey("0010001$distrainCode2024");
+ sequences.setType("MISSION");
+ sequences.setSeq(1L);
+ boolean result = generator.unused(sequences);
+ assert result;
+ }
+
+ @Test
+ public void lockTest() {
+ Sequences sequences = new Sequences();
+ sequences.setKey("0010001$distrainCode2024");
+ sequences.setType("MISSION");
+ sequences.setSeq(1L);
+ boolean result = generator.lock(sequences);
+ assert result;
+ }
+
+ @Test
+ public void lockedTest() {
+ Sequences sequences = new Sequences();
+ sequences.setKey("0010001$distrainCode2024");
+ sequences.setType("MISSION");
+ sequences.setSeq(1L);
+ boolean result = generator.locked(sequences);
+ System.out.println("locked: " + result);
+ }
}