zhongxuchen 发表于 2013-1-30 01:40:19

数据库表SEQUENCE产生

sagacity(睿智)架构
第三讲:数据库sequence产生
先抛一个问题:
      大家在做系统时对一些表要产生主键(一般以流水或日期加流水方式产生),大家一般怎么做呢?
      是不是:
      select max(id) from table 或则通过hibernate自带的uuid等方式产生呢?
      这种做法非常痛苦,要想sequence有点意义(如日期+流水)就比较麻烦,效率也低,每次都去对应的表里面做全量查询!
      sagacity中怎么做呢?
      我们通过一个TABLE_SEQUENCE表存放各个表的当前sequence,表结构如下:
     create table SYS_TABLE_SEQUENCE
     (
       SEQUENCE_NAME        varchar(200) not null,
       CURRENT_KEY_VALUE    numeric(20,0) not null,
       DATE_VALUE           numeric(8,0),
       primary key (SEQUENCE_NAME)
    );
    alter table SYS_TABLE_SEQUENCE comment '系统流水表';

    同时通过hibernate建立一个对象,SysTableSequence.java放在sagacity核心库中
    项目中的用法:
    在applicationContext.xml中配置sessionFactory时添加
    <property name="mappingResources">
   <list>
    <value>
     org/sagacity/framework/dao/model/SysTableSequence.hbm.xml
    </value>
    
     在DAO中我们如此调用
     1.单个流水:
     BigDecimal seq=this.getBigDecimalSequence(PmPurchaseOrderList.class);
     2. 批量流水,取得的流水为第一个,其它的流水通过seq+1
     BigDecimal seq=this.getBigDecimalSequence(PmPurchaseOrderList.class,size);
     3.日期+几位流水
     BigDecimal getDateSequence(Class entityClass, Date nowDate,String dateStyle, int length);
     4.批量取日期+几位流水
     BigDecimal getDateSequence(Class entityClass, Date nowDate,String dateStyle, int length, int size);
 
    代码片段如下:
     /**
  * 根据对象类获取序号
  *
  * @param entityClass
  * @return
  * @throws CreateSequenceException
  */
 protected BigDecimal getBigDecimalSequence(Class entityClass)
   throws CreateSequenceException {
  return getBigDecimalSequence(entityClass, 1);
 }
 
 /**
  * @todo example 获取以日期开头的序列号:seqName:orgData size:10 now seqence:10000
  *       return: 10001 now seqence:10010
  * @param seqName
  * @param size
  * @return
  * @throws CreateSequenceException
  */
 protected BigDecimal getBigDecimalSequence(Class entityClass, int size)
   throws CreateSequenceException {
  if (entityClass == null || size < 1)
   throw new CreateSequenceException("Input Parameters has Null!");
  else
   return getSequence(entityClass.getName(), null, null, null, size,
     false);
 }
 
 /**
  * 根据日期获取SEQNO
  * @param entityClass
  * @param nowDate
  * @param dateStyle
  * @param length
  * @return
  * @throws CreateSequenceException
  */
 protected BigDecimal getDateSequence(Class entityClass, Date nowDate,
   String dateStyle, int length) throws CreateSequenceException {
  return getDateSequence(entityClass, nowDate, dateStyle, length, 1);
 }
 
 /**
  * @todo 获取以日期开头的序列号example:nowSeq=20051118001 ,
  *       condition:dateValue=20051118;length=3,size=4 update seq:20051118005
  *       return:20051118002
  * @param entityClass
  * @param nowDate
  * @param dateStyle
  * @param length
  * @param size
  * @return
  * @throws CreateSequenceException
  */
 protected BigDecimal getDateSequence(Class entityClass, Date nowDate,
   String dateStyle, int length, int size)
   throws CreateSequenceException {
  if (entityClass == null || length < 1 || size < 1)
   throw new CreateSequenceException("Input Parameters has Null!");
  else
   return getSequence(entityClass.getName(), nowDate, dateStyle,
     new Integer(length), size, true);
 }
 
/**
  * @todo 获取以日期开头的序列号:example:nowSeq=20051118001 ,
  *       condition:dateValue=20051118;length=3,size=4 update seq:20051118005
  *       return:20051118002
  * @param seqName
  * @param nowDate
  * @param dateStyle
  * @param length
  * @param size
  * @param hasDate
  * @return
  * @throws CreateSequenceException
  */
 private BigDecimal getSequence(String seqName, Date nowDate,
   String dateStyle, Integer length, int size, boolean hasDate)
   throws CreateSequenceException {
  if (seqName == null || size < 1)
   throw new CreateSequenceException("Input Parameters has Null!");
  logger.debug("获取" + seqName + "的连续" + size + "个SEQUENCE!");
  try {
   synchronized (seqName) {
    TableSequence tableSeq = null;
    Object obj = this.getHibernateTemplate().get(
      TableSequence.class, seqName);
    Long seqValue = new Long(0);
    // 非第一次创建表序号,取出当前的SEQNO
    if (obj != null) {
     tableSeq = (TableSequence) obj;
     seqValue = tableSeq.getCurrentKeyValue();
    } else {
     // 第一次SEQNO=0
     tableSeq = new TableSequence();
     tableSeq.setSequenceName(seqName);
    }
    Long dateValue = null;
    // 有日期
    if (hasDate) {
     // 如果日期值为空,则取系统当前日期
     Date seqDate = (nowDate == null) ? DateUtil.getNowTime()
       : nowDate;
     dateValue = Long.valueOf(DateUtil.formatDate(seqDate,
       dateStyle));
     // 当前日期大于现有表里的日期,用当前日期替换seq 日期,seqNo从零开始
     if (tableSeq.getDateValue() == null
       || dateValue.longValue() > tableSeq.getDateValue()
         .longValue()) {
      tableSeq.setDateValue(dateValue);
      seqValue = new Long(0);
     }
    }
    // SEQNO 设置为当前SEQNO+增加量
    tableSeq.setCurrentKeyValue(new Long(seqValue.longValue()
      + size));
    if (obj != null)
     this.getHibernateTemplate().update(tableSeq);
    else
     this.getHibernateTemplate().save(tableSeq);
    // 返回起始seqNO
    BigDecimal startSeqNo = new BigDecimal(seqValue.longValue() + 1);
    // 日期
    if (hasDate)
     return new BigDecimal(dateValue
       + StringUtil.addLeftZero2Len(startSeqNo.toString(),
         length));
    else
     return startSeqNo;
   }
  } catch (Exception e) {
   e.printStackTrace();
   throw new CreateSequenceException("创建表:" + seqName
     + "的Sequence未成功!", e);
  }
 }
 
  请期待我的第四讲,excel导入工具!
页: [1]
查看完整版本: 数据库表SEQUENCE产生