欢迎光临
我们一直在努力

一个用java实现的数据库序列生成器-JSP教程,资料/其它

建站超值云服务器,限时71元/月

如果是集群等应用这个就不行了,只能在单应用的情况下使用
对于每个序列键只需在第一次使用时查询数据库,后面的都将不需要查询
有非常详细的注释,我就不多说了

package org.shaoye.common.sql;

import java.util.hashmap;
import java.sql.connection;
import java.sql.preparedstatement;
import java.sql.resultset;
import java.sql.sqlexception;

/**
* 类<code>key</code>是一个数据库主键生成器,用序列号的方式来产生数据库中需要的主键值。
* <p>
* <code>key</code>目前支持的数据库包括oracle的所有版本、mysql的3.x以上的版本
* 以及所有支持max()函数的数据库,支持字段类型仅为数字类型的主键,对于字符及其它类型的主键尚不提供支持。
* <p>
* 在使用时只需提供表名、字段名(主键)以及到数据库的jdbc连接,如果想要获得message表的id字段的下一个
* 主键值时:
* <p><blockquote><pre>
*     java.sql.connection conn = …;
*     org.shaoye.common.sql.key key = org.shaoye.common.sql.key.getinstance();
*     int keyvalue = key.getnextkey("message", "id", conn);
*     string sql = "insert into message (id,…) values (" + keyvalue + ",…)";
*     //执行插入操作…
* </pre></blockquote><p>
*
* @author 令少爷(shaoye@vip.sina.com)
* @since magic 0.1
*/
public final class key {

/**
  * key的最大值,默认为9223372036854775807,即long类型的最大值
  */
private long max = 9223372036854775807l;

/**
  * key的最小值,默认为1
  * */
private long min = 1l;

/**
  * key的唯一实例,通过getinstance()方法获得
  * */
private static key keygen = new key();

/**
  * keyinfo类的实例列表,默认容量为5个
  * */
private hashmap keylist = new hashmap(5); //keyinfo 列表

/**
  * 私有的默认构造方法,防止外部构造类的实例
  * */
private key() {
}

/**
  * 获得key的唯一实例
  * */
public static key getinstance() {
  return keygen;
}

/**
  * 用指定的表和字段获得key的下一个值,主键的值不得超过2147483647
  * @param tablename   数据库中的表名,表中必须有一个数字主键
  * @param keyname   表(tablename)中的字段名
  * @param conn    jdbc连接,如果欲获得的key是第一次取值,则必须保证conn能连接到数据库
  * @return key的下一个主键的int值
  * @throws <code>keyexception</code>  如果表名或字段名不存在、访问数据库错误或key的值大于2147483647时抛出
  */
public int getnextkey(string tablename, string keyname, connection conn) throws keyexception {
  long value = getnextkeylong(tablename, keyname, conn);
  if (value > 2147483647l) {
   throw new keyexception("keys value too big,please call getnextkeylong method!");
  }
  return (new long(value)).intvalue();
}

/**
  * 用指定的表和字段获得key的下一个值,最大为9223372036854775807
  * @param tablename   数据库中的表名,表中必须有一个数字主键
  * @param keyname   表(tablename)中的字段名
  * @param conn    jdbc连接,如果欲获得的key是第一次取值,则必须保证conn能连接到数据库
  * @return key的下一个主键的long值
  * @throws <code>keyexception</code>  如果表名或字段名不存在或访问数据库错误时抛出
  */
public long getnextkeylong(string tablename, string keyname, connection conn)
  throws keyexception {
  keyinfo keyinfo;
  string item = tablename + "." + keyname;
  try {
   if (keylist.containskey(item)) {
    keyinfo = (keyinfo) keylist.get(item);
   }
   else {
    keyinfo = new keyinfo(tablename, keyname, conn);
    keylist.put(item, keyinfo);
   }
   return keyinfo.getnextkey();
  }
  catch (sqlexception sqle) {
   throw new keyexception(sqle);
  }
}

/**
  * 用指定的"表<code>.</code>字段"形式的字符串获得key的下一个值,主键的值不得超过2147483647
  * @param tabledotfield  "表.字段"形式的字符串,如:message.id
  * @param conn    jdbc连接,如果欲获得的key是第一次取值,则必须保证conn能连接到数据库
  * @return key的下一个主键的int值
  * @throws <code>keyexception</code>  如果表名或字段名不存在、访问数据库错误或key的值
  * 大于2147483647时抛出
  */
public int getnextkey(string tabledotfield, connection conn) throws keyexception {
  long value = getnextkeylong(tabledotfield, conn);
  if (value > 2147483647l) {
   throw new keyexception("keys value too big,please call getnextkeylong method!");
  }
  return (new long(value)).intvalue();
}

/**
  * 用指定的"表<code>.</code>字段"形式的字符串获得key的下一个值,最大为9223372036854775807
  * @param tabledotfield  "表.字段"形式的字符串,如:message.id
  * @param conn    jdbc连接,如果欲获得的key是第一次取值,则必须保证conn能连接到数据库
  * @return key的下一个主键的int值
  * @throws <code>keyexception</code>  如果表名或字段名不存在或访问数据库错误时抛出
  */
public long getnextkeylong(string tabledotfield, connection conn) throws keyexception {
  int dot_index = tabledotfield.indexof(".");
  if (tabledotfield.indexof(".") < 1) {
   throw new keyexception("unknown key " + tabledotfield + "!");
  }
  string tab = tabledotfield.substring(0, dot_index);
  string key = tabledotfield.substring(dot_index);
  return getnextkeylong(tab, key, conn);
}

/**
  * 用指定的表和字段获得key的当前值,主键的值不得超过2147483647
  * @param tablename   数据库中的表名,表中必须有一个数字主键
  * @param keyname   表(tablename)中的字段名
  * @param conn    jdbc连接,如果欲获得的key是第一次取值,则必须保证conn能连接到数据库
  * @return key的当前int值
  * @throws <code>keyexception</code>  如果表名或字段名不存在、访问数据库错误或key的值大于2147483647时抛出
  */
public int getcurrentkey(string tablename, string keyname, connection conn)
  throws keyexception {
  long value = getcurrentkeylong(tablename, keyname, conn);
  if (value > 2147483647l) {
   throw new keyexception("keys value too big,please call getcurrentkeylong method!");
  }
  return (new long(value)).intvalue();
}

/**
  * 用指定的表和字段获得key的当前值,最大为9223372036854775807
  * @param tablename   数据库中的表名,表中必须有一个数字主键
  * @param keyname   表(tablename)中的字段名
  * @param conn    jdbc连接,如果欲获得的key是第一次取值,则必须保证conn能连接到数据库
  * @return key的当前long值
  * @throws <code>keyexception</code>  如果表名或字段名不存在或访问数据库错误时抛出
  */
public long getcurrentkeylong(string tablename, string keyname, connection conn)
  throws keyexception {
  keyinfo keyinfo;
  string item = tablename + "." + keyname;
  try {
   synchronized (keylist) {
    if (keylist.containskey(item)) {
     keyinfo = (keyinfo) keylist.get(item);
    }
    else {
     keyinfo = new keyinfo(tablename, keyname, conn);
     keylist.put(item, keyinfo);
    }
   }
   return keyinfo.getcurrentkey();
  }
  catch (sqlexception sqle) {
   throw new keyexception(sqle);
  }
}

/**
  * 用指定的"表<code>.</code>字段"形式的字符串获得key的当前值,主键的值不得超过2147483647
  * @param tabledotfield  "表.字段"形式的字符串,如:message.id
  * @param conn    jdbc连接,如果欲获得的key是第一次取值,则必须保证conn能连接到数据库
  * @return key的当前int值
  * @throws <code>keyexception</code>  如果表名或字段名不存在、访问数据库错误或key的值
  * 大于2147483647时抛出
  */
public int getcurrentkey(string tabledotfield, connection conn) throws keyexception {
  long value = getcurrentkeylong(tabledotfield, conn);
  if (value > 2147483647l) {
   throw new keyexception("keys value too big,please call getnextkeylong method!");
  }
  return (new long(value)).intvalue();
}

/**
  * 用指定的"表<code>.</code>字段"形式的字符串获得key的当前值,最大为9223372036854775807
  * @param tabledotfield  "表.字段"形式的字符串,如:message.id
  * @param conn    jdbc连接,如果欲获得的key是第一次取值,则必须保证conn能连接到数据库
  * @return key的当前int值
  * @throws <code>keyexception</code>  如果表名或字段名不存在或访问数据库错误时抛出
  */
public long getcurrentkeylong(string tabledotfield, connection conn) throws keyexception {
  int dot_index = tabledotfield.indexof(".");
  if (tabledotfield.indexof(".") < 1) {
   throw new keyexception("unknown key " + tabledotfield + "!");
  }
  string tab = tabledotfield.substring(0, dot_index);
  string key = tabledotfield.substring(dot_index);
  return getcurrentkeylong(tab, key, conn);
}
}

