浏览 2116 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-03-12
搭建java代码框架
引入辅助类和基类
PKgen为 PK 生成器 package net.sw.util; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * * 用来生成唯一的PK * 该 PK 生成器生成 19 位的唯一 long 值,精确到万分之一秒, * 最后一位为尾数,用来在集群环境下保证PK的唯一性。 * * 该PK生成虽然依赖于时间,但是在运行过程中改变时间不会影响PK, * 但是如果将系统时间后调,然后重新启动,有可能造成PK重复。 * * 该 PK 生成器不依赖于数据库,相比依赖数据表的PK生成器,速度快,而且值可读 * * @author <a href="mailto:yang_y@sysnet.com.cn">Young Yang</a> */ public class PKgen { /** * PK生成锁,用来限定同一时刻只有一个线程进入PK生成计算 */ private final Lock LOCK = new ReentrantLock(); /** * 初始化时的毫秒数,因为该时间会随系统时间的改变而改变, * 所以计算方法为该时间加上通过 nanoTime 计算出来的时间差 */ private final static Long startMilli = System.currentTimeMillis(); /** * 初始化时的纳秒数,用来计量时间差,nanoTime不会随着系统时间的修改而改变 */ private final static long startNano = System.nanoTime(); /** * 记录上一次生成 的 PK,如果新生成的PK和上次相等,则需要再次生成 */ private volatile long lastPK = -1; //private final static SimpleDateFormat dateFormat = new SimpleDateFormat( // "yyyyMMddHHmmssSSS"); private final static SimpleDateFormat dateFormat = new SimpleDateFormat( "yyMMddHHmmssSSS"); /** * 返回的long PK的尾数,尾数可以用来在集群环境中判断该PK由哪一个节点产生 * 尾数通过配置设定 */ private int suffix = 0; private static final Map<Integer, PKgen> instanceMap = new HashMap<Integer, PKgen>(); // 必须提供正确的参数,以保证 suffix 在机群环境的唯一性 private PKgen(int suffix) { this.suffix = suffix; } public synchronized static PKgen getInstance() { return getInstance(0); } /** * 单机环境下,应该保证用相同的 suffix * 在集群环境中,不同的机器必须提供不同的 suffix 来保证生成的ID的唯一性 * @param suffix * 唯一标识好 */ public synchronized static PKgen getInstance(int suffix) { PKgen pkgen; if (!instanceMap.containsKey(suffix)) { pkgen = new PKgen(suffix); instanceMap.put(suffix, pkgen); } else { pkgen = instanceMap.get(suffix); } return pkgen; } /** * 返回下一个 long 型 PK, format: 2006111423361344491 <br> * yyyyMMddHHmmssSSS + Macro Seconds + suffix * @return long PK */ public long nextPK() { LOCK.lock(); try { long newPK; do { long pastNano = System.nanoTime() - startNano; // 纳秒时间差 long milliTime = pastNano / 1000000; // 取得毫秒差 long macroTime = (pastNano / 100000) % 10; // 取得微秒第一位, // 计算出来的long PK,精度到万分之一秒(百微妙),加上尾数,一共19位,这是 Long.MAX_VALUE的最大位数了 newPK = Long.parseLong(dateFormat.format(new Date(startMilli + milliTime)) + macroTime + suffix); } while (lastPK == newPK); // 如果生成的相同,则再次计算 lastPK = newPK; // 设置 lastPK return newPK; } finally { LOCK.unlock(); } } public static void main(String[] args) throws Exception { PKgen pkg = PKgen.getInstance(0); int i = 0; long now = System.currentTimeMillis(); while (i++ < 10) { System.out.println(pkg.nextPK()); } System.out.println("Time: " + (System.currentTimeMillis() - now)); } }
BaseDomain package net.sw.base.domain; import java.util.Date; import javax.persistence.Column; import javax.persistence.Id; import javax.persistence.MappedSuperclass; import org.apache.commons.lang.builder.ToStringBuilder; import org.apache.commons.lang.builder.ToStringStyle; /** * 领域对象基类 * * @author vyyv * */ @SuppressWarnings("serial") @MappedSuperclass public abstract class BaseDomain implements java.io.Serializable { public BaseDomain() { // 对象有可能是在客户端由flex生成,不会执行这个构造方法,所以不能在此处添加ID // this.id = PKgen.getInstance(0).nextPK(); this.id=new Long(0); } /** * 领域对象编码 */ @Id @Column Long id; /** * 领域对象名称 */ @Column String name; /** * 领域对象描述 */ @Column String description; /** * 领域对象创建时间 */ @Column Date createtime; (setter getter 略) ........... ............ }
GenericDao package net.sw.base.dao; import java.io.Serializable; import java.util.List; /** * * @author vyyv * @param <T> * a type variable * @param <PK> * the primary key for that type */ public interface GenericDao<T, PK extends Serializable> { /** * 获取所有对象实例 * @return 由所有对象实例组成的List */ List<T> getAll(); /** * 获取一个对象实例 * 如果不存在抛出ObjectRetrievalFailureException * @param id 对象ID * @return 一个对象实例 * @see org.springframework.orm.ObjectRetrievalFailureException */ T get(PK id); /** * 判断对象实例是否存在 *@param id 对象ID * @return - 存在返回true,不存在返回false */ boolean exists(PK id); /** * 保存对象实例 - 新建或更新 * @param object 需要保存的对象 * @return 保存之后的对象(保存的动作可能会修改对象,例如:ID,createtime) */ T save(T object); /** * 删除对象实例 * @param id */ void remove(PK id); } GenericManager package net.sw.base.service; import java.io.Serializable; import java.util.List; /** * * @author vyyv</a> * @param <T> * a type variable * @param <PK> * the primary key for that type */ public interface GenericManager<T, PK extends Serializable> { /** * 获取所有对象实例 * @return 由所有对象实例组成的List */ List<T> getAll(); /** * 根据ID获取一个对象实例 * @param id 对象ID * @return 一个对象实例 */ T get(PK id); /** * 判断对象实例是否存在 *@param id 对象ID * @return - 存在返回true,不存在返回false */ boolean exists(PK id); /** * 保存对象实例 - 新建或更新 * @param object 需要保存的对象 * @return 保存之后的对象(保存的动作可能会修改对象,例如:ID,createtime) */ T save(T object); /** * 删除对象实例 * @param id */ void remove(PK id); }
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |