晨魅--自动生成流水号的代码片段

本文介绍了一种解决部门维护操作中从中间删除数据后,再添加数据时出现主键重复异常的方法。通过自定义编码和流水号生成策略,确保了主键和流水号的唯一性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这篇是对《晨魅--简单的部门维护操作》的补充,这里解决了之前从中间删除数据,在添加数据时会有“插入重复主键异常”抛出的问题。(这里的主键和流水号都不是自增的)

先写一个最基本的dao方法和service方法,并对其封装,封装的代码如下:

dao层, 这里是根据ID查找数据库里一共有多少条数据。。。  

    /**
     * @Description 根据ID查找流水号
     */
    public long getLsh(String tablename) throws DaoException{
        StringBuffer sql = new StringBuffer();
        sql.append(" SELECT COUNT(*) ");        
        sql.append(" FROM ");
        sql.append(tablename);        
        List<Object> param = new ArrayList<>();    
        long serval=this.queryForLong(sql.toString(),param);
        return serval;        
        
    }

service层

      /**
       * @Description 获取最大流水号
       */
	public String setLsh(String tablename,String head,Integer bit) throws DaoException{		
		long lsh = baseDao.getLsh(tablename);
		return setSerialNum(head,(int) (lsh+1),bit);	
	
	}

然后在写一个dao,是查询数据库里最大的流水号,用来跟上面的dao查询数据条数做比较

      /**
       * 查询最大的流水号
       */
       public Long getNumContract(Clause clause) throws DaoException {
		
		 StringBuffer sql = new StringBuffer();
		 sql.append(" SELECT max(d_num) ");		
		 sql.append(" FROM ");
		 sql.append(" dept ");
		 if(clause.getWhereClause()!=null){
			 sql.append(" WHERE "+clause.getWhereClause());
		 }		
       return  this.queryForLong(sql.toString(),clause.getParams());
	}

因为要求主键和流水号“自增”,不是手动填写的,所以要在填写主键和流水号之前就算出主键和流水号的值,就要在添加数据时调以上封装好的方法。同时抛出重复主键异常的问题也是在添加数据时出现的,所以也要在添加数据时处理。以下是解决流水号问题的代码片段:

       public Boolean insert_member(DeptBean bMember,Page page) throws DaoException{
		boolean flag = false;
		try {			
			// 部门编号和流水号(执行新增操作的方法)			
			String a = "BM";	//流水号的要求格式是“BM0001”  	
			String code = this.setLsh("dept", "1", 3);//调上面封装的service方法
			//"dept"是数据库的表名,“0”是起始数字是0,同上面的1,3是在起始数后面截取3位 
			String d_number = this.setLsh("dept", "0", 3);
			int d_num=Integer.parseInt(code);//这里要把流水号转成int型
			bMember.setD_number(a+d_number);
			bMember.setD_num(d_num);
			
			Long max = this.memberDao.getNumContract(clause);//调查询最大的流水号的方法		
			int ber,num;
			String b = null;
			 /*如果是在中间删除,最大值是不会变的,但是数据条数会变。因为是添加操作,所以上面在添加时
			  *做了加1操作,正常情况下流水号要大于数据库中查到的最大值,但是要是从中间删除数据,数据条数
			  *会变少,即使做加1操作也会小于或等于最大值,这样就会出现重复主键的问题了。
			  *在这里判断一下,如果从中间删除数据,就让它在最大值上加1,如果没有就不走这个判断里的方法
			  */
			if(max>=d_num){				
				ber=(int) ((max+1)-1000);
				NumberFormat nf = new DecimalFormat("0000");//转换格式的
				b = nf.format(ber);
				num=(int) (max+1);
				bMember.setD_number(a+b);			
				bMember.setD_num(num);
			}														
			if(this.memberDao.insertDept(bMember, clause)>0){
				flag = true;
			}
		} catch (Exception e) {
			e.printStackTrace();			
		}	
		return flag;
	}
	//在新增部门跳转时,掉这个方法,计算出部门编号和流水号
	public void save_obj(DeptBean bMember) throws DaoException{		
		// 部门编号和流水号		
		try {			
			// 部门编号和流水号(执行新增操作的方法)			
			String a = "BM";		
			String code = this.setLsh("dept", "1", 3);
			String d_number = this.setLsh("dept", "0", 3);
			int d_num=Integer.parseInt(code);
			bMember.setD_number(a+d_number);
			bMember.setD_num(d_num);
			//查询最大流水号
			Long max = this.memberDao.getNumContract(clause);	
			int ber,num;
			String b = null;
			if(max>=d_num){				
				ber=(int) ((max+1)-1000);
				NumberFormat nf = new DecimalFormat("0000");
				b = nf.format(ber);
				num=(int) (max+1);
				bMember.setD_number(a+b);			
				bMember.setD_num(num);
			}																	
		} catch (Exception e) {
			e.printStackTrace();			
		}			
	}

—————————————————————————————————————————————————————————————————————————————

编码自增方法(和流水号有些类似)

public ViewRenderer doSaveAction(DataParam param){
		String operateType = param.get(OperaType.KEY);
		if (OperaType.CREATE.equals(operateType)){
			String code = param.getString("CI_AREACODE");
			
			if(code.length()>3){
				code = code.substring(1);	
			}else if(code.length()==2){
				code = "0"+code;
			}else if(code.length()==1){
				code = "00"+code;
			}
			String maxNum = getService().getMaxCodeRecord(code);
			String num = code+maxNum;
			param.put("CI_NUMBER",num);
			getService().createRecord(param);	
		}
		else if (OperaType.UPDATE.equals(operateType)){
			getService().updateRecord(param);	
		}
		return new RedirectRenderer(getHandlerURL(listHandlerClass));
	}


public String getMaxCodeRecord(String areaCode) {
		String statementId = sqlNameSpace+"."+"getMaxCodeRecord";
		DataParam param = new DataParam();
		param.put("CI_AREACODE",areaCode);
		DataRow result = this.daoHelper.getRecord(statementId, param);
		String maxNum = "";
		if(result.size()>0){
			maxNum = result.getString("CI_MAX_NUMBER");
			int max = (Integer.parseInt(maxNum))+1;
			NumberFormat nf = new DecimalFormat("0000");转换格式,定义格式类型"0000"
			maxNum=nf.format(max).toString();用string类型接,把变量max的格式转为定义的格式,变成String类型
            
		}else{
			maxNum = "0001";
		}
		return maxNum;
	}

right(CI_NUMBER,4)查该字段从右数第4位,left(CI_NUMBER,3)从左数第3位
<select id="getMaxCodeRecord" parameterClass="com.agileai.domain.DataParam" resultClass="com.agileai.domain.DataRow">
select max(right(CI_NUMBER,4)) AS CI_MAX_NUMBER FROM clinic_infos
where left(CI_NUMBER,3) = #CI_AREACODE#
  </select>




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值