Java实现的Sequence工具
来源:互联网 发布:传奇霸业数据汇总 编辑:程序博客网 时间:2024/05/01 06:19
导读:
Java实现的Sequence工具
Sequence是数据库应用中很重要的一个特性,可是有些数据库没有这个特性,比如很流行的开源数据库MySQL就没有Sequence,利用自增主键感觉很不爽,每个表的ID都要设置,通用性也不好。因此考虑为这些不支持Sequence的数据做一个Sequence工具。自动为整个系统提供主键生成策略。
下面是一个Sequence实现,以数据库MySQL为平台。源代码如下:
一、Sequence工具类
packagesequence;
importjava.util.HashMap;
importjava.util.Map;
importjava.sql.SQLException;
/**
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2008-4-2 15:21:30
* Note: Java实现的Sequence工具
*/
publicclassSequenceUtils {
privatestaticSequenceUtils _instance = newSequenceUtils();
privateMap keyMap = newHashMap(20); //Sequence载体容器
privatestaticfinalintPOOL_SIZE = 10; //Sequence值缓存大小
/**
* 禁止外部实例化
*/
privateSequenceUtils() {
}
/**
* 获取SequenceUtils的单例对象
* @return SequenceUtils的单例对象
*/
publicstaticSequenceUtils getInstance() {
return_instance;
}
/**
* 获取下一个Sequence键值
* @param keyName Sequence名称
* @return 下一个Sequence键值
*/
publicsynchronizedlonggetNextKeyValue(String keyName) {
KeyInfo keyInfo = null
Long keyObject = null
try{
if(keyMap.containsKey(keyName)) {
keyInfo = keyMap.get(keyName);
} else{
keyInfo = newKeyInfo(keyName, POOL_SIZE);
keyMap.put(keyName, keyInfo);
}
keyObject = keyInfo.getNextKey();
} catch(SQLException e) {
e.printStackTrace();
}
returnkeyObject;
}
}
二、Sequence载体
packagesequence;
importjava.sql.*;
/**
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2008-4-2 15:24:52
* Note: Sequence载体
*/
publicclassKeyInfo {
privatelongmaxKey; //当前Sequence载体的最大值
privatelongminKey; //当前Sequence载体的最小值
privatelongnextKey; //下一个Sequence值
privateintpoolSize; //Sequence值缓存大小
privateString keyName; //Sequence的名称
privatestaticfinalString sql_update = "UPDATE KEYTABLE SET KEYVALUE = KEYVALUE + ? WHERE KEYNAME = ?"
privatestaticfinalString sql_query = "SELECT KEYVALUE FROM KEYTABLE WHERE KEYNAME = ?"
publicKeyInfo(String keyName, intpoolSize) throwsSQLException {
this.poolSize = poolSize;
this.keyName = keyName;
retrieveFromDB();
}
publicString getKeyName() {
returnkeyName;
}
publiclonggetMaxKey() {
returnmaxKey;
}
publiclonggetMinKey() {
returnminKey;
}
publicintgetPoolSize() {
returnpoolSize;
}
/**
* 获取下一个Sequence值
*
* @return 下一个Sequence值
* @throws SQLException
*/
publicsynchronizedlonggetNextKey() throwsSQLException {
if(nextKey >maxKey) {
retrieveFromDB();
}
returnnextKey++;
}
/**
* 执行Sequence表信息初始化和更新工作
*
* @throws SQLException
*/
privatevoidretrieveFromDB() throwsSQLException {
System.out.println("");
Connection conn = DBUtils.makeConnection();
//查询数据库
PreparedStatement pstmt_query = conn.prepareStatement(sql_query);
pstmt_query.setString(1, keyName);
ResultSet rs = pstmt_query.executeQuery();
if(rs.next()) {
maxKey = rs.getLong(1) + poolSize;
minKey = maxKey - poolSize + 1;
nextKey = minKey;
rs.close();
pstmt_query.close();
} else{
System.out.println("执行Sequence数据库初始化工作!");
String init_sql = "INSERT INTO KEYTABLE(KEYNAME,KEYVALUE) VALUES('"+ keyName + "',10000 + "+ poolSize + ")"
Statement stmt = conn.createStatement();
stmt.executeUpdate(init_sql);
maxKey = 10000 + poolSize;
minKey = maxKey - poolSize + 1;
nextKey = minKey;
stmt.close();
return
}
//更新数据库
conn.setAutoCommit(false);
System.out.println("更新Sequence最大值!");
PreparedStatement pstmt_up = conn.prepareStatement(sql_update);
pstmt_up.setLong(1, poolSize);
pstmt_up.setString(2, keyName);
pstmt_up.executeUpdate();
pstmt_up.close();
conn.commit();
rs.close();
pstmt_query.close();
conn.close();
}
}
三、简单的数据库连接工具
packagesequence;
importjava.sql.*;
/**
* 简单的数据连接工具
* File: DBUtils.java
* User: leizhimin
* Date: 2008-3-18 15:19:12
*/
publicclassDBUtils {
publicstaticfinalString url = "jdbc:mysql://127.0.0.1:3306/testdb";
publicstaticfinalString username = "root"
publicstaticfinalString password = "leizhimin"
publicstaticfinalString driverClassName = "com.mysql.jdbc.Driver"
/**
* 获取数据库连接Connection
*
* @return 数据库连接Connection
*/
publicstaticConnection makeConnection() {
Connection conn = null
try{
Class.forName(driverClassName);
} catch(ClassNotFoundException e) {
e.printStackTrace();
}
try{
conn = DriverManager.getConnection(url, username, password);
} catch(SQLException e) {
e.printStackTrace();
}
returnconn;
}
publicstaticvoidmain(String args[]) {
testConnection();
}
/**
* 测试连接方法
*/
publicstaticvoidtestConnection() {
Connection conn = makeConnection();
try{
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM mysql.user");
while(rs.next()) {
String s1 = rs.getString(1);
String s2 = rs.getString(2);
System.out.println(s1 + "/t"+ s2);
}
rs.close();
stmt.close();
} catch(SQLException e) {
e.printStackTrace();
} finally{
try{
conn.close();
} catch(SQLException e) {
e.printStackTrace();
}
}
}
}
四、测试类(客户端)
packagesequence;
/**
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2008-4-2 15:31:30
* Company: LavaSoft(http://lavasoft.blog.51cto.com)
* Sequence测试(客户端)
*/
publicclassTestSequence {
/**
* 测试入口
* @param args
*/
publicstaticvoidmain(String args[]) {
test();
}
/**
* 测试Sequence方法
*/
publicstaticvoidtest() {
System.out.println("----------test()----------");
for(inti = 0; i <20; i++) {
longx = SequenceUtils.getInstance().getNextKeyValue("sdaf");
System.out.println(x);
}
}
}
五、Sequence表的代码(for MySQL5)
-- SQL for MySQL5
-- http://lavasoft.blog.51cto.com
-- 2008年4月3日
-- 创建数据库testdb
create database if not exists testdb character set gbk collate gbk_chinese_ci;
-- 创建Sequence表
DROP TABLE IF EXISTS keytable;
CREATE TABLE keytable (
KEYNAME varchar(24) NOT NULL COMMENT 'Sequence名称',
KEYVALUE bigint(20) DEFAULT '10000' COMMENT 'Sequence最大值',
PRIMARY KEY (KEYNAME)
) ENGINE=MyISAM DEFAULT CHARSET=gbk;
数据库操作的截屏:
六、运行测试类输出结果:
----------test()----------
更新Sequence最大值!
10061
10062
10063
10064
10065
10066
10067
10068
10069
10070
更新Sequence最大值!
10071
10072
10073
10074
10075
10076
10077
10078
10079
10080
Process finished with exit code 0
说明:这个Sequence工具很智能,当请求一个不存在的Sequence时,会自动生成一个Sequence,保存到数据库。当请求一个已经存在的Sequence时,会从Sequence载体的缓存中获取一个Sequence值返回,当Sequence载体的缓存值达到最大时,会自动重新初始化Sequence载体信息,并更新数据库记录信息。
参考文档:《Java与模式》多例模式一章。以上代码仅仅是阎宏博士一个例子的具体实现。
本文出自 “熔 岩” 博客,转载请与作者联系!
本文转自
http://lavasoft.blog.51cto.com/62575/69682
Java实现的Sequence工具
Sequence是数据库应用中很重要的一个特性,可是有些数据库没有这个特性,比如很流行的开源数据库MySQL就没有Sequence,利用自增主键感觉很不爽,每个表的ID都要设置,通用性也不好。因此考虑为这些不支持Sequence的数据做一个Sequence工具。自动为整个系统提供主键生成策略。
下面是一个Sequence实现,以数据库MySQL为平台。源代码如下:
一、Sequence工具类
packagesequence;
importjava.util.HashMap;
importjava.util.Map;
importjava.sql.SQLException;
/**
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2008-4-2 15:21:30
* Note: Java实现的Sequence工具
*/
publicclassSequenceUtils {
privatestaticSequenceUtils _instance = newSequenceUtils();
privateMap
privatestaticfinalintPOOL_SIZE = 10; //Sequence值缓存大小
/**
* 禁止外部实例化
*/
privateSequenceUtils() {
}
/**
* 获取SequenceUtils的单例对象
* @return SequenceUtils的单例对象
*/
publicstaticSequenceUtils getInstance() {
return_instance;
}
/**
* 获取下一个Sequence键值
* @param keyName Sequence名称
* @return 下一个Sequence键值
*/
publicsynchronizedlonggetNextKeyValue(String keyName) {
KeyInfo keyInfo = null
Long keyObject = null
try{
if(keyMap.containsKey(keyName)) {
keyInfo = keyMap.get(keyName);
} else{
keyInfo = newKeyInfo(keyName, POOL_SIZE);
keyMap.put(keyName, keyInfo);
}
keyObject = keyInfo.getNextKey();
} catch(SQLException e) {
e.printStackTrace();
}
returnkeyObject;
}
}
二、Sequence载体
packagesequence;
importjava.sql.*;
/**
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2008-4-2 15:24:52
* Note: Sequence载体
*/
publicclassKeyInfo {
privatelongmaxKey; //当前Sequence载体的最大值
privatelongminKey; //当前Sequence载体的最小值
privatelongnextKey; //下一个Sequence值
privateintpoolSize; //Sequence值缓存大小
privateString keyName; //Sequence的名称
privatestaticfinalString sql_update = "UPDATE KEYTABLE SET KEYVALUE = KEYVALUE + ? WHERE KEYNAME = ?"
privatestaticfinalString sql_query = "SELECT KEYVALUE FROM KEYTABLE WHERE KEYNAME = ?"
publicKeyInfo(String keyName, intpoolSize) throwsSQLException {
this.poolSize = poolSize;
this.keyName = keyName;
retrieveFromDB();
}
publicString getKeyName() {
returnkeyName;
}
publiclonggetMaxKey() {
returnmaxKey;
}
publiclonggetMinKey() {
returnminKey;
}
publicintgetPoolSize() {
returnpoolSize;
}
/**
* 获取下一个Sequence值
*
* @return 下一个Sequence值
* @throws SQLException
*/
publicsynchronizedlonggetNextKey() throwsSQLException {
if(nextKey >maxKey) {
retrieveFromDB();
}
returnnextKey++;
}
/**
* 执行Sequence表信息初始化和更新工作
*
* @throws SQLException
*/
privatevoidretrieveFromDB() throwsSQLException {
System.out.println("");
Connection conn = DBUtils.makeConnection();
//查询数据库
PreparedStatement pstmt_query = conn.prepareStatement(sql_query);
pstmt_query.setString(1, keyName);
ResultSet rs = pstmt_query.executeQuery();
if(rs.next()) {
maxKey = rs.getLong(1) + poolSize;
minKey = maxKey - poolSize + 1;
nextKey = minKey;
rs.close();
pstmt_query.close();
} else{
System.out.println("执行Sequence数据库初始化工作!");
String init_sql = "INSERT INTO KEYTABLE(KEYNAME,KEYVALUE) VALUES('"+ keyName + "',10000 + "+ poolSize + ")"
Statement stmt = conn.createStatement();
stmt.executeUpdate(init_sql);
maxKey = 10000 + poolSize;
minKey = maxKey - poolSize + 1;
nextKey = minKey;
stmt.close();
return
}
//更新数据库
conn.setAutoCommit(false);
System.out.println("更新Sequence最大值!");
PreparedStatement pstmt_up = conn.prepareStatement(sql_update);
pstmt_up.setLong(1, poolSize);
pstmt_up.setString(2, keyName);
pstmt_up.executeUpdate();
pstmt_up.close();
conn.commit();
rs.close();
pstmt_query.close();
conn.close();
}
}
三、简单的数据库连接工具
packagesequence;
importjava.sql.*;
/**
* 简单的数据连接工具
* File: DBUtils.java
* User: leizhimin
* Date: 2008-3-18 15:19:12
*/
publicclassDBUtils {
publicstaticfinalString url = "jdbc:mysql://127.0.0.1:3306/testdb";
publicstaticfinalString username = "root"
publicstaticfinalString password = "leizhimin"
publicstaticfinalString driverClassName = "com.mysql.jdbc.Driver"
/**
* 获取数据库连接Connection
*
* @return 数据库连接Connection
*/
publicstaticConnection makeConnection() {
Connection conn = null
try{
Class.forName(driverClassName);
} catch(ClassNotFoundException e) {
e.printStackTrace();
}
try{
conn = DriverManager.getConnection(url, username, password);
} catch(SQLException e) {
e.printStackTrace();
}
returnconn;
}
publicstaticvoidmain(String args[]) {
testConnection();
}
/**
* 测试连接方法
*/
publicstaticvoidtestConnection() {
Connection conn = makeConnection();
try{
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM mysql.user");
while(rs.next()) {
String s1 = rs.getString(1);
String s2 = rs.getString(2);
System.out.println(s1 + "/t"+ s2);
}
rs.close();
stmt.close();
} catch(SQLException e) {
e.printStackTrace();
} finally{
try{
conn.close();
} catch(SQLException e) {
e.printStackTrace();
}
}
}
}
四、测试类(客户端)
packagesequence;
/**
* Created by IntelliJ IDEA.
* User: leizhimin
* Date: 2008-4-2 15:31:30
* Company: LavaSoft(http://lavasoft.blog.51cto.com)
* Sequence测试(客户端)
*/
publicclassTestSequence {
/**
* 测试入口
* @param args
*/
publicstaticvoidmain(String args[]) {
test();
}
/**
* 测试Sequence方法
*/
publicstaticvoidtest() {
System.out.println("----------test()----------");
for(inti = 0; i <20; i++) {
longx = SequenceUtils.getInstance().getNextKeyValue("sdaf");
System.out.println(x);
}
}
}
五、Sequence表的代码(for MySQL5)
-- SQL for MySQL5
-- http://lavasoft.blog.51cto.com
-- 2008年4月3日
-- 创建数据库testdb
create database if not exists testdb character set gbk collate gbk_chinese_ci;
-- 创建Sequence表
DROP TABLE IF EXISTS keytable;
CREATE TABLE keytable (
KEYNAME varchar(24) NOT NULL COMMENT 'Sequence名称',
KEYVALUE bigint(20) DEFAULT '10000' COMMENT 'Sequence最大值',
PRIMARY KEY (KEYNAME)
) ENGINE=MyISAM DEFAULT CHARSET=gbk;
数据库操作的截屏:
六、运行测试类输出结果:
----------test()----------
更新Sequence最大值!
10061
10062
10063
10064
10065
10066
10067
10068
10069
10070
更新Sequence最大值!
10071
10072
10073
10074
10075
10076
10077
10078
10079
10080
Process finished with exit code 0
说明:这个Sequence工具很智能,当请求一个不存在的Sequence时,会自动生成一个Sequence,保存到数据库。当请求一个已经存在的Sequence时,会从Sequence载体的缓存中获取一个Sequence值返回,当Sequence载体的缓存值达到最大时,会自动重新初始化Sequence载体信息,并更新数据库记录信息。
参考文档:《Java与模式》多例模式一章。以上代码仅仅是阎宏博士一个例子的具体实现。
本文出自 “熔 岩” 博客,转载请与作者联系!
本文转自
http://lavasoft.blog.51cto.com/62575/69682
- Java实现的Sequence工具
- Java实现的Sequence工具
- Java实现的Sequence工具
- Java实现的Sequence工具开发工具
- Java实现的Sequence工具 - 1
- Java实现的Sequence工具 - 2
- java截图工具的实现
- mysql实现oracle的sequence
- 基于Mysql的Sequence实现
- Java实现算法之Brackets Sequence问题
- Java实现的ZIP解压缩工具类
- java关机工具类的实现
- java实现Http工具类的封装
- Java实现的一个画图工具
- Java 实现的内容搜索工具
- JAVA 实现简单的日志工具
- Java实现的简单字符串加密工具
- MySQL 5.0的Sequence的实现
- AJAX框架--jQuery使用手册
- 学习EJB for JBoss 3.2笔记(1)
- 技术博客正式安窝于csdn
- 终于决定开始写博客了
- 十大互联网彩蛋
- Java实现的Sequence工具
- 界面表格数据对齐一般原则
- 保存几何元素到oracle spatial
- 一个基于封装CSLA框架后,设计业务类的例子:users
- java连接oracle
- 顺序表
- 完美的文本只能输入数字问题!
- hibernate下实现分页实例
- 一个基于封装CSLA框架后,设计业务类的例子:User