这个功能需求是这样的,编码是由5个条件限定而成,前四个是从列表中随意选择,后一个是根据类型按照序列递增,整个编码是由这5个条件组合而成,如下图所示:
此外还需满足:1)生成的最终编码是唯一的;2)可以批量生成。
我们先看单项生成的例子。
一、单项生成
背景:数据库里有导入历史数据,生成规则是按照选择的字符+流水号组合而成,且生成的编码唯一;流水号自增,从01开始。
思路:从数据库里select出5级条件限定的流水号的最大值,递增1;组合5个条件即可;解决了生成唯一性的问题,不需要检查重复值。
生成代码:
public ArrayList<SkuCode> singen(String l1,String l2,String l3,String l4,String l5) throws SQLException, ParseException {//参数为前台传入的5个选项值
Connection conn = null;
PreparedStatement ps = null;
SkuCode sc=null;
ArrayList<SkuCode> SCList = new ArrayList<SkuCode>();//对象列表
Calendar cal = Calendar.getInstance();
java.text.SimpleDateFormat format = new java.text.SimpleDateFormat("yyyy-MM-dd");
String today=format.format(Calendar.getInstance().getTime());//生成时间
if(l5!=null&&l5.equals("H+流水号")) {//流水号类型
String sql1 = "select max(l5) from SKU where l5 like \"%H%\" and type=2 and l1 like ? and l2 like ? and l3 like ? and l4 like ?";//5个选项值确定的那一类编码的流水号最大值的sql语句
conn=DBUtil.getConnection();
ps=conn.prepareStatement(sql1);
ps.setString(1, l1);
ps.setString(2, l2);
ps.setString(3, l3);
ps.setString(4, l4);
ResultSet rs=ps.executeQuery();//结果集
while(rs.next()) {
String max=rs.getString(1);
if(max != null) {//流水号最大值不为空就递增
int temp=Integer.valueOf(max.substring(1)).intValue();
temp++;
if(temp>0&&temp<10) {//流水号格式
l5="H"+"0"+String.valueOf(temp);
}else if(temp>9) {//流水号格式
l5="H"+String.valueOf(temp);
}
}else {
int temp=1;//流水号最大值为空就从1开始
l5="H"+"0"+String.valueOf(temp);
}
sc=new SkuCode();//对象赋值
sc.setL1(l1);
sc.setL2(l2);
sc.setL3(l3);
sc.setL4(l4);
sc.setL5(l5);
sc.setSku(l1+"-"+l2+"-"+l3+"-"+l4+"-"+l5);//生成编码格式
sc.setCreatetime(today);
SCList.add(sc);//添加到对象列表
}
}
else if(l5!=null&&l5.equals("S+流水号")) {//同上理
String sql2 = "select max(l5) from SKU where l5 like \"%s%\" and type=2 and l1 like ? and l2 like ? and l3 like ? and l4 like ?";
conn=DBUtil.getConnection();
ps=conn.prepareStatement(sql2);
ps.setString(1, l1);
ps.setString(2, l2);
ps.setString(3, l3);
ps.setString(4, l4);
ResultSet rs=ps.executeQuery();
while(rs.next()) {
String max=rs.getString(1);
if(max != null) {
int temp=Integer.valueOf(max.substring(1)).intValue();
temp++;
if(temp>0&&temp<10) {
l5="S"+"0"+String.valueOf(temp);
}else if(temp>9) {
l5="S"+String.valueOf(temp);
}
}else {
int temp=1;
l5="S"+"0"+String.valueOf(temp);
}
sc=new SkuCode();
sc.setL1(l1);
sc.setL2(l2);
sc.setL3(l3);
sc.setL4(l4);
sc.setL5(l5);
sc.setSku(l1+"-"+l2+"-"+l3+"-"+l4+"-"+l5);
sc.setCreatetime(today);
SCList.add(sc);
}
}
return SCList;//返回对象列表
}
写入数据库代码:
//添加方法(写入数据库)
public void add(SkuCode sc) throws SQLException {
Connection conn = null;
PreparedStatement ps = null;
String sql = "insert into SKU(l1,l2,l3,l4,l5,sku,createtime,type)values(?,?,?,?,?,?,?,2)";//插入语句
try{
conn = DBUtil.getConnection();
ps = conn.prepareStatement(sql);
ps.setString(1, sc.getL1());
ps.setString(2, sc.getL2());
ps.setString(3, sc.getL3());
ps.setString(4, sc.getL4());
ps.setString(5, sc.getL5());
ps.setString(6, sc.getSku());
ps.setString(7, sc.getCreatetime());
ps.executeUpdate();
}catch(SQLException e){
e.printStackTrace();
throw new SQLException("添加数据失败");
}
}
二、多项生成
多项生成的基本代码与单项生成基本相同,不过在生成时多了一项循环,前端传来参数生成多少条,这边就循环几次
生成代码(部分):
public ArrayList<SkuCode> gen(String l1,String l2,String l3,String l4,String l5,String num) throws SQLException,ParseException {
Connection conn = null;
PreparedStatement ps = null;
SkuCode sc=null;
ArrayList<SkuCode> SCList = new ArrayList<SkuCode>();
Calendar cal = Calendar.getInstance();
java.text.SimpleDateFormat format = new java.text.SimpleDateFormat("yyyy-MM-dd");
String today=format.format(Calendar.getInstance().getTime());
int k = Integer.valueOf(num).intValue();//这个是前端传入的生成条数
if(l5!=null&&l5.equals("H+流水号")) {
String sql1 = "select max(l5) from SKU where l5 like \"%H%\" and type=2 and l1 like ? and l2 like ? and l3 like ? and l4 like ?";
conn=DBUtil.getConnection();
ps=conn.prepareStatement(sql1);
ps.setString(1, l1);
ps.setString(2, l2);
ps.setString(3, l3);
ps.setString(4, l4);
ResultSet rs=ps.executeQuery();
while(rs.next()) {
String max=rs.getString(1);
if(max==null) {
int temp=0;
for(int i=0;i<k;i++){//注意这块循环,是多项生成和单项生成的区别所在
temp++;
if(temp>0&&temp<10) {
l5="H"+"0"+String.valueOf(temp);
}else {
l5="H"+String.valueOf(temp);
}
sc=new SkuCode();
sc.setL1(l1);
sc.setL2(l2);
sc.setL3(l3);
sc.setL4(l4);
sc.setL5(l5);
sc.setSku(l1+"-"+l2+"-"+l3+"-"+l4+"-"+l5);
sc.setCreatetime(today);
SCList.add(sc);
}
}else {
int temp=Integer.valueOf(max.substring(1)).intValue();
for(int i=0;i<k;i++){
temp++;
if(temp>0&&temp<10) {
l5="H"+"0"+String.valueOf(temp);
}else {
l5="H"+String.valueOf(temp);
}
sc=new SkuCode();
sc.setL1(l1);
sc.setL2(l2);
sc.setL3(l3);
sc.setL4(l4);
sc.setL5(l5);
sc.setSku(l1+"-"+l2+"-"+l3+"-"+l4+"-"+l5);
sc.setCreatetime(today);
SCList.add(sc);
}
}
}
}
三、检测重复值
背景:这块是遗留问题,数据库里的历史数据导致有部分编码的流水号是从中途开始的,例如从80开始;那么按照上述规则取最大值肯定是从81开始递增;实际需要从01开始。
思路:流水号直接从01开始递增,将整个编码跟数据库比对,如果数据库里存在,则跳过这个流水号往下递增,如果不存在则输出结束循环。
缺点:数据量大的话性能会崩溃
生成代码(部分):
//多项生成方法
public ArrayList<SkuCode> gen(String l1,String l2,String l3,String l4,String l5,String num) throws SQLException,ParseException {
Connection conn = null;
PreparedStatement ps = null;
SkuCode sc=null;
ArrayList<SkuCode> SCList = new ArrayList<SkuCode>();
Calendar cal = Calendar.getInstance();
java.text.SimpleDateFormat format = new java.text.SimpleDateFormat("yyyy-MM-dd");
String today=format.format(Calendar.getInstance().getTime());
int k = Integer.valueOf(num).intValue();
if(l5!=null&&l5.equals("H+流水号")) {
int temp=0;//从0开始
int count=0;
for(int i=0;i<k;i++){//生成条数的循环
do {//因为从0开始肯定要先执行一次,所以采用do-while循环
temp++;
if(temp>0&&temp<10) {//流水号格式
l5="H"+"0"+String.valueOf(temp);
}else{
l5="H"+String.valueOf(temp);
}
sc=new SkuCode();
sc.setL1(l1);
sc.setL2(l2);
sc.setL3(l3);
sc.setL4(l4);
sc.setL5(l5);
sc.setSku(l1+"-"+l2+"-"+l3+"-"+l4+"-"+l5);
String sku=sc.getSku();
String sql1 = "select count(sku) from SKU where sku like ? and type=2";//数据库比对是否存在该项生成的编码
conn=DBUtil.getConnection();
ps=conn.prepareStatement(sql1);
ps.setString(1, sku);
ResultSet rs=ps.executeQuery();
while(rs.next()) {
count=rs.getInt(1);
}
}while(count!=0);//不存在则结束循环;存在的话返回流水号继续递增再比对
sc.setCreatetime(today);
SCList.add(sc);//添加对象列表
}
}
四、前端传入部分代码
<%
request.setCharacterEncoding("utf-8");
String l1=request.getParameter("l1");
String l2=request.getParameter("l2");
String l3=request.getParameter("l3");
String l4=request.getParameter("l4");
String l5=request.getParameter("l5");
SkuCodeDaoImpl skuCode = new SkuCodeDaoImpl();
ArrayList<SkuCode> scList = skuCode.singen(l1,l2,l3,l4,l5);//传参
for (SkuCode s : scList){
%>
<tr align=center>
<td><%=s.getSku()%></td>
<%
SkuCode sc=new SkuCode();//赋值
sc.setL1(s.getL1());
sc.setL2(s.getL2());
sc.setL3(s.getL3());
sc.setL4(s.getL4());
sc.setL5(s.getL5());
sc.setSku(s.getSku());
sc.setCreatetime(s.getCreatetime());
skuCode.add(sc);//写入数据库
%>
<%}%>
以上就是全部实现方式,新手编码不成熟,以作总结。