java(优化二) 编号规则生成器(二)

一 需求:

编写一个接口,有两个方法:

一个返回当前年月+0001到9999的数值,如:2015040001,2015040002....;另一个方法返回年月日+0001到9999的数值,如:201504220001,201504220002....


二 操作步骤:

2.1 建表

DROP TABLE IF EXISTS `pl_num`;
CREATE TABLE `pl_num` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `cur_year` int(4) NOT NULL COMMENT '当前年份',
  `cur_month` int(2) NOT NULL COMMENT '当前月份',
  `cur_day` int(2) DEFAULT NULL COMMENT '当前日',
  `cur_ymd_num` int(4) DEFAULT NULL COMMENT '年月日自增的数值(0001-9999)',
  `cur_ym_num` int(4) DEFAULT NULL COMMENT '年月自增的数值(0001-9999)',
  `save_type` varchar(32) NOT NULL COMMENT '保存类型',
  `create_time` datetime NOT NULL COMMENT '创建时间(格式:yyyy-MM-dd HH:mm:ss)',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=109 DEFAULT CHARSET=utf8 COMMENT='编号生成器表';

2.2 ibatis配置

文件名:Num.xml   sqlmap配置:<sqlMap resource="ibatis/Num.xml"/>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd">

<sqlMap namespace="NumGenerater">
	<typeAlias type="com.yht.archives.commons.entity.Num" alias="Num"/>
	
	<!--select,update,insert,delete. id名用于访问该资源,resultClass表示输出类型,parameterClass表示输入参数-->
	<!-- 增加一条记录 -->
	<insert id="addNum" parameterClass="Num">
		INSERT INTO PL_NUM
		<dynamic prepend="(" >
			<isNotNull prepend="," property="id" > ID </isNotNull>
			<isNotNull prepend="," property="cur_year" > CUR_YEAR </isNotNull>
			<isNotNull prepend="," property="cur_month" > CUR_MONTH </isNotNull>
			<isNotNull prepend="," property="cur_day" > CUR_DAY </isNotNull>
			<isNotNull prepend="," property="cur_ymd_num" > CUR_YMD_NUM </isNotNull>
			<isNotNull prepend="," property="cur_ym_num" > CUR_YM_NUM </isNotNull>
			<isNotNull prepend="," property="save_type" > SAVE_TYPE </isNotNull>
			<isNotNull prepend="," property="create_time" > CREATE_TIME </isNotNull>
		      )
		</dynamic>
		VALUES 
		<dynamic prepend="(" >
		    <isNotNull prepend="," property="id" > #id# </isNotNull>
		    <isNotNull prepend="," property="cur_year" > #cur_year# </isNotNull>
		    <isNotNull prepend="," property="cur_month" > #cur_month# </isNotNull>
		    <isNotNull prepend="," property="cur_day" > #cur_day# </isNotNull>
		    <isNotNull prepend="," property="cur_ymd_num" > #cur_ymd_num# </isNotNull>
		    <isNotNull prepend="," property="cur_ym_num" > #cur_ym_num# </isNotNull>
		    <isNotNull prepend="," property="save_type" > #save_type# </isNotNull>
		    <isNotNull prepend="," property="create_time" > #create_time# </isNotNull>
		)
		</dynamic>
	</insert>

	<!-- 更新一条记录 -->
	<update id="updateNum" parameterClass="Num">
	  	<![CDATA[
			UPDATE PL_NUM
	  	]]>
		<dynamic prepend="SET">
		      <isNotNull prepend="," property="id"> ID = #id# </isNotNull>
		      <isNotNull prepend="," property="cur_year"> CUR_YEAR = #cur_year# </isNotNull>
		      <isNotNull prepend="," property="cur_month"> CUR_MONTH = #cur_month# </isNotNull>
		      <isNotNull prepend="," property="cur_day"> CUR_DAY = #cur_day# </isNotNull>
		      <isNotNull prepend="," property="cur_ymd_num"> CUR_YMD_NUM = #cur_ymd_num# </isNotNull>
		      <isNotNull prepend="," property="cur_ym_num"> CUR_YM_NUM = #cur_ym_num# </isNotNull>
		      <isNotNull prepend="," property="create_time"> CREATE_TIME = #create_time# </isNotNull>
		</dynamic>
		<dynamic prepend="WHERE">
		      <isNotNull prepend="AND" property="id"> ID = #id# </isNotNull>
		      <isNotNull prepend="AND" property="cur_year"> CUR_YEAR = #cur_year# </isNotNull>
		      <isNotNull prepend="AND" property="cur_month"> CUR_MONTH = #cur_month# </isNotNull>
		      <isNotNull prepend="AND" property="cur_day"> CUR_DAY = #cur_day# </isNotNull>
		      <isNotNull prepend="AND" property="save_type"> SAVE_TYPE = #save_type# </isNotNull>
		</dynamic>
	</update>
	
	<!-- 查询字段的sql -->
	<sql id="select_sql">
		<![CDATA[
	      SELECT	
		      ID AS id,
		      CUR_YEAR AS cur_year,
		      CUR_MONTH AS cur_month,
		      CUR_DAY AS cur_day,
		      CUR_YMD_NUM AS cur_ymd_num,
		      CUR_YM_NUM AS cur_ym_num,
		      SAVE_TYPE AS save_type,
			  CREATE_TIME AS create_time
		  FROM	
		     PL_NUM  
	    ]]>	
	</sql>
	
	<!-- 查询过滤条件的sql -->
	<sql id="where_sql">
		<dynamic prepend="WHERE">
			<isNotNull prepend="AND" property="id"> ID = #id# </isNotNull>
			<isNotNull prepend="AND" property="cur_year"> CUR_YEAR = #cur_year# </isNotNull>
			<isNotNull prepend="AND" property="cur_month"> CUR_MONTH = #cur_month# </isNotNull>
			<isNotNull prepend="AND" property="cur_day"> CUR_DAY = #cur_day# </isNotNull>
			<isNotNull prepend="AND" property="cur_ymd_num"> CUR_YMD_NUM = #cur_ymd_num# </isNotNull>
			<isNotNull prepend="AND" property="cur_ym_num"> CUR_YM_NUM = #cur_ym_num# </isNotNull>
			<isNotNull prepend="AND" property="save_type"> SAVE_TYPE = #save_type# </isNotNull>
			<isNotNull prepend="AND" property="create_time"> CREATE_TIME = #create_time# </isNotNull>
		</dynamic>	
	</sql>
	
	<!-- 列出记录数 -->
	<select id="findNumCount" parameterClass="Num" resultClass="integer">
		<![CDATA[
	      SELECT	
			    COUNT(ID)
		    FROM	
		        PL_NUM    
	     ]]>
		<include refid="where_sql"/>
	</select>
	
  	<!-- 列出一组记录 -->
	<select id="findNum" parameterClass="Num" resultClass="Num">
		<include refid="select_sql"/>
		<include refid="where_sql"/>
		<![CDATA[
	      ORDER BY CREATE_TIME DESC 
		  LIMIT 0,1  
	     ]]>
	</select>
</sqlMap>

2.3 dao层接口

public interface NumGeneraterDao {
	/**
	 * 新增一条数据
	 * @param num
	 * @return
	 * @throws RuntimeException
	 */
	public Object addNum(Num num) throws RuntimeException;

	/**
	 * 修改数据
	 * @param num
	 * @return
	 * @throws RuntimeException
	 */
	public void updateNum(Num num) throws RuntimeException;
	
	/**
	 * 查询已生成最大的编号
	 * @return
	 * @throws RuntimeException
	 */
	public Num findMaxNum(String save_type) throws RuntimeException;
	
}
封装ArchivesBaseDao:
public abstract class ArchivesBaseDao extends SqlMapClientDaoSupport{
	
	@Autowired
    public void setSqlMapClientForAutowire(SqlMapClient sqlMapClient) {
        super.setSqlMapClient(sqlMapClient);
    }
	
	protected Object insert(String id,Object param) {
		return getSqlMapClientTemplate().insert(id, param);
	}
	
	protected int update(String id,Object param) {
		return getSqlMapClientTemplate().update(id, param);
	}
	
	protected int delete(String id,Object param) {
		return getSqlMapClientTemplate().delete(id, param);
	}

	@SuppressWarnings("rawtypes")
	protected List queryForList(String id,Object param) {
		return getSqlMapClientTemplate().queryForList(id, param);
	}
	
	protected Object queryForObject(String id,Object param) {
		return getSqlMapClientTemplate().queryForObject(id, param);
	}
	
	protected Integer count(String id,Object param) {
		return (Integer) getSqlMapClientTemplate().queryForObject(id, param);
	}
	
}

2.4 dao层接口实现类

@Repository("numGeneraterDao")
public class NumGeneraterDaoImpl extends ArchivesBaseDao implements NumGeneraterDao {

	@Override
	public Object addNum(Num num) throws RuntimeException {
		return (Num) insert("NumGenerater.addNum", num);
	}

	@Override
	public void updateNum(Num num) throws RuntimeException {
		update("NumGenerater.updateNum", num);
	}

	@Override
	public Num findMaxNum(String save_type) throws RuntimeException {
		Num numQo = new Num();
		if(StringUtils.isNotBlank(save_type)){
			numQo.setSave_type(save_type);
		}
		return (Num) queryForObject("NumGenerater.findNum", numQo);
	}

}
2.5 service层接口
/**
 * 编号数字生成器
 * 规则:0001-9999 逐个加一,如0001,0002,0003....
 * @author zengdq 2014-12-20
 *
 */
public interface NumGeneraterServ {
	
	/**
	 * 返回年月+0001到9999的数值,如:2014120001,2014120002....
	 * @return
	 * @throws Exception
	 */
	public String getYMNum() throws Exception; 
	
	
	/**
	 * 返回年月日+0001到9999的数值,如:201412210001,201412210002....
	 * @return
	 * @throws Exception
	 */
	public String getYMDNum(String declare_type) throws Exception; 
	
}
2.6 service层接口实现类
@Service("numGeneraterServ")
@Transactional
public class NumGeneraterServImpl implements NumGeneraterServ {
	private Logger logger = Logger.getLogger(getClass());
	
	private final Integer DEFAULT_MIN_NUM = 0001; //默认最小编号,从0001开始
	
	private final Integer DEFAULT_MAX_NUM = 9999; //默认最大编号
	
	private final int DEFAULT_SHOW_NUM = 4; //整数显示最少位数
	
	@Autowired
	private NumGeneraterDao numGeneraterDao;

	@Override
	public synchronized String getYMNum() throws Exception {
		//先获取数据库存的最大值
		Num num = null;
		try {
			num = numGeneraterDao.findMaxNum(NumSaveType.YEAR_MONTH.name());
		} catch (Exception e) {
			logger.error("查询编号生成器SQL错误", e);
			throw new FinanceException("","获取编号失败", e);
		}
		//获取系统当前时间
		Integer add_num = DEFAULT_MIN_NUM;
		Calendar cal = Calendar.getInstance();
		int cur_year = cal.get(Calendar.YEAR); 
		int cur_month = cal.get(Calendar.MONTH)+1;//月份加1
		
		if(num != null){ //检查数据
			if((cur_year == num.getCur_year()) 
				&& (cur_month == num.getCur_month())){
				//当前数值+1先加1&保存并返回
				Integer cur_ym_num = num.getCur_ym_num();
				boolean flag = comparateTwoNum(cur_ym_num,DEFAULT_MIN_NUM);
				boolean flag2 = comparateTwoNum(DEFAULT_MAX_NUM,cur_ym_num);
				if(!flag || !flag2){
					throw new FinanceException("","获取编号失败,编号取值范围必须是:[0001-9999]");
				}
				//当前值加1
				add_num = cur_ym_num.intValue()+1;
			}
		}
		
		//新增数据&返回年月+4位编号
		StringBuffer sbf = saveAndReturnData(cur_year, cur_month,null,add_num,NumSaveType.YEAR_MONTH.name());
		
		return sbf.toString();
	}

