Java案例怎么实现主键自增?

wen java案例 49

本文目录导读:

Java案例怎么实现主键自增?

  1. 使用数据库自增字段
  2. 使用 MyBatis 框架
  3. 使用 JPA/Hibernate
  4. 使用 Spring JDBC
  5. 分布式环境下的自增ID(雪花算法)
  6. 数据库序列(Oracle/PostgreSQL)
  7. 最佳实践建议

在Java中实现主键自增主要有以下几种方式,具体取决于你使用的数据库和ORM框架:

使用数据库自增字段

MySQL 示例

CREATE TABLE user (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(50),
    age INT
);

JDBC 实现

public class UserDao {
    public int insertUser(User user) {
        String sql = "INSERT INTO user (name, age) VALUES (?, ?)";
        try (Connection conn = DriverManager.getConnection(url, username, password);
             PreparedStatement pstmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
            pstmt.setString(1, user.getName());
            pstmt.setInt(2, user.getAge());
            int affectedRows = pstmt.executeUpdate();
            if (affectedRows > 0) {
                // 获取自增主键
                ResultSet rs = pstmt.getGeneratedKeys();
                if (rs.next()) {
                    long id = rs.getLong(1);
                    user.setId(id);
                    return (int) id;
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return -1;
    }
}

使用 MyBatis 框架

XML 配置方式

<!-- UserMapper.xml -->
<insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
    INSERT INTO user (name, age) VALUES (#{name}, #{age})
</insert>

注解方式

@Insert("INSERT INTO user (name, age) VALUES (#{name}, #{age})")
@Options(useGeneratedKeys = true, keyProperty = "id")
int insertUser(User user);

使用示例

@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;
    public User createUser(User user) {
        userMapper.insertUser(user);
        // 插入后 user.getId() 会自动获取自增ID
        System.out.println("Generated ID: " + user.getId());
        return user;
    }
}

使用 JPA/Hibernate

Entity 配置

@Entity
@Table(name = "user")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(name = "name")
    private String name;
    @Column(name = "age")
    private Integer age;
    // getters and setters
}

使用示例

@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;
    public User createUser(User user) {
        User savedUser = userRepository.save(user);
        // savedUser.getId() 自动包含自增ID
        return savedUser;
    }
}

使用 Spring JDBC

使用 SimpleJdbcInsert

@Repository
public class UserDao {
    @Autowired
    private JdbcTemplate jdbcTemplate;
    public long insertUser(User user) {
        SimpleJdbcInsert insert = new SimpleJdbcInsert(jdbcTemplate)
            .withTableName("user")
            .usingGeneratedKeyColumns("id");
        Map<String, Object> parameters = new HashMap<>();
        parameters.put("name", user.getName());
        parameters.put("age", user.getAge());
        Number generatedId = insert.executeAndReturnKey(parameters);
        return generatedId.longValue();
    }
}

分布式环境下的自增ID(雪花算法)

当使用分布式数据库时,可以使用雪花算法生成唯一ID:

public class SnowflakeIdGenerator {
    private final long datacenterId;
    private final long machineId;
    private long sequence = 0L;
    private long lastTimestamp = -1L;
    public SnowflakeIdGenerator(long datacenterId, long machineId) {
        this.datacenterId = datacenterId;
        this.machineId = machineId;
    }
    public synchronized long nextId() {
        long timestamp = System.currentTimeMillis();
        if (timestamp < lastTimestamp) {
            throw new RuntimeException("Clock moved backwards");
        }
        if (timestamp == lastTimestamp) {
            sequence = (sequence + 1) & 4095;
            if (sequence == 0) {
                timestamp = tilNextMillis(lastTimestamp);
            }
        } else {
            sequence = 0L;
        }
        lastTimestamp = timestamp;
        return ((timestamp - 1288834974657L) << 22)
             | (datacenterId << 17)
             | (machineId << 12)
             | sequence;
    }
    private long tilNextMillis(long lastTimestamp) {
        long timestamp = System.currentTimeMillis();
        while (timestamp <= lastTimestamp) {
            timestamp = System.currentTimeMillis();
        }
        return timestamp;
    }
}

数据库序列(Oracle/PostgreSQL)

PostgreSQL 示例

CREATE TABLE user (
    id SERIAL PRIMARY KEY,
    name VARCHAR(50)
);

Oracle 示例

CREATE SEQUENCE user_seq START WITH 1 INCREMENT BY 1;
CREATE TABLE user (
    id NUMBER PRIMARY KEY,
    name VARCHAR2(50)
);
-- 插入时使用序列
INSERT INTO user (id, name) VALUES (user_seq.NEXTVAL, 'John');

最佳实践建议

  1. 简单应用:使用数据库自增字段 + MyBatis/JPA
  2. 分布式系统:使用雪花算法或分布式ID生成器(如Redis、ZooKeeper)
  3. 性能要求高:使用批量插入时预分配ID范围
  4. 数据迁移需求:考虑使用UUID或业务相关ID

选择哪种方式取决于你的具体需求、数据库类型和系统架构,最常用的是结合ORM框架(MyBatis/JPA)使用数据库的自增字段。

抱歉,评论功能暂时关闭!