1.如何获取递增主键
我们知道MySQL的auto_increment是用于主键自动增长的,从1开始增长,当你把第一条记录删除时,再插入第二条数据时,主键值是2,不是1,因为主键值永远是递增的。
JDBC中当我们执行一条insert语句,如何能获取到最新生成的主键呢? 我们只需要执行语句对象的getGeneratedKeys()方法,在插入的执行之后,获取主键值。
例如:
public class GenerateKeyDemo {
public static void main(String[] args) {
String sql = "insert into students (sname,gender) values(?,?)";
try(Connection conn = DBUtils.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS))
{
pstmt.setString(1,"张三丰");
pstmt.setString(2,"男");
pstmt.executeUpdate();
ResultSet rs = pstmt.getGeneratedKeys();
long key = -1;
//注意:这里必须把游标指向第一条记录。
if(rs.next()){
key = rs.getLong(1);
}
System.out.println("新添加记录的主键是:" + key);
}catch(Exception ex){
ex.printStackTrace();
}
}
}
2.非递增类型主键
对应非递增类型的主键,要根据主键的类型采用合适的算法,由程序自动生成。
通常对于int类型的主键,通常采用auto_increment或者序列来自动生成,对于字符串类型的主键需要采用合适的主键生成策略。
我们可以使用JDK自带的UUID工具类生成唯一的字符串类型的标识符。UUID 含义是通用唯一识别码 (Universally Unique Identifier),这是一个软件建构的标准。也是被开源软件基金会 (Open Software Foundation, OSF) 的组织应用在分布式计算环境 (Distributed Computing Environment, DCE) 领域的一部分。 UUID 的目的,是让分布式系统中的所有元素,都能有唯一的辨识资讯,而不需要透过中央控制端来做辨识资讯的指定。 如此一来,每个人都可以建立不与其它人冲突的 UUID。在这样的情况下,就不需考虑数据库建立时的名称重复问题。
例如:生成10个32位的UUID编号。
for (int i = 0; i < 10; i++) {
//替换所有的'-'为空串。
String uuid = UUID.randomUUID().toString().replaceAll("-","");
System.out.println(uuid);
}
运行结果:
44c328ab04af4f0ab74e8fa84f3d20f6
b21af26d3cf5470da3c9dd7a067df438
eed1a5d3944c4b8ab76dd422508c5b9b
b73ef12626db40688f2d47073ffa97ce
58528d178fa14919b5e616b5790400a0
e54457e081334741890657d9be52cad9
91019897c0ac4eb48b60f29a326ac2f3
ee2a1b67dba64d2b8347d29e6e92dfed
30ab8e2e2d6d458fb8904635bba636fa
909c29c168f24258817d10e526ee9218
我们也可以使用日期+UUID编号,生成指定长度的卡号。这一算法在实际项目中经常使用。 例如:生成十张会员卡号,卡号的生成规则是:日期+UUID编号,每个卡号的长度16位 (6位日期+10位UUID编号),且由阿拉伯数字组成。
实现算法如下:
//生成日期前缀
String prefix = LocalDateTime.now().format(DateTimeFormatter.ISO_DATE).replaceAll("-","");
for (int i = 0; i < 10; i++) {
String uuid = UUID.randomUUID().toString().replaceAll("-","");
//UUID转换为hashCode
String temp = Math.abs(uuid.hashCode())+"";
//不够十位前面补零
if(temp.length()<10){
String str=temp;
for(int j=0;j<10-temp.length();j++){
str="0"+str;
}
temp = str;
}
//打印卡号
System.out.println(prefix+temp);
}
运行结果:
202003231526802829
202003231858052955
202003231408557390
202003230388645533
202003231896371229
202003231421049316
202003230891326296
202003232081790716
202003232130806793
202003231794791245