提出的要求:

  生成13位纯数字的卡号与8位纯数字的卡密,要求卡号与卡密都必须全表唯一,然后保存到mysql。

思路:

  1.首先mysql中将这两个字段设置唯一索引,保证这两个字段的值在该表中是唯一存在的

  2.卡号是有序增长的,实现比较容易,先查询数据库中该字段的最大值,然后进行增长生成

  3.卡密是无序的,实现起来有些困难,(网上查找和经过多次运行结果,发现随机数的重复率是处于最低,所以选定了随机生成),查询数据库中该字段,将该字段放入map中(为了在生成卡密的时候进行判断,该卡密是否存在)每次生成唯一的时候,都会将值放入该map,生成的卡密放入linedklist中(因为这是个频繁的添加操作,linkedlist性能比arraylist性能高)

  4.循环遍历卡号(卡号和卡密数量是一样的),然后生成保存的对象,放入list中

  5.重新saveAll()方法(因为使用的springdatajpa,该saveAll()源码中是将数据进行循环遍历然后还是一条条的保存,使用了jpa的批量保存配置,设置后与未配置时并没有多少区别),进行保存。

代码:

  service层的方法

@PersistenceContext()
protected EntityManager entityManager;

public List<PayGeneralCard> add(PayGeneralCardFormBean formBean){
//校验当前spAppId是否时有效期
PayServiceProvider provider = payServiceProviderService.checkSpAppIdAndState(formBean.getSpAppId());
if(null == provider){
return null;
}
//获取当前应用最大的批次号
int maxBatchNumber = findMaxBatchNumber(formBean.getSpAppId());
//获取最大的卡号
Long byMaxCardNumber = findByMaxCardNumber();
//获取所有卡号,由于是写的sql查询所以数据类型变成了BigInteger,后面会转成Long
List<BigInteger> cardPasswordfindAll = payGeneralCardDao.cardPasswordfindAll();
HashMap<String, Boolean> map = new HashMap<>();
List<Long> cardPasswords = cardPasswordfindAll.stream().map(item-> item.longValue()).collect(Collectors.toList());
for(Long cardPassword:cardPasswords){
map.put(cardPassword.toString(),true);
} //生成卡号
ArrayList<Long> cardNumbers = PayCardNumberUtil.createNumber(formBean.getCount(), byMaxCardNumber); //生成卡密
LinkedList<Long> passwords = PayCardPassWordUtil.createPassword(formBean.getCount(),map); //组装数据
LinkedList<PayGeneralCard> list = new LinkedList<>();
for(int i = 0;i<cardNumbers.size();i++){
PayGeneralCard bean = createBean(formBean.getSpAppId(), formBean.getType(), cardNumbers.get(i),
passwords.get(i), maxBatchNumber);
list.add(bean);
} //保存数据
List<PayGeneralCard> payGeneralCards = savaAll(list);
return payGeneralCards;

}

//批量添加数据
public List<PayGeneralCard> savaAll(List<PayGeneralCard> payGeneralCards){
ArrayList<PayGeneralCard> list = new ArrayList<>(16);
for(PayGeneralCard payGeneralCard : payGeneralCards){
entityManager.persist(payGeneralCard);
list.add(payGeneralCard);
}
return list;
}

  

PayCardNumberUtil
import java.util.ArrayList;

public class PayCardNumberUtil {
private static long seq = 1000000000000l;
private static final long ROTATION = 9999999999999l; public static synchronized long next() {
if (seq > ROTATION) seq = 1000000000000l;
return seq++;
} /**
* 生成一卡通卡号的方法
* @param count 生成总数
* @param startNumber 从这个数开始往后生成
* @return
*/
public static ArrayList<Long> createNumber(long count,long startNumber){
if(seq < startNumber){
seq = startNumber;
}
ArrayList<Long> list = new ArrayList<>();
for (int i = 0; i < count; i++) {
long next = PayCardNumberUtil.next();
list.add(next);
}
return list;
} public static void main(String[] args) {
System.out.println(PayCardNumberUtil.createNumber(10l, 2004000000057l));
} }

  

PayCardPassWordUtil
import java.util.*;

/**
* 一卡通密码生成器
*
* @author nature
* @create 2017-12-22 10:58
*/
public class PayCardPassWordUtil { public static LinkedList<Long> createPassword(Long count,Map<String, Boolean> map){
LinkedList<Long> list = new LinkedList<>();
for (int i = 0; i < count; i++) {
String number = generateUID(map);
list.add(Long.parseLong(number));
}
return list;
} //唯一一个在测试时没有重复项的方法
public static String generateUID(Map<String, Boolean> map){
Random random = new Random();
String result="";
for(int i=0;i<8;i++){
//首字母不能为0
result += (random.nextInt(9)+1);
}
//如果有值说明改卡密已经存在了,需要重新再生成
if(null != map.get(result)){
return generateUID(map);
}
map.put(result,true);
return result;
} public static void main(String[] args) {
Map<String, Boolean> map = new HashMap<String, Boolean>();
for (int i = 0; i < 1000; i++) {
System.out.println(generateUID(map));
}
}
}

  

最新文章

  1. spring boot 配置启动后执行sql, 中文乱码
  2. JMeter专题系列(五)检查点
  3. HttpUrlConnection 的 setDoOutput 与 setDoInput
  4. C++ STL模板
  5. 实现窗体随着鼠标移动(控件)--《用delphi开发共享软件》-15.1任务管理器
  6. 六个创建模式之抽象工厂模式(Abstract Factory Pattern)
  7. 20145222黄亚奇《Java程序设计》第9周学习总结
  8. C# 读取文本文档(转)
  9. efficient c++,单线程内存池
  10. CGI/FASTCGI/ISAPI区别
  11. Android 动画效果 及 自定义动画
  12. 从零开始写一个Tomcat(叁)--请求解析
  13. .NET和JAVA的比较- 体系结构
  14. FFMpeg在Ubuntu上的安装和使用
  15. pycharm中的光标变粗的问题
  16. 在Ubuntu下如何切换到超级用户
  17. Mahout 算法
  18. JAVA程序员学PHP
  19. HDU 6382 odds (暴力 + 剪枝优化)
  20. finecms同时调用子栏目和子栏目的文章怎么操作

热门文章

  1. tslib-1.4移植(转)
  2. GIS和视频监控的集成
  3. 多测师肖sir_pdf转word方法
  4. 多测试_linux_003_肖sir
  5. BigInteger和BigDecimal
  6. python中jsonpath模块运用
  7. linux(centos8):配置docker的cgroup driver为systemd
  8. 第三章 虚拟机的简单使用及其xshell远程工具的使用
  9. 【转】time 模块详解(时间获取和转换)
  10. 微信小程序-基于高德地图API实现天气组件(动态效果)