You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 16:24:03