前几天做的一个需求,要求表中的主键按照yyyymmddhhmmss+3位从0开始当日递增。
接到这个需求的第一反应就是肯定要先获取当前时间,然后获取表中的最后一个ID。再截取今天的日期和表中最后一个ID的日期比较是否相等。如果相等,则获取最后三位并进行递增。反之,则从001开始。
具体代码如下:
import cn.hutool.core.date.DateUtil; // 导入日期工具类
import cn.hutool.core.util.RandomUtil; // 导入随机数工具类
import org.springframework.jdbc.core.JdbcTemplate; // 导入Spring JDBC模板类
import org.springframework.jdbc.datasource.DriverManagerDataSource; // 导入Spring JDBC驱动管理数据源类
import javax.annotation.Resource; // 导入javax标准注解,用于注入资源
import javax.sql.DataSource; // 导入数据源接口
import java.util.Date; // 导入日期类
import java.util.List; // 导入列表类
/**
* NumUtil类用于生成唯一的ID编号。
*/
public class NumUtil {
@Resource
private JdbcTemplate jdbcTemplate; // Spring JDBC模板类
private static final String DATE_FORMAT = "yyyyMMddHHmmss"; // 日期格式字符串:年月日时分秒
/**
* 创建并配置数据源对象
* @return 数据源对象
*/
private DataSource createDataSource() {
DataSource dataSource = new DriverManagerDataSource(); // 创建Spring JDBC驱动管理数据源对象
((DriverManagerDataSource) dataSource).setDriverClassName("com.mysql.cj.jdbc.Driver"); // 设置数据库驱动类名
((DriverManagerDataSource) dataSource).setUrl(""); // 设置数据库连接URL
((DriverManagerDataSource) dataSource).setUsername(""); // 设置数据库用户名
((DriverManagerDataSource) dataSource).setPassword(""); // 设置数据库密码
return dataSource;
}
/**
* NumUtil类的构造方法,用于初始化JdbcTemplate对象
*/
public NumUtil() {
DataSource dataSource = createDataSource(); // 创建数据源对象
jdbcTemplate = new JdbcTemplate(dataSource); // 初始化JdbcTemplate对象
System.out.println("jdbcTemplate initialized."); // 打印初始化完成的信息
}
/**
* 根据表名和列名生成一个新的ID编号
* @param tableName 表名
* @param columnName 列名
* @return 生成的ID编号
*/
public String createId(String tableName, String columnName) {
String currentTime = getCurrentTime(); // 获取当前时间的字符串表示
String lastId = getLastId(tableName, columnName); // 获取指定表中最后一个ID编号
String increment = getIncrement(lastId, currentTime); // 获取自增的三位数字
return currentTime + increment; // 返回生成的ID编号
}
/**
* 获取当前时间的字符串表示,格式为"yyyyMMddHHmmss"
* @return 当前时间的字符串表示
*/
private String getCurrentTime() {
return DateUtil.format(new Date(), DATE_FORMAT); // 使用日期工具类将当前时间格式化为指定的字符串格式
}
/**
* 获取指定表中最后一个ID编号
* @param tableName 表名
* @param columnName 列名
* @return 最后一个ID编号
*/
private String getLastId(String tableName, String columnName) {
// 确保在使用jdbcTemplate之前,它已经被正确初始化。
if (jdbcTemplate == null) {
throw new RuntimeException("JdbcTemplate has not been initialized."); // 如果jdbcTemplate为null,则抛出运行时异常
}
String sql = "SELECT " + columnName + " FROM " + tableName + " ORDER BY " + columnName + " DESC LIMIT 1"; // 构造查询最后一个ID编号的SQL语句
List<String> result = jdbcTemplate.query(sql, (rs, rowNum) -> rs.getString(columnName)); // 使用jdbcTemplate查询数据库并返回结果列表
if (result.isEmpty()) {
return null; // 如果结果列表为空,则返回null
}
return result.get(0); // 否则返回结果列表中的第一个元素
}
/**
* 获取自增的三位数字
* @param lastId 最后一个ID编号
* @param currentTime 当前时间的字符串表示
* @return 自增的三位数字
*/
private String getIncrement(String lastId, String currentTime) {
if (lastId != null) {
String lastDate = lastId.substring(0, 8); // 从最后一个ID编号中截取日期部分
String currentDate = currentTime.substring(0, 8); // 从当前时间的字符串表示中截取日期部分
if (lastDate.equals(currentDate)) {
String increment = lastId.substring(14, 17); // 截取最后三位数字
int incrementNumber = Integer.parseInt(increment); // 将截取到的字符串转换为整数
incrementNumber++; // 自增1
String newIncrement = String.format("%03d", incrementNumber); // 将新的数字转换为三位数的字符串形式,不足三位的数字前面补0.
return newIncrement; // 返回自增的三位数字
}
}
return "001"; // 如果当日不存在已有的ID编号,则从001开始自增。
}
}
PS:上面代码中的注释都是用GPT生成的,目前GPT3.5真的很好用。我已经自用半年多了,正考虑自己做一个平台出来,进行商业化。