	@Override
	public synchronized String getYMDNum(String declare_type) throws Exception {
		//先获取数据库存的最大值
		Num num = null;
		try {
			num = numGeneraterDao.findMaxNum(NumSaveType.YEAR_MONTH_DAY.name());
		} catch (Exception e) {
			logger.error("查询编号生成器SQL错误", e);
			throw new FinanceException("","获取编号失败", e);
		}
		//获取系统当前时间
		Integer add_num = DEFAULT_MIN_NUM;
		Calendar cal = Calendar.getInstance();
		int cur_year = cal.get(Calendar.YEAR); 
		int cur_month = cal.get(Calendar.MONTH)+1;//月份加1
		int cur_day = cal.get(Calendar.DATE);
		
		if(num != null){ //检查数据
			if((cur_year == num.getCur_year()) 
				&& (cur_month == num.getCur_month())
				&& (cur_day == num.getCur_day())){
				//当前数值+1先加1&保存并返回
				Integer cur_ym_num = num.getCur_ymd_num();
				boolean flag = comparateTwoNum(cur_ym_num,DEFAULT_MIN_NUM);
				boolean flag2 = comparateTwoNum(DEFAULT_MAX_NUM,cur_ym_num);
				if(!flag || !flag2){
					throw new FinanceException("","获取编号失败,编号取值范围必须是:[0001-9999]");
				}
				//当前值加1
				add_num = cur_ym_num.intValue()+1;
			}
		}
		
		//新增数据&返回年月+4位编号
		StringBuffer sbf = new StringBuffer();
		if(declare_type.equals(DeclareType.NEW_DECLARE.getValue())){
			sbf.append("RZXZ");
		}else if(declare_type.equals(DeclareType.CHANGE_DECLARE.getValue())){
			sbf.append("RZBG");
		}
		sbf.append(saveAndReturnData(cur_year, cur_month,cur_day,add_num,NumSaveType.YEAR_MONTH_DAY.name()));
		return sbf.toString();
	}
	
	/**
	 * 比较两个整数的大小
	 * true表现num1小于um2;false表示num1大于或等于num2
	 * @param cur_ym_num
	 * @param dEFAULT_MIN_NUM2
	 * @return
	 */
	private boolean comparateTwoNum(Integer num1, Integer num2) {
		boolean flag = false;
		BigDecimal big1 = new BigDecimal(num1);
		BigDecimal big2 = new BigDecimal(num2);
		//-1表示小于,0表示等于,1表示大于
		if(1 == big1.compareTo(big2)){
			flag = true;
		}else if(0 == big1.compareTo(big2)){
			flag = true;
		}/*else if(-1 == big1.compareTo(big2)){
			flag = false;
		}else{
			flag = false;
		}*/
		return flag;
	}

	/**
	 * 新增一条,年月+4位编号的数据
	 * @param cur_year
	 * @param cur_month
	 * @return
	 */
	private StringBuffer saveAndReturnData(Integer cur_year, Integer cur_month,Integer cur_day,Integer number,String save_type) {
		StringBuffer sb =new StringBuffer();
		
		Num addNum = new Num();
		addNum.setCur_year(cur_year);
		addNum.setCur_month(cur_month);
		addNum.setSave_type(save_type);
		addNum.setCreate_time(DateUtil.getCurrentTime());
		//
		sb.append(cur_year);
		
		sb.append(numFormat(cur_month,2));
		if(NumSaveType.YEAR_MONTH.name().equals(save_type)){
			addNum.setCur_ym_num(number);
		}else if(NumSaveType.YEAR_MONTH_DAY.name().equals(save_type)){
			addNum.setCur_day(cur_day);
			addNum.setCur_ymd_num(number);
			//
			sb.append(numFormat(cur_day,2));
		}else{
			throw new FinanceException("S","添加编号失败,编号保存类型是非法的");
		}
		sb.append(numFormat(number,DEFAULT_SHOW_NUM));
		
		try {
			numGeneraterDao.addNum(addNum);
		} catch (Exception e) {
			logger.error("新增编号数据SQL错误", e);
			throw new FinanceException("D","添加编号失败", e);
		}
		
		//返回该数据
		return sb;
	}

	/**
	 * 显示固定长度的N位数值
	 * @param number
	 * @return
	 */
	private Object numFormat(Integer num, int minDigit) {
		NumberFormat formatter = NumberFormat.getNumberInstance();
		formatter.setMinimumIntegerDigits(minDigit); //整数显示最少位数不足前面补零  
		formatter.setGroupingUsed(false); // true(带逗号),false
		//
		return formatter.format(num);
	}
}
三 测试:
main方法里:
NumGeneraterServ numGeneraterServ = (NumGeneraterServ)getBean("numGeneraterServ");
String value1 = numGeneraterServ.numGeneraterServ.getYMNum();
String value2 = numGeneraterServ.getYMDNum(DeclareType.NEW_DECLARE.name());









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值