/**
* 内部类,用来存储主键信息
* */
class keyinfo {
private long max = 9223372036854775807l;
private long min = 1l;
private long nextkey;
private string tablename;
private string keyname;
private connection conn = null;
/**
  * keyinfo 对象初始化
  */
keyinfo(string tablename, string keyname, connection _conn) throws sqlexception {
  this.tablename = tablename;
  this.keyname = keyname;
  this.conn = _conn;
  retrievefromdb();
}
int getmax() {
  return (new long(max)).intvalue();
}
long getmaxlong() {
  return max;
}
int getmin() {
  return (new long(min)).intvalue();
}
long getminlong() {
  return min;
}
/**
  * 取下一键值
  */
int getnextkey() {
  return (new long(getnextkeylong())).intvalue();
}
/**
  * 取下一键值
  */
synchronized long getnextkeylong() {
  nextkey++;
  return nextkey;
}
/**
  * 取当前键值
  */
synchronized int getcurrentkey() {
  return (new long(nextkey)).intvalue();
}
/**
  * 取当前键值
  */
synchronized long getcurrentkeylong() {
  return nextkey;
}
/**
  * 从数据库中取当前最大值
  */
void retrievefromdb() throws sqlexception {
  preparedstatement pstmt = null;
  resultset rs = null;
  int keyfromdb = 0;
  string sql = "select max(" + keyname + ") from " + tablename;
  try {
   pstmt = conn.preparestatement(sql);
  }
  catch (exception ex) {
   throw new keyexception("cant connect database!");
  }
  try {
   rs = pstmt.executequery();
  }
  catch (sqlexception sqle) {
   if (pstmt != null)
    pstmt.close();
   throw new keyexception(
    "" + keyname + " or " + tablename + " isnt exist in database!",
    sqle);
  }
  try {
   if (rs.next()) {
    nextkey = rs.getlong(1);
    if (nextkey < min) {
     nextkey = min;
    }
   }
   else {
    nextkey = min;
   }
  }
  catch (sqlexception sqle) {
   throw (sqle);
  }
  finally {
   if (rs != null)
    rs.close();
   if (pstmt != null)
    pstmt.close();
  }
}
}

赞(0)
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com 特别注意:本站所有转载文章言论不代表本站观点! 本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。未经允许不得转载:IDC资讯中心 » 一个用java实现的数据库序列生成器-JSP教程,资料/其它
分享到: 更多 (0)