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

一 需求:

编写一个接口,要求自动生成000001-999999的一个值。传入参数:user_id、project_code 返回结果:000001-999999中不重复的数值。

二 操作步骤:

  2.1 建表(数据库mysql)

DROP TABLE IF EXISTS `pj_contract_code`;
CREATE TABLE `pj_contract_code` (
  `ID` BIGINT(32) NOT NULL AUTO_INCREMENT COMMENT '自增ID',
  `USER_ID` varchar(32) NOT NULL COMMENT '用户ID',
  `PROJECT_CODE` varchar(32) NOT NULL COMMENT '项目编号',
  `SEQ_START` bigint(20) NOT NULL DEFAULT '000001'COMMENT '允许的最小值',
  `SEQ_END` bigint(20) NOT NULL DEFAULT '999999' COMMENT '允许的最大值',
  `CURRENT_VALUE` bigint(20) NOT NULL COMMENT '当前值',
  `LAST_UPDATE` datetime NOT NULL COMMENT '上一次修改时间',
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


ALTER TABLE pj_contract_code ADD INDEX USER_ID_INDEX (USER_ID) USING BTREE;
ALTER TABLE pj_contract_code ADD INDEX PROJECT_CODE_INDEX (PROJECT_CODE) USING BTREE;


2.2 ibatis配置

文件名:ProjContractCode.xml   sqlmap配置:<sqlMap resource="ibatis/ProjContractCode.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="ProjContractCode">
	<typeAlias type="com.yht.wxt.project.po.ProjContractCode" alias="ProjContractCode"/>
	<typeAlias type="com.yht.wxt.project.qo.ProjContractCodeQo" alias="ProjContractCodeQo"/>
	
	<!--select,update,insert,delete. id名用于访问该资源,resultClass表示输出类型,parameterClass表示输入参数-->
	<!-- 增加一条记录 -->
	<insert id="addProjContractCode" parameterClass="ProjContractCode">
		INSERT INTO PJ_CONTRACT_CODE
		<dynamic prepend="(" >
			<isNotNull prepend="," property="id" > ID </isNotNull>
			<isNotEmpty prepend="," property="user_id" > USER_ID </isNotEmpty>
			<isNotEmpty prepend="," property="project_code" > PROJECT_CODE </isNotEmpty>
			<isNotNull prepend="," property="seq_start" > SEQ_START </isNotNull>
			<isNotNull prepend="," property="seq_end" > SEQ_END </isNotNull>
			<isNotNull prepend="," property="current_value" > CURRENT_VALUE </isNotNull>
			<isNotNull prepend="," property="last_update" > LAST_UPDATE </isNotNull>
		      )
		</dynamic>
		VALUES 
		<dynamic prepend="(" >
		    <isNotNull prepend="," property="id" > #id# </isNotNull>
			<isNotEmpty prepend="," property="user_id" > #user_id# </isNotEmpty>
			<isNotEmpty prepend="," property="project_code" > #project_code# </isNotEmpty>
		    <isNotNull prepend="," property="seq_start" > #seq_start# </isNotNull>
		    <isNotNull prepend="," property="seq_end" > #seq_end# </isNotNull>
		    <isNotNull prepend="," property="current_value" > #current_value# </isNotNull>
		    <isNotNull prepend="," property="last_update" > #last_update# </isNotNull>
		)
		</dynamic>
	</insert>
<!-- 查询字段的sql -->
	<sql id="select_sql">
		<![CDATA[
	      SELECT	
			      ID AS id,
			      USER_ID AS user_id,
			      PROJECT_CODE AS project_code,
			      SEQ_START AS seq_start,
			      SEQ_END AS seq_end,
			      CURRENT_VALUE AS current_value,
				  LAST_UPDATE AS last_update
		    FROM	PJ_CONTRACT_CODE  
	    ]]>	
	</sql>
	
	<!-- 查询过滤条件的sql -->
	<sql id="where_sql">
		<dynamic prepend="WHERE">
			<isNotNull prepend="AND" property="id"> ID = #id# </isNotNull>
			<isNotEmpty prepend="AND" property="user_id"> USER_ID = #user_id# </isNotEmpty>
			<isNotEmpty prepend="AND" property="project_code"> PROJECT_CODE = #project_code# </isNotEmpty>
			<isNotNull prepend="AND" property="current_value"> CURRENT_VALUE = #current_value# </isNotNull>
		</dynamic>	
	</sql>
<!-- 列出记录数 -->
	<select id="findProjContractCodeCount" parameterClass="ProjContractCodeQo" resultClass="integer">
		<![CDATA[
	      SELECT	
			    	COUNT(*)
		    FROM	PJ_CONTRACT_CODE    
	     ]]>
		<include refid="where_sql"/>
	</select>
	
  	<!-- 列出一组记录 -->
	<select id="findProjContractCode" parameterClass="ProjContractCodeQo" resultClass="ProjContractCode">
		<include refid="select_sql"/>
		<include refid="where_sql"/>
	</select>
</sqlMap>


2.3 dao层接口

public interface ProjContractCodeDao {

	public Object addProjContractCode(ProjContractCode projContractCode) throws RuntimeException;

	public void updateProjContractCode(ProjContractCode projContractCode) throws RuntimeException;

	public ProjContractCode findById(Long id) throws RuntimeException;

	public List<ProjContractCode> findListCode(ProjContractCodeQo projContractCodeQo) throws RuntimeException;
}

封装WxtBaseDao:
public abstract class WxtBaseDao {

	private SqlMapClientTemplate sqlMapClientTemplate = new SqlMapClientTemplate();

	@Autowired
	public void setSqlMapClient(SqlMapClient sqlMapClient) {
		this.sqlMapClientTemplate.setSqlMapClient(sqlMapClient);
	}

	protected Object insert(String sql_id, Object param) throws DataAccessException {
		return sqlMapClientTemplate.insert(sql_id, param);
	}

	protected int update(String sql_id, Object param) throws DataAccessException {
		return sqlMapClientTemplate.update(sql_id, param);
	}

	protected int delete(String sql_id, Object id) throws DataAccessException {
		return sqlMapClientTemplate.delete(sql_id, id);
	}

	protected Object find(String sql_id, Object query) throws DataAccessException {
		return sqlMapClientTemplate.queryForObject(sql_id, query);
	}

	@SuppressWarnings("rawtypes")
	protected List list(String sql_id, Object query) throws DataAccessException {
		return sqlMapClientTemplate.queryForList(sql_id, query);
	}

	@SuppressWarnings("rawtypes")
	protected List list(String sql_id) throws DataAccessException {
		return sqlMapClientTemplate.queryForList(sql_id);
	}

	protected Integer number(String sql_id, Object query) throws DataAccessException {
		return (Integer) sqlMapClientTemplate.queryForObject(sql_id, query);
	}
	
	protected Integer number(String sql_id) throws DataAccessException {
		return (Integer) sqlMapClientTemplate.queryForObject(sql_id);
	}

	protected SqlMapClientTemplate getSqlMapClientTemplate() {
		return sqlMapClientTemplate;
	}
}


2.4 dao层接口实现类

@Repository("projContractCodeDao")
@SuppressWarnings("unchecked")
public class ProjContractCodeDaoImpl extends WxtBaseDao implements ProjContractCodeDao {

	@Override
	public Object addProjContractCode(ProjContractCode projContractCode) throws RuntimeException {
		return (Object) insert("ProjContractCode.addProjContractCode", projContractCode);
	}

	@Override
	public void updateProjContractCode(ProjContractCode projContractCode) throws RuntimeException {
		update("ProjContractCode.updateProjContractCode", projContractCode);
	}

	@Override
	public ProjContractCode findById(Long id) throws RuntimeException {
		return (ProjContractCode) find("ProjContractCode.findProjContractCodeById", id);
	}

	@Override
	public List<ProjContractCode> findListCode(ProjContractCodeQo projContractCodeQo) throws RuntimeException {
		return list("ProjContractCode.findProjContractCode", projContractCodeQo);
	}

}

2.5 service层接口

public interface ProjContractCodeSvc {

	public void addProjContractCode(ProjContractCode projContractCode) throws ProjException;

	public List<ProjContractCode> findListCode(ProjContractCodeQo projContractCodeQo) throws ProjException;

	/** 获取合同编号00001-999999 */
	public String getContractCode(String user_id, String project_code) throws ProjException;

}

2.6 service层接口实现类

@Service("projContractCodeSvc")
public class ProjContractCodeSvcImpl implements ProjContractCodeSvc {

	private Logger logger = Logger.getLogger(getClass());

	private static final Long SEQ_START_DEFAULT = 000001L;

	private static final Long SEQ_END_DEFAULT = 999999L;

	private static final String PATTERN = "yyyy-MM-dd HH:mm:ss";

	private final int DEFAULT_SHOW_NUM = 6; // 整数显示最少位数

	@Autowired
	private ProjContractCodeDao projContractCodeDao;

	@Override
	public void addProjContractCode(ProjContractCode projContractCode) throws ProjException {
		if (projContractCode == null) {
			logger.error("保存合同编号数据库错误,保存对象不存在!");
			throw new ProjException("", "保存合同编号数据库错误,保存对象不存在!");
		}

		if (StringUtils.isBlank(projContractCode.getUser_id())) {
			logger.error("保存合同编号数据库错误,user_id不存在!");
			throw new ProjException("", "保存合同编号数据库错误,用户信息不存在!");
		}

		if (StringUtils.isBlank(projContractCode.getProject_code())) {
			logger.error("保存合同编号数据库错误,project_code不存在!");
			throw new ProjException("", "保存合同编号数据库错误,项目信息不存在!");
		}

		if (projContractCode.getSeq_start() == null || projContractCode.getSeq_start() < 0) {
			logger.error("保存合同编号数据库,seq_start不存在,设置默认值为:" + SEQ_START_DEFAULT);
			projContractCode.setSeq_start(SEQ_START_DEFAULT);
		}

		if (projContractCode.getSeq_end() == null || projContractCode.getSeq_end() < 0) {
			logger.error("保存合同编号数据库,seq_end不存在,设置默认值为:" + SEQ_END_DEFAULT);
			projContractCode.setSeq_end(SEQ_END_DEFAULT);
		}

		if (projContractCode.getSeq_end() > SEQ_END_DEFAULT) {
			logger.error("保存合同编号数据库错误,当前值超过最大值了!");
			throw new ProjException("", "保存合同编号数据库错误,当前值超过允许的最大值!");
		}

		if (projContractCode.getCurrent_value() == null || projContractCode.getCurrent_value() < 0) {
			logger.error("保存合同编号数据库,current_value不存在,设置默认值为:" + SEQ_START_DEFAULT);
			projContractCode.setCurrent_value(SEQ_START_DEFAULT);
		}

		if (projContractCode.getLast_update() == null) {
			logger.error("保存合同编号数据库,last_update不存在设置默认值为当前时间");
			String system_time = TimeUtils.getCurrentTime(PATTERN);
			SimpleDateFormat format = new SimpleDateFormat(PATTERN);

			try {
				projContractCode.setLast_update(format.parse(system_time));
			} catch (ParseException e) {
				logger.error("保存合同编号数据库错误,保存当前时间出错!");
				throw new ProjException("", "保存合同编号数据库错误,保存当前时间出错!");
			}
		}

		// 调用dao接口
		try {
			projContractCodeDao.addProjContractCode(projContractCode);
		} catch (Exception e) {
			logger.error("保存合同编号数据库错误", e);
			throw new ProjException("保存合同编号数据库错误", e.getMessage());
		}

	}
@Override
	public List<ProjContractCode> findListCode(ProjContractCodeQo projContractCodeQo) throws ProjException {
		List<ProjContractCode> list = new ArrayList<ProjContractCode>();
		if (projContractCodeQo == null) {
			return list;
		}
		// 调用dao接口
		try {
			list = projContractCodeDao.findListCode(projContractCodeQo);
		} catch (Exception e) {
			logger.error("查询合同编号列表数据库错误", e);
			throw new ProjException("查询合同编号列表数据库错误", e.getMessage());
		}

		return list;
	}

