Spring Data JPA设置表联合主键

简介: 遇到了一个新的问题,就是如何使用 Spring Data JPA 建立表的联合主键?网上找了很多答案,自己也踩了一些坑,总结出了三种方式,记录一下。

遇到了一个新的问题,就是如何使用 Spring Data JPA 建立表的联合主键?网上找了很多答案,自己也踩了一些坑,总结出了三种方式,记录一下。


第一种方式:


第一种方式是直接使用 @Id 这个注解,来设置联合主键,例如下面这样,我要在 stu_no 和 stu_name 上建立联合主键:

@Entity
@Table(name = "student")
public class Student {
    @Id
    @Column(name = "stu_no", nullable = false, length = 11)
    private Integer stuNo;
    @Id
    @Column(name = "stu_name", nullable = false, length = 128)
    private String stuName;
    @Column(name = "stu_age", nullable = false, length = 3)
    private Integer stuAge;
    @Column(name = "class_id", nullable = false, length = 8)
    private String classId;
}

这种方式很简单,但是问题也是存在的。例如我想把 stu_no 设置为自动递增,加上 @GeneratedValue ,就是不生效,而是作用于 stu_name 这个字段上面,实在是很邪门!


第二种方式:


使用 @IdClass 这个注解来实现,我们需要新建一个主键类,这个类需要实现 Serializable 接口,并且需要无惨构造函数,还需要重写 equals 和 hashCode 方法,具体内容如下:

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
public class StudentUPK implements Serializable {
    private Integer stuNo;
    private String stuName;
}
这里我是使用 lombok 插件来简化代码的,当然你可以自己手写构造函数和重写方法。然后实体类 Student 的内容如下:
@Entity
@IdClass(StudentUPK.class)
@Table(name = "student")
public class Student {
    @Id
    @Column(name = "stu_no", nullable = false, length = 11)
    private Integer stuNo;
    @Id
    @Column(name = "stu_name", nullable = false, length = 128)
    private String stuName;
    @Column(name = "stu_age", nullable = false, length = 3)
    private Integer stuAge;
    @Column(name = "class_id", nullable = false, length = 8)
    private String classId;
}

这种方式也是存在问题的,在使用 JpaRepository 的时候,这样写:public interface StudentRepository extends JpaRepository<Student, StudentUPK> ,ID 写成这主键类,本以为是可以的,但一执行 CRUD 老是会报错,到现在还没找到原因。


第三种方式:


第三种方式是使用 @Embeddable 和 @EmbeddedId 注解来实现,同样是需要一个主键类,内容如下:

@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
@Embeddable
@EqualsAndHashCode
public class StudentUPK implements Serializable {
    @Column(name = "stu_no", nullable = false, length = 11)
    private Integer stuNo;
    @Column(name = "stu_name", nullable = false, length = 128)
    private String stuName;
}
主键类也是需要实现 Serializable 接口,并且需要无惨构造函数,还需要重写 equals 和 hashCode 方法。实体类 Student 的内容如下:
@Entity
@Table(name = "student")
public class Student {
    @EmbeddedId
    private StudentUPK studentUPK;
    @Column(name = "stu_age", nullable = false, length = 3)
    private Integer stuAge;
    @Column(name = "class_id", nullable = false, length = 8)
    private String classId;
}

这里使用了 @EmbeddedId 这个注解。这种方式使用 JpaRepository 是可以的,例如写成这样:`public interface StudentRepository extends JpaRepository<Student, StudentUPK> {

}`

然后再新建一个测试方法:

@SpringBootTest
@RunWith(SpringRunner.class)
public class StudentRepositoryTest {
    @Resource
    private StudentRepository studentRepository;
    @Test
    public void testInsert(){
        StudentUPK upk = StudentUPK.builder().stuNo(132).stuName("Rose Duan").build();
        Student student = Student.builder().studentUPK(upk).stuAge(14).classId("12312323").build();
        studentRepository.save(student);
    }
}

