数据库表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]