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 的操作应该就成功了!

相关文章
|
7天前
|
druid Java 关系型数据库
Spring Boot2 系列教程(二十五)Spring Boot 整合 Jpa 多数据源
Spring Boot2 系列教程(二十五)Spring Boot 整合 Jpa 多数据源
|
5天前
|
XML 运维 Java
Spring运维之boot项目打包jar和插件运行并且设置启动时临时属性和自定义配置文件
Spring运维之boot项目打包jar和插件运行并且设置启动时临时属性和自定义配置文件
11 1
|
13天前
|
安全 Java API
Java一分钟之-Spring Data REST:创建RESTful服务
【6月更文挑战第15天】Spring Data REST让基于Spring Data的项目轻松创建REST API,免去大量控制器代码。通过自动HTTP映射和链接生成,简化CRUD操作。文章涵盖启用REST、配置仓库、自定义端点、解决过度暴露、缺失逻辑和安全性问题,提供代码示例,如自定义Repository、投影和安全配置,强调在利用其便利性时注意潜在挑战。
26 5
|
18小时前
|
SQL Java 数据库
使用Spring Boot和Spring Data JPA进行数据库操作
使用Spring Boot和Spring Data JPA进行数据库操作
|
5天前
|
运维 Java 测试技术
Spring运维之业务层测试数据回滚以及设置测试的随机用例
Spring运维之业务层测试数据回滚以及设置测试的随机用例
7 0
|
18天前
|
NoSQL Java MongoDB
Java一分钟之-Spring Data MongoDB:MongoDB集成
【6月更文挑战第11天】Spring Data MongoDB简化Java应用与MongoDB集成,提供模板和Repository模型。本文介绍其基本用法、常见问题及解决策略。包括时间字段的UTC转换、异常处理和索引创建。通过添加相关依赖、配置MongoDB连接、定义Repository接口及使用示例,帮助开发者高效集成MongoDB到Spring Boot应用。注意避免时间差、异常处理不充分和忽视索引的问题。
34 0
|
19天前
|
缓存 NoSQL Java
Java一分钟之-Spring Data Redis:使用Redis做缓存
【6月更文挑战第10天】Spring Data Redis是Spring框架的一部分,简化了Java应用与Redis的集成,支持多种数据结构操作。本文介绍了其基本使用,包括添加依赖、配置Redis连接及使用RedisTemplate。还讨论了常见问题,如序列化、缓存穿透和雪崩,并提供解决方案。通过实战示例展示了缓存与数据库读写分离的实现,强调了Spring Data Redis在提升系统性能中的作用。
45 0
|
19天前
|
SQL Java 数据库
Java一分钟之-Spring Data JPA:简化数据库访问
【6月更文挑战第10天】Spring Data JPA是Spring Data项目的一部分,简化了Java数据库访问。它基于JPA,提供Repository接口,使开发者能通过方法命名约定自动执行SQL,减少代码量。快速上手包括添加相关依赖,配置数据库连接,并定义实体与Repository接口。常见问题涉及主键生成策略、查询方法命名和事务管理。示例展示了分页查询的使用。掌握Spring Data JPA能提升开发效率和代码质量。
36 0
|
1月前
|
SQL Java 数据库连接
Springboot框架整合Spring Data JPA操作数据
Spring Data JPA是Spring基于ORM和JPA规范封装的框架,简化了数据库操作,提供增删改查等接口,并可通过方法名自动生成查询。集成到Spring Boot需添加相关依赖并配置数据库连接和JPA设置。基础用法包括定义实体类和Repository接口,通过Repository接口可直接进行数据操作。此外,JPA支持关键字查询,如通过`findByAuthor`自动转换为SQL的`WHERE author=?`查询。
|
1月前
|
存储 安全 Java
第2章 Spring Security 的环境设置与基础配置(2024 最新版)(下)
第2章 Spring Security 的环境设置与基础配置(2024 最新版)(下)
34 0