`

易学设计模式十 单例序列键生成器

阅读更多
数据库有很多种,例如Oracle,DB2,Sybase,MySql,SQL Server等等,他们有的提供主键生成,有的不提供,提供的方式也不一样,如果有的系统需要同时支持多种数据库,就要求主键生成更有通用性,下面就给出解决方案。

使用表存储,表有两个列,一个存放键名,一个存放键值
取值时先更新数据库键值+20;然后查询出增加后的值,例如我们更新后的值是1000,每次增加20,现在可用的key = 1000 -20 +1 = 981;这样做的好处就是缓存主键,不用增加一个就修改,查询一次数据库,我们增加20次才查询一次数据库。



public class KeyGenerator {
	
	private static Map keygens = new HashMap(10);
	private static final int POOL_SIZE = 20;
	private KeyInfo keyinfo;
	
	private KeyGenerator(){}
	
	private KeyGenerator(String keyName) {
		keyinfo = new KeyInfo(POOL_SIZE, keyName);
	}
	
	public static synchronized KeyGenerator getInstance(String keyName) {
		KeyGenerator keygen;
		if(keygens.containsKey(keyName)) {
			keygen = (KeyGenerator)keygens.get(keyName);
		} else {
			keygen = new KeyGenerator(keyName);
			keygens.put(keyName, keygen);
		}
		return keygen;
	}
	
	public synchronized int getNextKey() {
		return keyinfo.getnextKey();
	}

}


public class KeyInfo {
	
	private int keyMax;
	private int keyMin;
	private int nextKey;
	private int poolSize;
	private String keyName;
	
	public KeyInfo(int poolSize, String keyName) {
		this.poolSize = poolSize;
		this.keyName = keyName;
		retrieveFromDB();
	}
	
	public int getKeyMax() {
		return keyMax;
	}
	
	public int getKeyMin() {
		return keyMin;
	}
	
	public int getnextKey() {
		if(nextKey > keyMax) {
			retrieveFromDB();
		}
		return nextKey++;
	}
	
	private void retrieveFromDB() {
		String updateSql = "UPDATE KEYTABLE SET KEYVALUE = KEYVALUE + "
			+ poolSize + "where keyname = '" + keyName +"'";
		String selectSql = "select keyvalue from keytable where keyname = '"
			+ keyName +"'";
		//execute the above queries in a transaction and commit it
		//assume the value returned is 1000
		int keyFromDB = 1000;
		keyMax = keyFromDB;
		keyMin = keyFromDB - poolSize + 1;
		nextKey = keyMin;
	}
	

}


public class Client {

	public static void main(String[] args) {
		
		KeyGenerator keygen = KeyGenerator.getInstance("PO_NUMBER");
		for(int i=0; i < 20; i++) {
			System.out.println("key(" + (i+1)+")=" +keygen.getNextKey());
		}
	}
}


输出结果:

key(1)=981
key(2)=982
key(3)=983
key(4)=984
key(5)=985
key(6)=986
key(7)=987
key(8)=988
key(9)=989
key(10)=990
key(11)=991
key(12)=992
key(13)=993
key(14)=994
key(15)=995
key(16)=996
key(17)=997
key(18)=998
key(19)=999
key(20)=1000
  • 大小: 23.7 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics