主键生存方式

package com.bj58.opt.cpt.dbo.mdt;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;


public class MDTIDHelper {
	
	private static int upper = 9;
	private static int lower = 5;
	private static int count = (int) (Math.random()*(upper-lower+1)+lower); // 下限
	private static final long idFlag = 1397059200000L; // DateHelper.strToDate("2014-04-10").getTime()
	private static long oldID = 9999999999999999l;
	private static long oldID_1 = 54500000000000000L;
	private static long lastTimestamp = -1L;
	private static long sequence = 0L;
	
	public static void main(String[] args) throws Exception {	
		long gbid = getMDTUniqueID();
		System.out.println(gbid);
		System.out.println(getMDTUniqueID(gbid));
		System.out.println(getMDTUniqueID(gbid));
		
		gbid = System.currentTimeMillis();
		System.out.println(gbid);
		gbid = gbid - MDTConstantHelper.ID_FLAG;
		System.out.println(gbid);
		
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		Calendar c = Calendar.getInstance();
		c.setTime(df.parse("2014-04-10"));
		System.out.println(c.getTimeInMillis());
		
		gbid = (gbid<<1)|1;
		System.out.println(gbid);
		gbid = 1 ;
		gbid = (gbid<<5);
		System.out.println(gbid);
		System.out.println(getShortUniqueID());
		System.out.println(getShortUniqueID(99));
		
	}
	
	/**
	 * 返回0-999自增数
	 * @return
	 * @throws InterruptedException
	 */
	private static int getRandom() throws InterruptedException{
//		return new Random().nextInt(999);
//		return (int) (Math.round(Math.random() * 1000) );
		if(count==upper)// 上限
			count = lower - 1;// 下限
		return ++count;
	}
	
	private static long getMDTBaseID()  throws Exception {
		if(MDTConstantHelper.SERVER_ID <= 0) {
			throw new Exception("server id is error,please check config file!");
		}
		
		long destID = System.currentTimeMillis() - MDTConstantHelper.ID_FLAG;
//		long destID = DateHelper.strToDate("2581-08-16").getTime() - MDTConstantHelper.ID_FLAG;
		destID = (destID<<9) | MDTConstantHelper.SERVER_ID;
		Thread.sleep(1);
		return destID;
	}
	
	/**
	 * 垂直分表源id生成
	 * 最大支持到2581-08-16
	 * @return
	 * @throws Exception
	 */
	public static synchronized long getMDTUniqueID() throws Exception {
		return getMDTBaseID()*1000+getRandom();
	}
	
	
	/**
	 * 垂直分表目标id生成
	 * 最大支持到2581-08-16
	 * @param sourceId
	 * @return
	 * @throws Exception
	 */
	public static synchronized long getMDTUniqueID(long sourceId) throws Exception {
		return getMDTBaseID()*1000+sourceId%1000;
	}
	
	/**
	 * 获取主键ID
	 * @return
	 * @throws Exception
	 */
	public static synchronized long getShortUniqueID() throws Exception {
		if(MDTConstantHelper.SERVER_ID <= 0) {
			throw new Exception("server id is error,please check config file!");
		}
		long timestamp = timeGen();
		if (timestamp < lastTimestamp) {
			try {
				throw new Exception("Clock moved backwards.  Refusing to generate id for "+ (lastTimestamp - timestamp) + " milliseconds");
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		if (lastTimestamp == timestamp) {
			// 当前毫秒内,则+1
			sequence = (sequence + 1) & 7;//0111
			if (sequence == 0) {
				// 当前毫秒内计数满了,则等待下一秒
				timestamp = tilNextMillis(lastTimestamp);
			}
		} else {
			sequence = 0;
		}
		lastTimestamp = timestamp;
		
		long destID = timestamp - MDTConstantHelper.ID_FLAG;
		destID = (destID<<10) | (MDTConstantHelper.SERVER_ID<<3)|sequence;
		return destID;
	}
	
	/**
	 * 获取主键ID
	 * @return
	 * @throws Exception
	 */
	public static synchronized long getShortUniqueID(long sourceID) throws Exception {
		if(MDTConstantHelper.SERVER_ID <= 0) {
			throw new Exception("server id is error,please check config file!");
		}
		
		sourceID = getShortDBIndex(sourceID);
		long destID = System.currentTimeMillis() - MDTConstantHelper.ID_FLAG;
		destID = (destID << 10) | sourceID;
		destID = (destID<<7) | MDTConstantHelper.SERVER_ID;
		Thread.sleep(1);
		return destID;
	}
	
	/**
	 * 不分库,不分表
	 * 获取主键ID
	 * @return
	 * @throws Exception
	 */
	public static synchronized long getUniqueID() throws Exception {
		long sourceID = 0;
		return getUniqueID(sourceID);
	}
	
	/**
	 * 不分库,分表
	 * @param tableID
	 * @return
	 * @throws Exception
	 */
	public static synchronized long getUniqueID(int tableID) throws Exception {
		int sourceID = 0;
		return getUniqueID(sourceID, tableID);
	}
	/**
	 * 分库,不分表
	 * 生成唯一ID,该ID的dbIndex与sourceID一至
	 * 注:最大支持库      :1024个
	 *     最大支持时间:4240-01-01
	 * @param sourceID
	 * @return
	 * @throws Exception
	 */
	public static synchronized long getUniqueID(long sourceID) throws Exception {
		int tableID = 0;
		return getUniqueID(sourceID, tableID);
	}
	
	/**
	 * 分库,分表
	 * 生成唯一ID,该ID的表编号与tableID一致
	 * 注:分库同时分表ID生成
	 * @param tableID
	 * @return
	 * @throws Exception
	 */
	public static synchronized long getUniqueID(long sourceID, int tableID) throws Exception {
		if(MDTConstantHelper.SERVER_ID <= 0) {
			throw new Exception("server id is error,please check config file!");
		}
		
		int sourceIndex = getDBIndex(sourceID);
		long destID = System.currentTimeMillis() - MDTConstantHelper.ID_FLAG;
		destID = (destID << 10) | tableID;//分表
		destID = (destID << 5) | sourceIndex;//分库
		destID = (destID << 4) | MDTConstantHelper.SERVER_ID;
		Thread.sleep(1);
		return destID;
	}
	
	/**
	 * 获得表索引号
	 * @param id 
	 * @param tableCount 分表总数
	 * @return
	 */
	public static int getTableIndex(long id, int tableCount){
		if(id<9999999999999999L){
			return 0;
		}
		return (int)((id >> 9 ) & (tableCount - 1));
	}
	
	/**
	 * 获得表索引号
	 * @param id 
	 * @param clazz 实体
	 * @return
	 */
	public static int getTableIndex(long id, Class<?> clazz){
//		if(Order.class.getName().equals(clazz.getName()) || Ticket.class.getName().equals(clazz.getName())){
//			if(id<9999999999999999l){
//				return 0;
//			}
//			if(id<54500000000000000L){
//				return 1;
//			}
//		}
		//取模定位表
		return MDTTableHelper.getTableIndex(clazz, id);
	}
	
	/**
	 * 获取ID所对应该的数据库编号
	 * @param ID
	 * @return 数据库
	 */
	public static int getDBIndex(long id) {
		return (int)((id>>4) & (MDTConstantHelper.DB_COUNT - 1));
	}
	
	/**
	 * 获取ID所对应该的数据库编号
	 * @param ID
	 * @return 数据库
	 */
	public static int getDBIndex(long id, Class<?> clazz) {
//		if(Order.class.getName().equals(clazz.getName()) || Ticket.class.getName().equals(clazz.getName())){
//			int dbIndex = 0;
//			List<Node> nodes = MDTTableHelper.getNodes(clazz);
//			if (null != nodes && nodes.size() > 0) {
//				dbIndex = nodes.get(0).getDbIndex();
//			}
//			
//			if(id<9999999999999999l){
//				return dbIndex;
//			}
//			if(id<54500000000000000L){
//				return dbIndex;
//			}
//		}
		//取模定位库
		return MDTTableHelper.getDBIndex(clazz, id);
	}
	
	/**
	 * 获取ID所对应该的数据库编号
	 * @param ID
	 * @return 数据库
	 */
	public static int getShortDBIndex(long id) {
		return (int)((id>>7) & (MDTConstantHelper.DB_COUNT - 1));
	}
	
	private static long tilNextMillis(final long lastTimestamp) {
		long timestamp = timeGen();
		while (timestamp <= lastTimestamp) {
			timestamp = timeGen();
		}
		return timestamp;
	}

	private static long timeGen() {
		return System.currentTimeMillis();
	}
	
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值