CRUD 的操作应该就成功了!

相关文章
|
2月前
|
Java Spring
spring多线程实现+合理设置最大线程数和核心线程数
本文介绍了手动设置线程池时的最大线程数和核心线程数配置方法,建议根据CPU核数及程序类型(CPU密集型或IO密集型)来合理设定。对于IO密集型,核心线程数设为CPU核数的两倍;CPU密集型则设为CPU核数加一。此外,还讨论了`maxPoolSize`、`keepAliveTime`、`allowCoreThreadTimeout`和`queueCapacity`等参数的设置策略,以确保线程池高效稳定运行。
236 10
spring多线程实现+合理设置最大线程数和核心线程数
|
1月前
|
存储 Java API
如何使用 Java 记录简化 Spring Data 中的数据实体
如何使用 Java 记录简化 Spring Data 中的数据实体
34 9
|
1月前
|
存储 Java API
简单两步,Spring Boot 写死的定时任务也能动态设置:技术干货分享
【10月更文挑战第4天】在Spring Boot开发中,定时任务通常通过@Scheduled注解来实现,这种方式简单直接,但存在一个显著的限制:任务的执行时间或频率在编译时就已经确定,无法在运行时动态调整。然而,在实际工作中,我们往往需要根据业务需求或外部条件的变化来动态调整定时任务的执行计划。本文将分享一个简单两步的解决方案,让你的Spring Boot应用中的定时任务也能动态设置,从而满足更灵活的业务需求。
82 4
|
1月前
|
SQL Java 关系型数据库
Springboot引入jpa来管理数据库
Springboot引入jpa来管理数据库
33 0
Springboot引入jpa来管理数据库
|
1月前
|
SQL Java 数据库连接
springBoot+Jpa(hibernate)数据库基本操作
springBoot+Jpa(hibernate)数据库基本操作
37 0
|
2月前
|
Java 数据库连接 API
【Java笔记+踩坑】Spring Data JPA
从常用注解、实体类和各层编写方法入手,详细介绍JPA框架在增删改查等方面的基本用法,以及填充用户名日期、分页查询等高级用法。
【Java笔记+踩坑】Spring Data JPA
|
3月前
|
Java Spring 数据库
怎样动动手指就能实现数据操作?Spring Data JPA背后的魔法揭秘
【8月更文挑战第31天】在Java开发中,数据库交互至关重要。传统的JDBC操作繁琐且难维护,而Spring Data JPA作为集成JPA的数据访问层解决方案,提供了CRUD等通用操作接口,显著减少代码量。通过继承`JpaRepository`,开发者能轻松实现数据的增删改查,甚至复杂查询和分页也不再困难。本文将通过示例详细介绍如何利用Spring Data JPA简化数据访问层的开发,提升代码质量和可维护性。
41 0
|
3月前
|
Java Spring 开发者
解锁 Spring Boot 自动化配置的黑科技:带你走进一键配置的高效开发新时代,再也不怕繁琐设置!
【8月更文挑战第31天】Spring Boot 的自动化配置机制极大简化了开发流程,使开发者能专注业务逻辑。通过 `@SpringBootApplication` 注解组合,特别是 `@EnableAutoConfiguration`,Spring Boot 可自动激活所需配置。例如,添加 JPA 依赖后,只需在 `application.properties` 配置数据库信息,即可自动完成 JPA 和数据源设置。这一机制基于多种条件注解(如 `@ConditionalOnClass`)实现智能配置。深入理解该机制有助于提升开发效率并更好地解决问题。
70 0
|
3月前
|
存储 Java 数据库
|
2月前
|
SQL 监控 druid
springboot-druid数据源的配置方式及配置后台监控-自定义和导入stater(推荐-简单方便使用)两种方式配置druid数据源
这篇文章介绍了如何在Spring Boot项目中配置和监控Druid数据源,包括自定义配置和使用Spring Boot Starter两种方法。