Spring Boot项目中将String类型字段设为主键的注解用法及最佳实践问询
问题解答
一、String类型字段作为主键的最佳实践
- 确保字段值唯一且不可变:作为业务主键的
location必须保证全局唯一,且业务场景下不会修改该字段的值。如果后续存在修改地点名称的需求,建议新增自增数值型字段作为主键,将location改为普通唯一约束字段,避免主键变更引发的关联表数据批量更新问题。 - 做好长度与非空校验:业务层提前校验
location的值,避免空值、长度超出20位的内容传入,减少数据库层面的报错。 - 业务层提前查重:新增数据前先查询对应
location是否已存在,避免触发主键冲突异常。 - 性能方面注意:你当前设置的
location长度仅20位,作为主键的索引存储开销和查询性能和数值型主键差异不大,若后续字符串长度超过50位,会明显增加索引存储成本,该场景下不推荐用字符串作为主键。
二、实体类需要补充的注解与修改后代码
你当前的实体类缺少主键标识@Id、字段映射@Column、表名映射@Table注解,直接运行会抛出JPA无主键的异常,修改后的代码如下:
注意
如果你的Spring Boot版本为3.x及以上,需要将所有javax.persistence开头的导入包替换为jakarta.persistence,Java EE已更名为Jakarta EE,包路径发生了变更。
User.java
package com.hashir.smartcity.entities; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Column; import javax.persistence.Table; @Entity @Table(name = "USER") // 显式指定表名,避免部分数据库中USER为关键字引发的错误 public class User { @Column(name = "FIRST_NAME", length = 20) private String firstName; @Column(name = "LAST_NAME", length = 20) private String lastName; @Column(name = "EMAIL", unique = true, length = 20) private String email; @Column(name = "PASSWORD", length = 25) private String password; @Id // 标记该字段为主键 @Column(name = "LOCATION", nullable = false, length = 20) private String location; // 原有getter setter方法保持不变即可 public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getLocation() { return location; } public void setLocation(String location) { this.location = location; } }
Wander.java
package com.hashir.smartcity.entities; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Column; import javax.persistence.Table; @Entity @Table(name = "WANDER") public class Wander{ @Id // 标记该字段为主键 @Column(name = "LOCATION", nullable = false, length = 20) private String location; @Column(name = "PLACES_TO_EAT", nullable = false, length = 20) private String placesToEat; @Column(name = "VISIT", nullable = false, length = 20) private String visit; @Column(name = "METRO", nullable = false, length = 20) private String metro; // 原有getter setter方法保持不变即可 public String getLocation() { return location; } public void setLocation(String location) { this.location = location; } public String getPlacesToEat() { return placesToEat; } public void setPlacesToEat(String placesToEat) { this.placesToEat = placesToEat; } public String getVisit() { return visit; } public void setVisit(String visit) { this.visit = visit; } public String getMetro() { return metro; } public void setMetro(String metro) { this.metro = metro; } }
内容的提问来源于stack exchange,提问作者Mohammad Hashir
相关产品推荐
相关产品推荐

