本文目录导读:

在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');
最佳实践建议
- 简单应用:使用数据库自增字段 + MyBatis/JPA
- 分布式系统:使用雪花算法或分布式ID生成器(如Redis、ZooKeeper)
- 性能要求高:使用批量插入时预分配ID范围
- 数据迁移需求:考虑使用UUID或业务相关ID
选择哪种方式取决于你的具体需求、数据库类型和系统架构,最常用的是结合ORM框架(MyBatis/JPA)使用数据库的自增字段。