sunny123456

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  1796 随笔 :: 22 文章 :: 24 评论 :: 226万 阅读
< 2025年3月 >
23 24 25 26 27 28 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 31 1 2 3 4 5

@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` (
  `namevarchar(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.classnew User11Key("张三""15188994534"));
        System.out.println(JSONObject.toJSONString(user));
 
        em.getTransaction().commit();
        em.close();
        emf.close();
        System.out.println("finished.");
    }
 
}


posted on   sunny123456  阅读(958)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 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
点击右上角即可分享
微信分享提示