@IdClass 注解和@Id JPA联合主键
原文链接:https://www.hxstrive.com/subject/open_jpa/538.htm
前面章节已经介绍了 @Id 注解,该注解定义实体类中某个属性为数据库的主键,一个实体里面必须有一个主键。本章节将介绍 @IdClass 注解,该注解用来为某个实体指定复合主键,复合主键存放在一个单独的类当中。
符合主键类需要要满足以下要求:
必须实现 Serializable 接口;
必须有默认的 public 无参数的构造方法;
必须覆盖 equals 和 hashCode 方法。equals 方法用于判断两个对象是否相同,EntityManger 通过 find 方法来查找 Entity 时是根据 equals 的返回值来判断的。hashCode 方法返回当前对象的哈希码,生成的 hashCode 相同的概率越小越好,算法可以进行优化。
实例
(1)假设我们拥有一张 users2 表,该表使用 “name” + “phone” 作为复合主键。SQL 脚本如下:
1 2 3 4 5 6 7 | CREATE TABLE `users2` ( ` name ` varchar (100) NOT NULL , `phone` varchar (15) NOT NULL , `email` varchar (100) DEFAULT NULL , `address` varchar (255) DEFAULT NULL , PRIMARY KEY (` name `,`phone`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
(2)为上面的 users2 表的复合主键 “name” + “phone” 创建复合主键 User11Key.java 类,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | import lombok.Data; import java.io.Serializable; @Data public class User11Key implements Serializable { private String name; private String phone; public User11Key() {} public User11Key(String name, String phone) { this .name = name; this .phone = phone; } } |
(3)为 users2 表创建一个实体类,在实体类上面使用 @IdClass 注解指定复合主键。同时,需要在 name 和 phone 字段上面使用 @Id 注解标记为主键。代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | import lombok.Data; import javax.persistence.*; @Data @Entity @Table (name = "users2" ) @IdClass (value = User11Key. class ) public class User11 { // 指定为主键 @Id @Column (nullable = false ) private String name; // 指定为主键 @Id @Column (nullable = false ) private String phone; @Column private String email; @Column private String address; } |
(4)客户端代码,使用 EntityManager 的实例根据复合主键查询 users 表中的数据。代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | import com.alibaba.fastjson.JSONObject; import com.huangx.openjpa.annotation.entity.User11; import com.huangx.openjpa.annotation.entity.User11Key; import javax.jws.soap.SOAPBinding; import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; import javax.persistence.Query; import java.util.List; public class OpenJpaDemo11 { /** 持久化单元名称 */ private static final String NAME = "openJPA" ; public static void main(String[] args) { EntityManagerFactory emf = Persistence.createEntityManagerFactory(NAME); EntityManager em = emf.createEntityManager(); em.getTransaction().begin(); // 根据主键查询数据 User11 user = em.find(User11. class , new User11Key( "张三" , "15188994534" )); System.out.println(JSONObject.toJSONString(user)); em.getTransaction().commit(); em.close(); emf.close(); System.out.println( "finished." ); } } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)
2021-07-13 C#发起Http请求,调用接口
2021-07-13 C#发起HTTP请求Post请求
2021-07-13 C# 调用HTTP接口两种方式Demo WebRequest/WebResponse 和WebApi