一般采用: 时间+序列号
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; } } |
|