之前在BlogJava上发表过这篇文章,那时没怎么做整理。想不到已经有博友把它弄到ITEye来了(虽然写得水平差,但还是希望那位博友能注明是转载的)。这次稍作了整理,自己也加深下印象。
使用场景:用于生成实体主键键值,每次增长1。
框架支持:spring,hibernate
工作方式:单例,序列号生成器支持缓存键值,可设定每次取键的个数。用于集群环境时,取键个数设为1即可。
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import com.pro.base.model.TableKey;
import com.pro.base.service.BasicService;
/***
* 基于单例模式的多键值带缓存序列号生成器
*
* 思路:
* 数据库表通过Hibernate映射为实体类,主键通过序列号生成器(KeyGenerator)生成;
* 序列号生成器以Singleton方式工作,并维护所有需要维护的实体的序列号(KeyBean);
* 列号生成器缓存一定的键值,避免每次取序列号都从数据库获取;
* 数据库建立实体和当前键值对应表,每从列号生成器获取一个序列时,同步到该键值对应表,避免宕机后不一致
*
* @author o_oand0_0
*
*/
public class KeyGenerator implements ApplicationContextAware {
//实现ApplicationContextAware,Spring对applicationContext自动装配
private ApplicationContext applicationContext;
//键值实体类
private Map<String, KeyBean> keyMap;
//数据库服务
private BasicService basicService;
//设置要缓存的键值的数量,建议在团队开发测试时设为1,省得总出现主键冲突,到上线后再调大
//另外集群环境下使用时,需要把该值设为1,相当于每次取键值的时候同时更新数据库
private static long keyNum=20;
private static final KeyGenerator instance=null;
private KeyGenerator() {
basicService=(BasicService)applicationContext.getBean("basicService");
}
public ApplicationContext getApplicationContext() {
return applicationContext;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
this.applicationContext=applicationContext;
}
//以单例方式获取序列号生成器
public static synchronized KeyGenerator getInstance(){
if(instance==null){
return new KeyGenerator();
}else{
return instance;
}
}
/**
* 根据类名获取序列号
* @param clazz
* @return
*/
public String generatorKey(Class clazz){
return getKey(clazz);
}
/**
* 生成序列号,并同步至数据库
* 此方法可以根据自己需要定义生成序列号的规则
* @param clazz
* @return
*/
public String getKey(Class clazz) {
if (keyMap == null) {
keyMap = new ConcurrentHashMap<String, KeyBean>();
}
KeyBean kb = keyMap.get(clazz.getName());
if (kb == null||kb.getMaxIndex()==kb.getNowIndex()) {
updateKeyBean(clazz.getName());
}
kb = keyMap.get(clazz.getName());
long now=kb.getNowIndex();
kb.setNowIndex(now+1);
return now+"";
}
/**
* 同步序列值到数据库,并修改序列号生成器对应实体的下一键值
* @param classPath
*/
private void updateKeyBean(String classPath) {
TableKey tk = (TableKey) basicService.expandObjectByKey(TableKey.class.getName(),
classPath);
KeyBean kb=new KeyBean();
kb.setKeyName(classPath);
try {
if (tk == null) {
tk=new TableKey();
kb.setMaxIndex(keyNum);
kb.setNowIndex(1);
tk.setTableName(classPath);
tk.setNowIndex(""+keyNum);
basicService.insert(tk);
} else {
kb.setMaxIndex(keyNum+Long.valueOf(tk.getNowIndex()));
kb.setNowIndex(Long.valueOf(tk.getNowIndex()));
tk.setNowIndex(Long.valueOf(tk.getNowIndex()) + keyNum + "");
basicService.update(tk);
}
keyMap.put(classPath, kb);
} catch (Exception e) {
e.printStackTrace();
}
}
public Map<String, KeyBean> getKeyMap() {
return keyMap;
}
public void setKeyMap(Map<String, KeyBean> keyMap) {
this.keyMap = keyMap;
}
public BasicService getBasicService() {
return basicService;
}
public void setBasicService(BasicService basicService) {
this.basicService = basicService;
}
/***
* 键值实体类
* @author o_oand0_0
*
*/
protected class KeyBean {
private String keyName;
private long nowIndex;
private long maxIndex;
public String getKeyName() {
return keyName;
}
public void setKeyName(String keyName) {
this.keyName = keyName;
}
public long getNowIndex() {
return nowIndex;
}
public void setNowIndex(long nowIndex) {
this.nowIndex = nowIndex;
}
public long getMaxIndex() {
return maxIndex;
}
public void setMaxIndex(long maxIndex) {
this.maxIndex = maxIndex;
}
}
}
/**
* TableKey 实体.
* 记录实体的类名和当前的索引号,对应数据库表table_key
* @author o_oand0_0
*/
public class TableKey implements java.io.Serializable {
// Fields
private String tableName;
private String nowIndex;
// Constructors
/** default constructor */
public TableKey() {
}
/** full constructor */
public TableKey(String tableName, String nowIndex) {
this.tableName = tableName;
this.nowIndex = nowIndex;
}
// Property accessors
public String getTableName() {
return this.tableName;
}
public void setTableName(String tableName) {
this.tableName = tableName;
}
public String getNowIndex() {
return this.nowIndex;
}
public void setNowIndex(String nowIndex) {
this.nowIndex = nowIndex;
}
}
需要在applicationContext.xml中生成器:
<bean name="keyGenerator" class="com.pro.base.util.KeyGenerator">
<property name="basicService" ref="basicService"></property>
</bean>
使用方法:
String keyId = KeyGenerator.getInstance().getKey(Attachments.class);
分享到:
相关推荐
cod4序列号生成器 cod4序列号生成器
7. **扩展性**:对于大型系统,序列号生成器可能需要设计成可扩展的,以便在集群环境中支持多个节点同时生成序列号。 虽然具体的实现细节无法提供,但上述知识点提供了一个基本的框架,可以帮助理解数据库序列号...
然而,"Nero Burning Rom 序列号生成器"涉及的话题较为敏感,因为这可能指的是一个用于生成非法或假冒软件序列号的工具,这违反了软件版权法律。 首先,让我们明确一点:合法使用软件是每个用户的义务,尊重知识...
易语言序列号生成器源码,序列号生成器,十六进制到十进制,十进制到十六进制,序列号显示,序列号算法,序列号反算,读取授权文件,秘密,wvsprintfA,StrToIntExA
虚拟机序列号生成器.rar
卡巴斯基序列号生成器
### 序列号生成器实现解析 #### 一、概述 本文将深入解析一个Java实现的序列号生成器,该生成器主要用于在分布式系统中生成唯一标识符(ID)。通过分析其核心方法`nextId()`及辅助方法,我们将了解它是如何确保在...
【标题】"adobe-dreamwear cs4序列号生成器"所涉及的知识点主要集中在Adobe Dreamweaver CS4这款软件的授权与激活机制上。Adobe Dreamweaver是Adobe公司开发的一款专业级网页设计和开发工具,它融合了视觉设计与代码...
web storm 序列号生成器, 破解, 支持当前最新的WebStorm3.03, 3.03版本支持NodeJS的开发. 非常好用的JavaScript的开发工具.
系统硬盘序列号 网卡MAC 主板信息 支持Windows10 1809 1903 1909 2004 20h2 21h1 使用方法就是依次输入1 2 3就行 重启不会自动恢复 : 随机化注册表和重置网卡数据 重启会自动恢复 : 加载匿名驱动 建议配合影子系统...
在描述中提到的“vmware workstation 10 序列号生成器”是指一种工具,通常这类工具是非官方的,目的是为了生成可以激活VMware Workstation 10的序列号。然而,值得注意的是,使用这种序列号生成器是违反VMware的...
Steelray Project Viewer序列号生成器noy-steelray.project.viewer.keygen.jar 支持5.0以上版本,其他版本未测试 运行需安装jdk、jre 另,内含多个可用的license
软件序列号生成器,通取物理地址,实现对MAC地址的绑定。加密好工具。
描述中提到的“序列号生成器”通常是指一种用于生成软件激活码的工具。在Balsamiq Mockups的情况下,这个“keygen”可能是第三方开发的,旨在允许用户免费或非法地使用软件。使用序列号生成器违反了软件的许可协议,...
在IT行业中,序列号生成是常见的...总的来说,C#自动生成序列号涉及多个知识点,包括`Guid`、`DateTime`、随机数生成以及可能的加密和验证策略。通过理解和运用这些工具,开发者可以创建出符合业务需求的序列号系统。
#### 多线程下的单例模式实现 由于单例模式涉及到全局共享资源的访问,因此在多线程环境下需要特别注意同步问题。下面是一些常见的实现方式: 1. **懒汉式,线程不安全**:这种方式简单,但是不支持多线程,容易...
在描述中提到的“代码实现”是指序列号生成器的源代码,这类工具通常是非法的,因为它们试图绕过软件的版权保护机制。序列号生成器通过模拟官方的验证算法来生成看似合法的序列号,这种行为违反了软件使用协议,并...
eset 序列号生成器eset 序列号生成器eset 序列号生成器eset 序列号生成器
完全意义上的 汉语大辞典5.87序列号生成程序,不是程序的破解,真正的注册序列号,一台机器对应很多序列号,选择一个输入即可完美注册
【标题】"eclipse序列号生成器"涉及的是软件授权和Eclipse集成开发环境(IDE)的相关知识。Eclipse是一款开源、跨平台的Java IDE,广泛用于Java应用程序的开发,同时也支持其他编程语言如C++、Python等。然而,这里...