首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > Java相关 >

Java中UUID的代替方法?Oracle中系列的代替方法?解决办法

2013-11-11 
Java中UUID的代替方法?Oracle中系列的代替方法??这是昨天参加复试的时候,技术问的:一、您有么有一种办法来

Java中UUID的代替方法?Oracle中系列的代替方法??
这是昨天参加复试的时候,技术问的:
一、
您有么有一种办法来代替UUID,就是说保证全球无重复!
Ps:不用说用 时间 + 随机字符,就是这么说的,技术说那也可能有重复的!
不用说 Base64或Base58,这个也是基于UUID的
现在说的是你自己创造的"UUID"
二、
Oracle中有Sequence,那么您如何在不用Sequence的情况下,做出类似Sequence的效果呢?比方说我当前的最大Id是5,那么下一个应该就是6,但是我1秒可能有上百万的数据存入,您如何实现呢 Java Oracle Sequence UUID
[解决办法]
一、除了你说的2种我想不出来,坐等答案。
二、可以自己写Sequence生成器。

我项目中用的:


import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Map;

/**
*
* <b>Note</b>: Java实现的Sequence工具
*/
public class SequenceUtil {
        
        /**
         * 单例模式
         */
        private static SequenceUtil instance = new SequenceUtil();
        
        /**
         * 存放序列的MAP
         */
        private Map<String, KeyInfo> keyMap = new HashMap<String, KeyInfo>(20);
        private static final int POOL_SIZE = 1;

        /**
         * 防止外部实例化
         */
        private SequenceUtil() {
        }

        /**
         * 单例模式,获取单例
         *
         * @return SequenceUtils的单例对象
         */
        public static SequenceUtil getInstance() {
                return instance;
        }

        /**
         * 获取下一个sequence值
         *
         * @param keyName
         * Sequence名称
         * @return 下一个Sequence键值
         */
        public synchronized int getNextKeyValue(String keyName) {
                KeyInfo keyInfo = null;
                Integer 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;
        }
}

class KeyInfo {
        
        /**
         * 当前Sequence载体的最大值
         */
        private int maxKey;
        
        /**
         * 当前Sequence的最小值
         */
        private int minKey;
        
        /**
         * 下一个Sequence值
         */
        private int nextKey;
        
        /**
         * Sequence缓存值
         */
        private int poolSize;
        
        /**
         * Sequence的名称
         */
        private String keyName;
        
        /**
         * 更新存放Sequence表的语句
         */
        private static final String sql_update = "UPDATE intpub_Sequence SET KEYVALUE = KEYVALUE + ? WHERE KEYNAME = ?";
        
        /**
         * 查询Sequence表中的当前值
         */
        private static final String sql_query = "SELECT KEYVALUE FROM intpub_Sequence WHERE KEYNAME = ?";

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

        public String getKeyName() {
                return keyName;
        }

        public int getMaxKey() {
                return maxKey;
        }

        public int getMinKey() {
                return minKey;
        }

        public int getPoolSize() {
                return poolSize;
        }

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

        /**
         * 执行Sequence表初始化和更新工作
         *


         * @throws SQLException
         */
        private void retrieveFromDB() throws SQLException {

                Connection conn = ConnectionPool.getInstance().getConnection();
                // 查询数据库
                PreparedStatement pstmt_query = conn.prepareStatement(sql_query);
                pstmt_query.setString(1, keyName);
                ResultSet rs = pstmt_query.executeQuery();
                if (rs.next()) {
                        maxKey = rs.getInt(1) + poolSize;
                        minKey = maxKey - poolSize + 1;
                        nextKey = minKey;
                        rs.close();
                        pstmt_query.close();
                } else {
                        String init_sql = "INSERT INTO intpub_Sequence(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);
                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();
        }

}


[解决办法]
推荐一下,看看第一题的答案!
[解决办法]
使用MONGODB的ObjectID算法吧,目前为止我遇到的最优雅的ID生成策略....
[解决办法]
引用:
Quote: 引用:

使用MONGODB的ObjectID算法吧,目前为止我遇到的最优雅的ID生成策略....



能否解释一下,我在用mongodb,但是这个id生成原理没有去研究过

为了和你解释我又回去翻了一下书,怕解释错了误导你。。
MongDB的id采用12个双字节(24个字符)来处理
0123 
[解决办法]
 456 
[解决办法]
 78 
[解决办法]
 91011 
[解决办法]

时间戳  机器  PID  计数器
这在排序和分片上,都非常好处理,字符排序算法一般先看长度,其次从第一个字符比大小。
通过这样的设计能够很好的是这个随机码完成排序,由能通过计数器做分片,保证数据分布均匀

热点排行