	@Override
	public synchronized String getContractCode(String user_id, String project_code) throws ProjException {
		String code = null;
		Long number = 0L;
		Long curent_max_value = SEQ_START_DEFAULT; // 当前最大值
		if (StringUtils.isBlank(user_id) || StringUtils.isBlank(project_code)) {
			return code;
		}
		// 先查询,后修改
		ProjContractCodeQo projContractCodeQo = new ProjContractCodeQo();
		projContractCodeQo.setProject_code(project_code);
		List<ProjContractCode> listProjs = findListCode(projContractCodeQo);
		if (CollectionUtils.isNotEmpty(listProjs)) {
			Map<String, Object> map = new HashMap<String, Object>();
			for (ProjContractCode projCode : listProjs) {
				map.put(projCode.getUser_id(), projCode);

				if (curent_max_value < projCode.getCurrent_value()) {
					curent_max_value = projCode.getCurrent_value();
				}

			}

			ProjContractCode userProjContractCode = (ProjContractCode) map.get(user_id);
			if (userProjContractCode != null) { // 获取当前值
				number = userProjContractCode.getCurrent_value();
			} else { // 新增一条数据,编号从(当前最大值+1)开始
				Long add_value = curent_max_value + 1;
				if (add_value < SEQ_START_DEFAULT) {
					add_value = SEQ_START_DEFAULT;
				}

				if (add_value > SEQ_END_DEFAULT) {
					add_value = SEQ_END_DEFAULT;
					logger.error("获取合同编号列表数据库错误,当前值超过最大值:" + SEQ_END_DEFAULT);
					throw new ProjException("获取合同编号列表数据库错误,当前值超过最大值:" + SEQ_END_DEFAULT);
				}

				addProjContractCode(converParam(project_code, user_id, curent_max_value + 1));
				number = add_value;
			}

		} else { // 新增一条数据,编号从SEQ_START_DEFAULT开始
			addProjContractCode(converParam(project_code, user_id, SEQ_START_DEFAULT));
			number = SEQ_START_DEFAULT;
		}
		if (number != null) {
			code = (String) numFormat(number, DEFAULT_SHOW_NUM);
		}
		return code;
	}

	/**
	 * 
	 * @param number
	 * @return
	 */
	private Object numFormat(Long value, int minDigit) {
		NumberFormat formatter = NumberFormat.getNumberInstance();
		formatter.setMinimumIntegerDigits(minDigit); // 整数显示最少位数不足前面补零
		formatter.setGroupingUsed(false); // true(带逗号),false
		//
		return formatter.format(value);
	}

	/**
	 * 数据封装
	 * 
	 * @param projContractCode
	 * @param user_id
	 * @return
	 */
	private ProjContractCode converParam(String project_code, String user_id, Long value) {
		ProjContractCode addProjContractCode = new ProjContractCode();
		addProjContractCode.setUser_id(user_id);
		addProjContractCode.setProject_code(project_code);
		addProjContractCode.setCurrent_value(value);
		return addProjContractCode;
	}

}

三 测试:

main方法里:    
ProjContractCodeSvc projContractCodeSvc = (ProjContractCodeSvc)getBean("projContractCodeSvc");
String value = projContractCodeSvc.getContractCode(user_id, project_code);






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值