public class DateSeqGenerator implements IdentifierGenerator,
Configurable {
// logger
private static final Log log = LogFactory.getLog(DateSeqGenerator.class);
// reference to the underlying generator to which we delegate the work
private String currentDate = "";
//上次生成标识的日期前缀
private long day;
//下一个Sequence值
private long next;
//末位序号的位数限制
private int length = 4;
//从数据库获取当前最大标识的Sql语句
private String sql;
//标识返回值的JAVA类别
private Class returnClass;
/**
* Construct a new DateSeqGenerator
*/
public DateSeqGenerator() {
super();
}
/* (non-Javadoc)
* @see org.hibernate.id.IdentifierGenerator#generate(org.hibernate.engine.SessionImplementor, java.lang.Object)
*/
public Serializable generate(SessionImplementor session, Object object)
throws SQLException, HibernateException
{
if (sql!=null) {
getNext( session );
}
long currentDay = getCurrentDay();
if(currentDay != day){
day = currentDay;
next = 1l;
}
return IdentifierGeneratorFactory.createNumber(day * Math.pow(10l,length) + (next++), returnClass);
}
/* (non-Javadoc)
* @see org.hibernate.id.Configurable#configure(org.hibernate.type.Type, java.util.Properties, org.hibernate.dialect.Dialect)
*/
public void configure(Type type, Properties params, Dialect dialect)
throws MappingException
{
String tableList = params.getProperty("tables");
if (tableList==null) tableList = params.getProperty(PersistentIdentifierGenerator.TABLES);
String[] tables = StringHelper.split(", ", tableList);
String column = params.getProperty("column");
if (column==null) column = params.getProperty(PersistentIdentifierGenerator.PK);
String numLength = params.getProperty("length");
if(numLength == null)
length = 4;
else
length = Integer.parseInt(numLength);
String schema = params.getProperty(PersistentIdentifierGenerator.SCHEMA);
String catalog = params.getProperty(PersistentIdentifierGenerator.CATALOG);
returnClass = type.getReturnedClass();
StringBuffer buf = new StringBuffer();
for ( int i=0; i<tables.length; i++ ) {
if (tables.length>1) {
buf.append("select ").append(column).append(" from ");
}
buf.append( Table.qualify(catalog, schema, tables[i], d.getSchemaSeparator() ) );
if ( i<tables.length-1) buf.append(" union ");
}
if (tables.length>1) {
buf.insert(0, "( ").append(" ) ids_");
column = "ids_." + column;
}
sql = "select max(" + column + ") from " + buf.toString();
}
/**
* 从数据库检索已有数据标识的最大值
* @param session
*
* @return
*/
//从数据库获取已有数据的最大ID标识,确定下一标识的值
private void getNext( SessionImplementor session ) {
Connection conn = session.connection();
log.debug("fetching initial value: " + sql);
try {
PersistentIdentifierGenerator.SQL.debug(sql);
PreparedStatement st = conn.prepareStatement(sql);
ResultSet rs = null;
try {
rs = st.executeQuery();
if ( rs.next() ) {
next = rs.getLong(1);
if ( rs.wasNull())
next = 1l;
else{
day = Long.parseLong(next.substring(0,8)) + 1; }
next = Long.parseLong((next + "").substring(8));
}
else {
next = 1l;
}
sql=null;
log.debug("first free id: " + next);
}
finally {
if (rs!=null) rs.close();
st.close();
}
}
catch (SQLException sqle) {
throw JDBCExceptionHelper.convert(
session.getFactory().getSQLExceptionConverter(),
sqle,
"could not fetch initial value",
sql
);
}
}
/**
* 从数据库服务器获取当前日期
*
* @return long 数据库当前日期,日期格式为'yyyymmdd'
*/
private long getCurrentDay(){
String cDate = null;
/**此部分代码省略**/
/** 从数据库获取当前日期,返回格式为'yyyymmdd',“20060316”**/
return cDate;
}
}
分享到:
相关推荐
例如,一个简单的流水号可能是按时间顺序生成的日期和时间戳,如"20230408153012",代表2023年4月8日15点30分12秒生成。更复杂的流水号可能包括业务系统的标识符、随机数或者自增序列。 流水号生成软件的设计通常...
这个表将使用函数f_NewBH()来生成流水号,并将其作为主键。 插入数据 现在,我们可以插入数据到表中。我们可以使用以下SQL语句来插入数据: ```sql INSERT table_BH (Pname) VALUES ('张三') INSERT table_BH ...
4. **物理表作为流水号生成器**: 另一种方法是创建一个只包含流水号的表,每次插入新行时更新这个表。这种方法在多用户环境下可能会有并发问题,需要额外的锁机制来保证线程安全。 5. **系统函数NEXT VALUE FOR ...
在IT开发领域,生成不重复的编号或标识符是一个常见的需求,特别是在数据库记录、订单号、唯一用户ID等场景。为了满足这一需求,开发者经常利用系统时间作为基础,结合其他算法来生成这样的唯一序列。标题提到的...
最后,收入支出平衡表`tbl_srzchb`用于记录收支的平衡情况,包含收支流水号、用户编号、收入和支出金额、余额及备注,同样设定了流水号为主键。 在Oracle中,索引可以提高查询效率,约束则保证数据的完整性和一致性...
1. **主键设计**:题目要求主键使用无意义的流水号,这通常意味着需要使用自增序列或者UUID生成器来创建唯一的标识符。在Java中,可以使用JPA的@Id注解配合@GeneratedValue来实现。 2. **数据类型选择**:所有字段...
在实际开发中,`django_autosequence`可以大大简化那些依赖于顺序ID的业务逻辑,比如订单系统、流水号生成等。通过使用这个库,开发者可以专注于应用的业务逻辑,而不必担心序列冲突带来的问题。 总的来说,`django...
业务主键具有实际含义,而逻辑主键通常是无意义的,如自增的流水号。推荐使用逻辑主键,因为它更便于管理和维护。在数据库设计中,表名和列名应遵循一定的命名规范,如前缀`T_`、`tb_`或`tbl_`,列名首字母大写等。 ...
- **性质资产流水号**:该性质下最大流水号,初始化为0。 **3.1.5 输出项** - 无直接输出项,但会更新数据库中的相关信息。 **3.1.6 设计方法(算法)** - **新增/修改**:在提交前验证编号和名称的唯一性。 - *...
在Oracle数据库中,Sequence是一种非常方便的工具,用于生成唯一的序列号,常用于主键或者流水号等场景。然而,MySQL数据库本身并不直接支持类似Oracle的Sequence功能。当从Oracle迁移到MySQL时,我们需要寻找替代的...