`

日期流水号主键生成器

 
阅读更多
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秒生成。更复杂的流水号可能包括业务系统的标识符、随机数或者自增序列。 流水号生成软件的设计通常...

    14位编号=8位日期(+6位流水号)

    这个表将使用函数f_NewBH()来生成流水号,并将其作为主键。 插入数据 现在,我们可以插入数据到表中。我们可以使用以下SQL语句来插入数据: ```sql INSERT table_BH (Pname) VALUES ('张三') INSERT table_BH ...

    数据库sqlservser的流水号.rar

    4. **物理表作为流水号生成器**: 另一种方法是创建一个只包含流水号的表,每次插入新行时更新这个表。这种方法在多用户环境下可能会有并发问题,需要额外的锁机制来保证线程安全。 5. **系统函数NEXT VALUE FOR ...

    利用时间生成8位不重复数

    在IT开发领域,生成不重复的编号或标识符是一个常见的需求,特别是在数据库记录、订单号、唯一用户ID等场景。为了满足这一需求,开发者经常利用系统时间作为基础,结合其他算法来生成这样的唯一序列。标题提到的...

    oracle部分课件

    最后,收入支出平衡表`tbl_srzchb`用于记录收支的平衡情况,包含收支流水号、用户编号、收入和支出金额、余额及备注,同样设定了流水号为主键。 在Oracle中,索引可以提高查询效率,约束则保证数据的完整性和一致性...

    关于JAVA企业面试题

    1. **主键设计**:题目要求主键使用无意义的流水号,这通常意味着需要使用自增序列或者UUID生成器来创建唯一的标识符。在Java中,可以使用JPA的@Id注解配合@GeneratedValue来实现。 2. **数据类型选择**:所有字段...

    Python库 | django_autosequence-0.6.0-py3-none-any.whl

    在实际开发中,`django_autosequence`可以大大简化那些依赖于顺序ID的业务逻辑,比如订单系统、流水号生成等。通过使用这个库,开发者可以专注于应用的业务逻辑,而不必担心序列冲突带来的问题。 总的来说,`django...

    WPF数据绑定

    业务主键具有实际含义,而逻辑主键通常是无意义的,如自增的流水号。推荐使用逻辑主键,因为它更便于管理和维护。在数据库设计中,表名和列名应遵循一定的命名规范,如前缀`T_`、`tb_`或`tbl_`,列名首字母大写等。 ...

    资产管理系统-详细设计说明书正式版.pdf

    - **性质资产流水号**:该性质下最大流水号,初始化为0。 **3.1.5 输出项** - 无直接输出项,但会更新数据库中的相关信息。 **3.1.6 设计方法(算法)** - **新增/修改**:在提交前验证编号和名称的唯一性。 - *...

    基于Mysql的Sequence实现方法

    在Oracle数据库中,Sequence是一种非常方便的工具,用于生成唯一的序列号,常用于主键或者流水号等场景。然而,MySQL数据库本身并不直接支持类似Oracle的Sequence功能。当从Oracle迁移到MySQL时,我们需要寻找替代的...

Global site tag (gtag.js) - Google Analytics