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