一般采用: 时间+序列号
20111001+000001 = 20111001000001
规则 : 前面以年月日前缀+序列号每天从1天始 第二天又是从1开始
代码:
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.sql.DataSource;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.springframework.batch.item.database.support.DefaultDataFieldMaxValueIncrementerFactory;
import org.springframework.batch.support.DatabaseType;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.jdbc.support.JdbcUtils;
import org.springframework.jdbc.support.incrementer.DataFieldMaxValueIncrementer;
public class DailyRollingIncrementer implements InitializingBean {
/**
* define bean as :
* <bean id="dailyRollingIncrementer" class="com.book511.incrementer.DailyRollingIncrementer">
* <property name="dataSource" ref="dataSource"/>
* <property name="incrementerName" value="TEST_SEQ"/>
* </bean>
*
* and run sql in MySQL as :
* CREATE TABLE TEST_SEQ (ID BIGINT NOT NULL) ENGINE=MYISAM;
* INSERT INTO TEST_SEQ(id) select 0 from DUAL where not exists (select id from TEST_SEQ);
* CREATE TABLE TEST_SEQ_ROLLING (`YMD` CHAR(8) NOT NULL , `SEQ_NUMBER` BIGINT NULL , PRIMARY KEY (`YMD`) ) ENGINE = MyISAM;
*
*/
private String incrementerName;
private DataSource dataSource;
private DefaultDataFieldMaxValueIncrementerFactory maxValueIncrementerFactory;
private DataFieldMaxValueIncrementer maxValueIncrementer;
private String rollingTable;
private String selectSql;
private String insertSql;
private String currentYmd = null;
private Long currentSeq = null;
private DateTimeFormatter formatter = DateTimeFormat.forPattern("YYYYMMdd");
/**
* Caution !!!
* you should check if return value is not 0
* @return
*/
public long nextLongValue() {
DateTime dt = new DateTime();
String ymd = formatter.print(dt);
return nextLongValue(ymd);
}
public synchronized long nextLongValue(String ymd) {
Long nextSeq = 0L;
try {
nextSeq = maxValueIncrementer.nextLongValue();
System.out.println("nextSeq is : " + nextSeq);
} catch (Exception e) {
return 0L;
}
long number = seqNumber(ymd);
if (number == 0) {
number = nextSeq;
insertSeqNumber(ymd, number);
/*try {
Thread.sleep(10000);
} catch (InterruptedException e) {
}*/
}
return nextSeq - number + 1;
}
private synchronized long seqNumber(String ymd) {
if (ymd != null) {
if (ymd.equals(currentYmd))
return currentSeq;
}
Connection con = null;
PreparedStatement selectPreparedStatement = null;
try {
con = DataSourceUtils.getConnection(getDataSource());
selectPreparedStatement = con.prepareStatement(selectSql);
DataSourceUtils.applyTransactionTimeout(selectPreparedStatement,
getDataSource());
selectPreparedStatement.setString(1, ymd);
ResultSet rs = selectPreparedStatement.executeQuery();
if (rs.next()) {
long seq = (long) rs.getLong(1);
currentYmd = ymd;
currentSeq = seq;
return seq;
}
} catch (Exception ex) {
// throw new DataAccessResourceFailureException(
// "Error ...", ex);
} finally {
JdbcUtils.closeStatement(selectPreparedStatement);
DataSourceUtils.releaseConnection(con, getDataSource());
}
return 0;
}
private synchronized boolean insertSeqNumber(String ymd, long seqNumber) {
Connection con = null;
PreparedStatement selectPreparedStatement = null;
try {
con = DataSourceUtils.getConnection(getDataSource());
PreparedStatement insertPreparedStatement = con
.prepareStatement(insertSql);
insertPreparedStatement.setString(1, ymd);
insertPreparedStatement.setLong(2, seqNumber);
int count = insertPreparedStatement.executeUpdate();
System.out.println("count is : " + count);
return count > 0;
} catch (Exception ex) {
System.out.println("seqNumber = " + seqNumber);
ex.printStackTrace();
} finally {
JdbcUtils.closeStatement(selectPreparedStatement);
DataSourceUtils.releaseConnection(con, getDataSource());
}
return false;
}
public String genSn(int bit){
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
Date dNow = new Date();
String dateStr = sdf.format(dNow).toString();
long v = nextLongValue(dateStr);
String v_s = String.valueOf(v);
int num = getNumBit(v_s);
if(num<bit){
int zeroNum = bit - num;
String zeroStr = "";
for(int i=0;i<zeroNum;i++){
zeroStr += "0";
}
System.out.println("result is : " + zeroStr);
v_s = zeroStr + v_s;
}
if(v_s.length()!=bit){
System.out.println("error");
}
return v_s;
}
public int getNumBit(String str){
if(str!=null){
str = str.trim();
}
int numlen=0;
for (int i=0;i<str.length();i++){
System.out.print(str.substring(i, i+1)+",");//substring把STR的每一个字符取出
numlen++;//计数
}
return numlen;
}
@Override
public void afterPropertiesSet() throws Exception {
DatabaseType incrementerType = DatabaseType.fromMetaData(dataSource);
maxValueIncrementerFactory = new DefaultDataFieldMaxValueIncrementerFactory(
dataSource);
maxValueIncrementer = maxValueIncrementerFactory.getIncrementer(
incrementerType.getProductName(), incrementerName);
rollingTable = incrementerName + "_ROLLING";
selectSql = "select SEQ_NUMBER from " + rollingTable + " where YMD = ?";
insertSql = "insert into " + rollingTable + "(YMD,SEQ_NUMBER) values(?,?)";
}
public String getIncrementerName() {
return incrementerName;
}
public void setIncrementerName(String incrementerName) {
this.incrementerName = incrementerName;
}
public DataSource getDataSource() {
return dataSource;
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
}
20111001+000001 = 20111001000001
规则 : 前面以年月日前缀+序列号每天从1天始 第二天又是从1开始
代码:
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.sql.DataSource;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.springframework.batch.item.database.support.DefaultDataFieldMaxValueIncrementerFactory;
import org.springframework.batch.support.DatabaseType;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.jdbc.support.JdbcUtils;
import org.springframework.jdbc.support.incrementer.DataFieldMaxValueIncrementer;
public class DailyRollingIncrementer implements InitializingBean {
/**
* define bean as :
* <bean id="dailyRollingIncrementer" class="com.book511.incrementer.DailyRollingIncrementer">
* <property name="dataSource" ref="dataSource"/>
* <property name="incrementerName" value="TEST_SEQ"/>
* </bean>
*
* and run sql in MySQL as :
* CREATE TABLE TEST_SEQ (ID BIGINT NOT NULL) ENGINE=MYISAM;
* INSERT INTO TEST_SEQ(id) select 0 from DUAL where not exists (select id from TEST_SEQ);
* CREATE TABLE TEST_SEQ_ROLLING (`YMD` CHAR(8) NOT NULL , `SEQ_NUMBER` BIGINT NULL , PRIMARY KEY (`YMD`) ) ENGINE = MyISAM;
*
*/
private String incrementerName;
private DataSource dataSource;
private DefaultDataFieldMaxValueIncrementerFactory maxValueIncrementerFactory;
private DataFieldMaxValueIncrementer maxValueIncrementer;
private String rollingTable;
private String selectSql;
private String insertSql;
private String currentYmd = null;
private Long currentSeq = null;
private DateTimeFormatter formatter = DateTimeFormat.forPattern("YYYYMMdd");
/**
* Caution !!!
* you should check if return value is not 0
* @return
*/
public long nextLongValue() {
DateTime dt = new DateTime();
String ymd = formatter.print(dt);
return nextLongValue(ymd);
}
public synchronized long nextLongValue(String ymd) {
Long nextSeq = 0L;
try {
nextSeq = maxValueIncrementer.nextLongValue();
System.out.println("nextSeq is : " + nextSeq);
} catch (Exception e) {
return 0L;
}
long number = seqNumber(ymd);
if (number == 0) {
number = nextSeq;
insertSeqNumber(ymd, number);
/*try {
Thread.sleep(10000);
} catch (InterruptedException e) {
}*/
}
return nextSeq - number + 1;
}
private synchronized long seqNumber(String ymd) {
if (ymd != null) {
if (ymd.equals(currentYmd))
return currentSeq;
}
Connection con = null;
PreparedStatement selectPreparedStatement = null;
try {
con = DataSourceUtils.getConnection(getDataSource());
selectPreparedStatement = con.prepareStatement(selectSql);
DataSourceUtils.applyTransactionTimeout(selectPreparedStatement,
getDataSource());
selectPreparedStatement.setString(1, ymd);
ResultSet rs = selectPreparedStatement.executeQuery();
if (rs.next()) {
long seq = (long) rs.getLong(1);
currentYmd = ymd;
currentSeq = seq;
return seq;
}
} catch (Exception ex) {
// throw new DataAccessResourceFailureException(
// "Error ...", ex);
} finally {
JdbcUtils.closeStatement(selectPreparedStatement);
DataSourceUtils.releaseConnection(con, getDataSource());
}
return 0;
}
private synchronized boolean insertSeqNumber(String ymd, long seqNumber) {
Connection con = null;
PreparedStatement selectPreparedStatement = null;
try {
con = DataSourceUtils.getConnection(getDataSource());
PreparedStatement insertPreparedStatement = con
.prepareStatement(insertSql);
insertPreparedStatement.setString(1, ymd);
insertPreparedStatement.setLong(2, seqNumber);
int count = insertPreparedStatement.executeUpdate();
System.out.println("count is : " + count);
return count > 0;
} catch (Exception ex) {
System.out.println("seqNumber = " + seqNumber);
ex.printStackTrace();
} finally {
JdbcUtils.closeStatement(selectPreparedStatement);
DataSourceUtils.releaseConnection(con, getDataSource());
}
return false;
}
public String genSn(int bit){
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
Date dNow = new Date();
String dateStr = sdf.format(dNow).toString();
long v = nextLongValue(dateStr);
String v_s = String.valueOf(v);
int num = getNumBit(v_s);
if(num<bit){
int zeroNum = bit - num;
String zeroStr = "";
for(int i=0;i<zeroNum;i++){
zeroStr += "0";
}
System.out.println("result is : " + zeroStr);
v_s = zeroStr + v_s;
}
if(v_s.length()!=bit){
System.out.println("error");
}
return v_s;
}
public int getNumBit(String str){
if(str!=null){
str = str.trim();
}
int numlen=0;
for (int i=0;i<str.length();i++){
System.out.print(str.substring(i, i+1)+",");//substring把STR的每一个字符取出
numlen++;//计数
}
return numlen;
}
@Override
public void afterPropertiesSet() throws Exception {
DatabaseType incrementerType = DatabaseType.fromMetaData(dataSource);
maxValueIncrementerFactory = new DefaultDataFieldMaxValueIncrementerFactory(
dataSource);
maxValueIncrementer = maxValueIncrementerFactory.getIncrementer(
incrementerType.getProductName(), incrementerName);
rollingTable = incrementerName + "_ROLLING";
selectSql = "select SEQ_NUMBER from " + rollingTable + " where YMD = ?";
insertSql = "insert into " + rollingTable + "(YMD,SEQ_NUMBER) values(?,?)";
}
public String getIncrementerName() {
return incrementerName;
}
public void setIncrementerName(String incrementerName) {
this.incrementerName = incrementerName;
}
public DataSource getDataSource() {
return dataSource;
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
}