Java实现的Sequence工具 - 1

来源:互联网 发布:it专业课程 编辑:程序博客网 时间:2024/05/22 11:01
Java实现的Sequence工具
 
Sequence是数据库应用中很重要的一个特性,可是有些数据库没有这个特性,比如很流行的开源数据库MySQL就没有Sequence,利用自增主键感觉很不爽,每个表的ID都要设置,通用性也不好。因此考虑为这些不支持Sequence的数据做一个Sequence工具。自动为整个系统提供主键生成策略。
 
下面是一个Sequence实现,以数据库MySQL为平台。源代码如下:
 
一、Sequence工具类
package sequence; 

import java.util.HashMap; 
import java.util.Map; 
import java.sql.SQLException; 

/** 
* Created by IntelliJ IDEA.<br> 
* <b>User</b>: leizhimin<br> 
* <b>Date</b>: 2008-4-2 15:21:30<br> 
* <b>Note</b>: Java实现的Sequence工具 
*/
 
public class SequenceUtils { 
    private static SequenceUtils _instance = new SequenceUtils(); 
    private Map<String, KeyInfo> keyMap = new HashMap<String, KeyInfo>(20); //Sequence载体容器 
    private static final int POOL_SIZE = 10;      //Sequence值缓存大小 

    /** 
     * 禁止外部实例化 
     */
 
    private SequenceUtils() { 
    } 

    /** 
     * 获取SequenceUtils的单例对象 
     * @return SequenceUtils的单例对象 
     */
 
    public static SequenceUtils getInstance() { 
        return _instance; 
    } 

    /** 
     * 获取下一个Sequence键值 
     * @param keyName Sequence名称 
     * @return 下一个Sequence键值 
     */
 
    public synchronized long getNextKeyValue(String keyName) { 
        KeyInfo keyInfo = null
        Long keyObject = null
        try { 
            if (keyMap.containsKey(keyName)) { 
                keyInfo = keyMap.get(keyName); 
            } else { 
                keyInfo = new KeyInfo(keyName, POOL_SIZE); 
                keyMap.put(keyName, keyInfo); 
            } 
            keyObject = keyInfo.getNextKey(); 
        } catch (SQLException e) { 
            e.printStackTrace(); 
        } 
        return keyObject; 
    } 
}
 
二、Sequence载体
package sequence; 

import java.sql.*; 

/** 
* Created by IntelliJ IDEA.<br> 
* <b>User</b>: leizhimin<br> 
* <b>Date</b>: 2008-4-2 15:24:52<br> 
* <b>Note</b>: Sequence载体 
*/
 
public class KeyInfo { 
    private long maxKey;        //当前Sequence载体的最大值 
    private long minKey;        //当前Sequence载体的最小值 
    private long nextKey;       //下一个Sequence值 
    private int poolSize;       //Sequence值缓存大小 
    private String keyName;     //Sequence的名称 
    private static final String sql_update = "UPDATE KEYTABLE SET KEYVALUE = KEYVALUE + ? WHERE KEYNAME = ?"
    private static final String sql_query = "SELECT KEYVALUE FROM KEYTABLE WHERE KEYNAME = ?"

    public KeyInfo(String keyName, int poolSize) throws SQLException { 
        this.poolSize = poolSize; 
        this.keyName = keyName; 
        retrieveFromDB(); 
    } 

    public String getKeyName() { 
        return keyName; 
    } 

    public long getMaxKey() { 
        return maxKey; 
    } 

    public long getMinKey() { 
        return minKey; 
    } 

    public int getPoolSize() { 
        return poolSize; 
    } 

    /** 
     * 获取下一个Sequence值 
     * 
     * @return 下一个Sequence值 
     * @throws SQLException 
     */
 
    public synchronized long getNextKey() throws SQLException { 
        if (nextKey > maxKey) { 
            retrieveFromDB(); 
        } 
        return nextKey++; 
    } 

    /** 
     * 执行Sequence表信息初始化和更新工作 
     * 
     * @throws SQLException 
     */
 
    private void retrieveFromDB() throws SQLException { 
        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(); 
    } 
}
 
三、简单的数据库连接工具
package sequence; 

import java.sql.*; 

/** 
* 简单的数据连接工具 
* File: DBUtils.java 
* User: leizhimin 
* Date: 2008-3-18 15:19:12 
*/
 
public class DBUtils { 
    public static final String url = "jdbc:mysql://127.0.0.1:3306/testdb"; 
    public static final String username = "root"
    public static final String password = "leizhimin"
    public static final String driverClassName = "com.mysql.jdbc.Driver"

    /** 
     * 获取数据库连接Connection 
     * 
     * @return 数据库连接Connection 
     */
 
    public static Connection 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(); 
        } 
        return conn; 
    } 

    public static void main(String args[]) { 
        testConnection(); 
    } 

    /** 
     * 测试连接方法 
     */
 
    public static void testConnection() { 
        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(); 
            } 
        } 
    } 
}
 
四、测试类(客户端)
package sequence; 

/** 
* Created by IntelliJ IDEA. 
* User: leizhimin 
* Date: 2008-4-2 15:31:30 
* Company: LavaSoft([url]http://lavasoft.blog.51cto.com[/url]) 
* Sequence测试(客户端) 
*/
 
public class TestSequence { 
    /** 
     * 测试入口 
     * @param args 
     */
 
    public static void main(String args[]) { 
        test(); 
    } 

    /** 
     * 测试Sequence方法 
     */
 
    public static void test() { 
        System.out.println("----------test()----------"); 
        for (int i = 0; i < 20; i++) { 
            long x = SequenceUtils.getInstance().getNextKeyValue("sdaf"); 
            System.out.println(x); 
        } 
    } 
}
 
五、Sequence表的代码(for MySQL5)
-- SQL for MySQL5 
-- [url]http://lavasoft.blog.51cto.com[/url] 
-- 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 
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 政府卖非农户口怎么办 90年代买了户口怎么办 上海应届大学生积分不够怎么办 广州居住证回执单丢了怎么办 惠阳居住证回执单丢了怎么办 南京居住证换地方了怎么办 买家退回的商品有问题怎么办 农转农户口手续怎么办 原房东不迁户口我怎么办 户主信息页掉了怎么办 户主变了户口本首页怎么办 大人户口迁走小孩户口怎么办 网银转账处理中怎么办 教育部学籍在线验证报告有错怎么办 验证码连续输入三次错误怎么办 交通运输监察大队截车了怎么办 平安安康续保没成功怎么办 危险品经营许可证到期了怎么办 郑万350渝万怎么办 厂里饭堂的饭好难吃怎么办 学校的食堂饭菜不好不卫生怎么办 亲戚借钱我真没有怎么办 榴莲肉酸了吃了怎么办 亲戚赖在家里住怎么办 食堂饭菜味道差该怎么办 被监视居住公安打电话睡着了怎么办 鱼缺氧浮上水面怎么办 车载低音炮有电流声怎么办 925纯银变黑了怎么办 银子放久了变黑怎么办 高铁票网上售空怎么办 高铁票出票失败怎么办 高铁票名字打错怎么办 高铁票姓名错了怎么办 高铁票弄丢了怎么办 用过的车票丢了怎么办 高铁票被水洗了怎么办 沈阳地铁卡丢了怎么办 火车票没写检票口怎么办 吃鸡听的脚步声距离太近怎么办 检票时车票丢了怎么办