Hibernate O-R 映射

对象关系映射(Object-Relational Mapping,简称 ORM)是将面向对象模型中的对象映射到关系型数据库中的技术。Hibernate 是一个流行的 ORM 框架,它提供了强大的功能来简化这一过程。下面我将详细介绍 Hibernate 中的对象关系映射。

1. 基础概念

在 Hibernate 中,对象关系映射涉及到以下几个概念:

  • 实体类:Java 类,代表数据库中的表。
  • 属性:Java 类中的字段,映射到数据库表中的列。
  • 主键:唯一标识实体类中的每个实例。
  • 关系:实体类之间的关联,例如一对一、一对多、多对一和多对多。

2. 基本映射

在 Hibernate 中,你可以使用 JPA 注解或 XML 映射文件来定义实体类与数据库表之间的映射关系。下面是一个使用 JPA 注解的基础映射示例:

import jakarta.persistence.*;

@Entity
@Table(name = "employees")
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    private String name;

    private String email;

    // Getters and Setters
}

在这个示例中,Employee 类映射到名为 employees 的数据库表。id 字段是主键,使用 @GeneratedValue 注解设置为主键自动生成策略。

3. 一对一映射

一对一映射通常使用 @OneToOne 注解来实现。以下是一个简单的示例:

@Entity
@Table(name = "employees")
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    private String name;

    private String email;

    @OneToOne(mappedBy = "employee")
    private Address address;

    // Getters and Setters
}

@Entity
@Table(name = "addresses")
public class Address {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    private String street;

    private String city;

    @OneToOne
    @JoinColumn(name = "emp_id")
    private Employee employee;

    // Getters and Setters
}

在这个例子中,Employee 类有一个 address 属性,它表示一个一对一的关系。Address 类有一个 employee 属性,它也表示一个一对一的关系。mappedBy 属性告诉 Hibernate 从哪个方向获取关系信息。

4. 一对多映射

一对多映射使用 @OneToMany@ManyToOne 注解来实现。以下是一个简单的示例:

@Entity
@Table(name = "employees")
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    private String name;

    private String email;

    @OneToMany(mappedBy = "employee", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Project> projects;

    // Getters and Setters
}

@Entity
@Table(name = "projects")
public class Project {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    private String projectName;

    @ManyToOne
    @JoinColumn(name = "emp_id")
    private Employee employee;

    // Getters and Setters
}

在这个例子中,Employee 类有一个 projects 属性,它表示一个员工可以有多个项目。Project 类有一个 employee 属性,它表示一个项目属于一个员工。

5. 多对一映射

多对一映射与一对多映射类似,只是方向相反。下面是一个简单的示例:

@Entity
@Table(name = "projects")
public class Project {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    private String projectName;

    @ManyToOne
    @JoinColumn(name = "emp_id")
    private Employee employee;

    // Getters and Setters
}

@Entity
@Table(name = "employees")
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    private String name;

    private String email;

    @OneToMany(mappedBy = "employee", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Project> projects;

    // Getters and Setters
}

在这个例子中,Project 类有一个 employee 属性,它表示一个项目属于一个员工。Employee 类有一个 projects 属性,它表示一个员工可以有多个项目。

6. 多对多映射

多对多映射通常需要一个额外的关联表。以下是一个简单的示例:

@Entity
@Table(name = "employees")
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    private String name;

    private String email;

    @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
    @JoinTable(
        name = "employee_project",
        joinColumns = @JoinColumn(name = "emp_id"),
        inverseJoinColumns = @JoinColumn(name = "proj_id")
    )
    private List<Project> projects;

    // Getters and Setters
}

@Entity
@Table(name = "projects")
public class Project {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    private String projectName;

    @ManyToMany(mappedBy = "projects")
    private List<Employee> employees;

    // Getters and Setters
}

在这个例子中,Employee 类有一个 projects 属性,它表示一个员工可以参与多个项目。Project 类有一个 employees 属性,它表示一个项目可以由多个员工参与。

7. 继承映射

Hibernate 还支持继承映射,这使得你可以将具有共同属性的实体类组织在一起。这里有几种不同的继承策略:

  • 单表策略(Single Table):所有子类共享同一张表。
  • 每类一张表策略(Table per Class):每个子类都有一张独立的表。
  • 每表一子类策略(Table per Subclass):基类有一张表,每个子类都有自己的表。

下面是一个简单的单表策略示例:

@Entity
@Table(name = "employees")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "type")
public abstract class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    private String name;

    private String email;

    // Getters and Setters
}

@Entity
@DiscriminatorValue("manager")
public class Manager extends Employee {
    private double bonus;

    // Getters and Setters
}

@Entity
@DiscriminatorValue("worker")
public class Worker extends Employee {
    private double hourlyRate;

    // Getters and Setters
}

在这个例子中,Employee 类是抽象的,并且定义了一个名为 type 的区分器列。ManagerWorker 类继承了 Employee 类,并且每个子类都有一个区分器值。

8. 组件映射

组件映射用于将一个 Java 类映射到一个复合列。例如,你可以将一个地址类映射到数据库中的一个地址列。

public class Address {
    private String street;
    private String city;
    private String zipCode;

    // Getters and Setters
}

@Entity
@Table(name = "employees")
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    private String name;

    private String email;

    @Embedded
    private Address address;

    // Getters and Setters
}

在这个例子中,Address 类是一个组件类,它被嵌入到 Employee 类中。

9. 枚举映射

枚举类型也可以被映射到数据库中。下面是一个简单的示例:

@Entity
@Table(name = "employees")
public class Employee {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;

    private String name;

    private String email;

    @Enumerated(EnumType.STRING)
    private Gender gender;

    // Getters and Setters
}

public enum Gender {
    MALE, FEMALE, OTHER
}

在这个例子中,Gender 枚举被映射到数据库中的一列。

总结

这些示例展示了 Hibernate 中一些基本的对象关系映射技术。根据你的具体需求,你可以选择合适的映射类型来处理实体之间的关系。如果你需要更详细的信息或特定的示例,请随时告诉我。

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值