← 返回首页
JDBC教程(七)
发表时间:2020-03-23 01:41:59
讲解JDBC之获取自增主键

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