一个数据库序号类NoCtr类的实现

一个NoCtrl类的实现

import java.sql.*;
import com.liming.db.*;
import com.liming.util.*;
import java.text.*;

/**
 * <p>Title: 编号控制档</p>
 * <p>Description: </p>
 * <p>Copyright:  Copyright (c) 2005</p>
 * <p>Company: Liming Network System</p>
 * @author Yao Kui
 * @version 1.0
 */

public class NoCtrl {
  /**
   * 调试模式
   * 0=非调试模式;1=调试模式
   */
  public static int DebugMode = 0;

  public static String CURR_DATE = "CURR_DATE";//编码规则,当前日期eg:20050501
  public NoCtrl() {
  }
  /**
   * @deprecated
   * @see currNO
   * @param tableCode
   * @param columnCode
   * @return
   */
  public static String currNo(String tableCode,String columnCode){
    Connection con = null;
    Statement stmt = null;
    DBManager dbMgr = new DBManager();

    try{
      String sqlStr =
          "SELECT * FROM NO_CTRL";
      String where = " WHERE TABLE_CODE='"+tableCode+"'";
      if(columnCode != null) where += " AND COLUMN_CODE='"+columnCode+"'";
      sqlStr += where;
        AppTools.printStack(sqlStr);

        if (DebugMode==0) {
            con = dbMgr.getConnect(JndiName.JNDIORACLE);
        }
        else {
            con = dbMgr.getConnDirect();
        }
        stmt = con.createStatement();

        ResultSet rst = stmt.executeQuery(sqlStr);
        if(rst.next()){
          String prefix = coverFixString(rst.getString("PREFIX"));
          String postfix = coverFixString(rst.getString("POSTFIX"));
          int currNo = rst.getInt("CURR_NO");
          int numLen = rst.getInt("NUM_LEN");
          stmt.executeUpdate("UPDATE NO_CTRL SET CURR_NO=CURR_NO+1"+where);
          return prefix+lpad(Integer.toString(currNo),"0",numLen)+postfix;
        }else{
          return null;
        }
    }
    catch(SQLException se) {
        AppTools.printStack("操作编号控制档失败!");
        AppTools.printStack(se);
        return null;
    }
    catch(Exception e) {
        AppTools.printStack("操作编号控制档失败!");
        AppTools.printStack(e);
        return null;
    }
    finally
    {
        dbMgr.release(con,stmt);
    }
  }
  private static String coverFixString(String fix){
    if(fix == null) return "";
    java.text.SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");
    long date = System.currentTimeMillis();
    String datestr = df.format(new Date(date));


    /*if(CURR_DATE.equals(fix)){
      java.text.SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");
      long date = System.currentTimeMillis();
      return df.format(new Date(date));
    }*/
    return fix.replaceAll(CURR_DATE,datestr);
  }
  //将字符串左补串到一定长度
  private static String lpad(String src,String pad,int len){
    if(src.length() >= len) return src;
    int padLen = len - src.length();
    int padTimes = padLen/pad.length() + 1;
    StringBuffer sb = new StringBuffer();
    for(int i=0;i<padTimes;i++){
     sb.append(pad);
    }
    return sb.toString().substring(0,padLen)+src;
  }
  public static void main(String[] args){
    System.out.println(NoCtrl.lpad("15","0",5));

    System.out.println(NoCtrl.lpad("aaas15","0",5));
    System.out.println(NoCtrl.lpad("15","ab",5));
    System.out.println(NoCtrl.coverFixString(null));

    System.out.println(NoCtrl.coverFixString("asdff"));
    System.out.println(NoCtrl.currNo("IN_BOX","IN_NO"));
  }

  /*上面的currNo方法对于业务逻辑后面报错的情况,会出现跳号的情况。对于要保证不跳号的业务则不可以。
     下面是将取号与更新分开,延迟更新来保证不跳号的情况。首先业务取得的号(在出现新增页面则就要显示编号的情况)
   只是表示“大致”的编号,在更新时一个事务中重新取号与更新编号。
   */
  public static String[] currNO(String tableCode,String columnCode){
    return currNO(tableCode,columnCode,false);
  }

  /**
   *更新序号,在业务新增数据中一起执行,为了保证多用户时也正确,不会重复。取得号后更新时加上原号
   * 作为条件,正如多用户更新加上版本(version)字段一样。
   * @param tableCode
   * @param columnCode
   * @param currNum
   * @return
   */
  public static String updateNOSql(String tableCode,String columnCode,String currNum){
    return updateNOSql(tableCode,columnCode,currNum,1);
  }

  /*对于上面的取与更新在一个事务中进行。只取一个号,取时不用加锁。
   对于如果后台要进行插入(多条),取回多个号,最好是连续时。如
   for(){
    insert(no,..);
   }
   由于在一个事务中,所以NO_CTRL没有更新,对自己或其它用户,取下一个号都不对。
   所以最好使用加锁(for update)读出第一个号,最后的更新语句传导入使用的个数。
   var no = 加锁读出第一个号。
   for(i=0;i<xxx;i++){
   insert(no+i,...);
   }
   update(curr_no=curr_no+xxx)。
   */
  public static String[] currNO(String tableCode,String columnCode,boolean lock){
   Connection con = null;
   Statement stmt = null;
   DBManager dbMgr = new DBManager();
   String[] rt = new String[2];
   try{
     String sqlStr =
         "SELECT * FROM NO_CTRL";
     String where = " WHERE TABLE_CODE='"+tableCode+"'";
     if(columnCode != null) where += " AND COLUMN_CODE='"+columnCode+"'";
     sqlStr += where;
     if(lock) sqlStr += " FOR UPDATE"; //**LOCK
       AppTools.printStack(sqlStr);

       if (DebugMode==0) {
           con = dbMgr.getConnect(JndiName.JNDIORACLE);
       }
       else {
           con = dbMgr.getConnDirect();
       }
       stmt = con.createStatement();

       ResultSet rst = stmt.executeQuery(sqlStr);
       if(rst.next()){
         String prefix = coverFixString(rst.getString("PREFIX"));
         String postfix = coverFixString(rst.getString("POSTFIX"));
         int currNo = rst.getInt("CURR_NO");
         int numLen = rst.getInt("NUM_LEN");
         //stmt.executeUpdate("UPDATE NO_CTRL SET CURR_NO=CURR_NO+1"+where);//延迟更新
         rt[0] = prefix+lpad(Integer.toString(currNo),"0",numLen)+postfix;
         rt[1] = Integer.toString(currNo);
       }
       return rt;
   }
   catch(SQLException se) {
       AppTools.printStack("操作编号控制档失败!");
       AppTools.printStack(se);
       return null;
   }
   catch(Exception e) {
       AppTools.printStack("操作编号控制档失败!");
       AppTools.printStack(e);
       return null;
   }
   finally
   {
       dbMgr.release(con,stmt);
   }
  }
  /**
   * 返回更新NO_CTRL的语句
   * @param tableCode
   * @param columnCode
   * @param currNum 当前号,即取回时的号码(序号)
   * @param usedNum 此次事务中使用的个数
   * @return
   */
  public static String updateNOSql(String tableCode,String columnCode,String currNum,int usedNum){
    if(usedNum <0) usedNum = 0;
    String where = " WHERE TABLE_CODE='"+tableCode+"'";
    if(columnCode != null) where += " AND COLUMN_CODE='"+columnCode+"'";
    return "UPDATE NO_CTRL SET CURR_NO=CURR_NO+"+usedNum+where+" AND CURR_NO="+currNum;
  }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值