SpringBoot——》关联映射

推荐链接:
    总结——》【Java】
    总结——》【Mysql】
    总结——》【Redis】
    总结——》【Kafka】
    总结——》【Spring】
    总结——》【SpringBoot】
    总结——》【MyBatis、MyBatis-Plus】
    总结——》【Linux】
    总结——》【MongoDB】
    总结——》【Elasticsearch】

一、场景

以员工、地址、部门、角色四者之间的关联关系为例:

  1. 一个员工只能有一个地址,一个地址也只属于一个员工;
  2. 一个员工只能属于一个部门,但是一个部门可以包含有多个员工;
  3. 一个员工可以拥有多个角色,一个角色也可以属于多个员工。
实体类描述备注
tb_employeeEmployee员工一个员工只能有一个地址
一个员工只能属于一个部门
一个员工可以拥有多个角色
tb_addressAddress地址一个地址只属于一个员工
tb_departmentDepartment部门一个部门可以包含有多个员工
tb_roleRole角色一个角色也可以属于多个员工

二、关联映射

由于 @OneToOne(一对一)、@OneToMany(一对多)、@ManyToOne(多对一)、@ManyToMany(多对多) 等注解只能确定实体之间几对几的关联关系,它们并不能指定与实体相对应的数据库表中的关联字段,因此,需要与 @JoinColumn 注解来配合使用。

1、@OneToOne(一对一)

实现一:@JoinColumn

在员工表中会有一个指向地址表主键的字段address_id

// 一个员工只能有一个地址,在员工实体类中添加如下注解:

@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "address_id")
private Address address;

实现二:@PrimaryKeyJoinColumn

如果员工表和地址表是以主键关联的:

  • 员工表主键:employee_id
  • 地址表主键:address_id
// 一个员工只能有一个地址,在员工实体类中添加如下注解:

@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@PrimaryKeyJoinColumn(name = "employee_id", referencedColumnName = "address_id")
private Address address;

实现三:不使用@JoinColumn和@PrimaryKeyJoinColumn

Hibernate会自动在员工表生成关联字段,字段默认的命名规则:被控方类名_被控方主键,如:address_id

// 一个员工只能有一个地址,在员工实体类中添加如下注解:

@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
// Hibernate会自动在员工表生成关联字段,字段默认的命名规则:被控方类名_被控方主键,如:address_id
private Address address;

2、@OneToMany(一对多)

一个员工只能属于一个部门,但是一个部门可以包含有多个员工,如果我们站在部门的角度来看,部门与员工之间就是一对多的关系。

实现一:@JoinColumn

// 一个部门可以包含有多个员工,在部门实体类中添加如下注解:

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "department_id")
private List<Employee> employees;

实现二:@JoinTable

// 一个部门可以包含有多个员工,在部门实体类中添加如下注解:

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
/**
* joinColumns 用来指定中间表中关联自己ID的字段 
* inverseJoinColumns 用来指定中间表中关联对方ID的字段
*/
@JoinTable(name = "tbl_employee_department", joinColumns = {
@JoinColumn(name = "department_id") }, inverseJoinColumns = { @JoinColumn(name = "employee_id") })
private List<Employee> employees;

实现三:不使用@JoinColumn

Hibernate会自动生成一张中间表来对员工和部门进行绑定,表名默认的命名规则:一的表名_一实体类中关联多的属性名,例如,部门表名为 tb_department ,部门实体中关联的员工集合属性名为 employees ,则生成的中间表名为:tb_department_employees。
通常并不推荐让Hibernate自动去自动生成中间表,而是使用@JoinTable注解来指定中间表。

3、@ManyToOne(多对一)

实现一:@JoinColumn

// 一个部门可以包含有多个员工,但一个员工只能属于一个部门,在员工实体类中添加如下注解:

@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "department_id")
private Department department;

4、@ManyToMany(多对多)

一个员工可以拥有多个角色,一个角色也可以属于多个员工,员工与角色之间就是多对多的关系。通常这种多对多关系都是通过创建中间表来进行关联处理,并使用@JoinTable注解来指定。

实现一:@JoinTable

// 一个员工可以拥有多个角色,在员工实体类中添加如下注解:

@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinTable(name = "tb_employee_role", joinColumns = { @JoinColumn(name = "employee_id") }, inverseJoinColumns = {
@JoinColumn(name = "role_id") })
private List<Role> roles;
// 一个角色可以属于多个员工,在角色实体类中添加如下注解:

@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinTable(name = "tb_employee_role", joinColumns = { @JoinColumn(name = "role_id") }, inverseJoinColumns = {
    @JoinColumn(name = "employee_id") })
private List<Employee> employees;

三、完整示例

1、员工实体类:Employee.java

@Entity
@Table(name = "tb_employee")
@Comment("员工")
@Data
public class Employee {

    @Id
    @GeneratedValue(generator = "seq_employee_id")
    @SequenceGenerator(name = "seq_employee_id", sequenceName = "seq_employee_id")
    private Long id;

    @Column(name = "name", columnDefinition = "varchar(64) COMMENT '名称'", nullable = false)
    private String name;

    @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinColumn(name = "address_id", columnDefinition = "bigint(20) COMMENT '地址ID'", nullable = false)
    // @PrimaryKeyJoinColumn(name = "employee_id", referencedColumnName = "address_id")
    private Address address;

    @Getter
    @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    @JoinColumn(name = "department_id")
    private Department department;

    @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinTable(name = "tb_employee_role",
            joinColumns = {@JoinColumn(name = "employee_id")},
            inverseJoinColumns = {@JoinColumn(name = "role_id")})
    private List<Role> roles; // 角色
}

2、地址实体类:Address.java

@Entity
@Table(name = "tb_address")
@Comment("地址")
@Data
public class Address {
    @Id
    @GeneratedValue(generator = "seq_address_id")
    @SequenceGenerator(name = "seq_address_id", sequenceName = "seq_address_id")
    private Long id;

    @Column(name = "address", columnDefinition = "varchar(64) COMMENT '地址'", nullable = false)
    private String address;
}

3、部门实体类:Department.java

@Entity
@Table(name = "tb_department")
@Comment("部门")
@Data
public class Department {

    @Id
    @GeneratedValue(generator = "seq_department_id")
    @SequenceGenerator(name = "seq_department_id", sequenceName = "seq_department_id")
    private Long id;

    @Getter
    @Column(name = "name", columnDefinition = "varchar(64) COMMENT '名称'", nullable = false)
    private String name;

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    @JoinColumn(name = "department_id")

    /**
     * joinColumns 用来指定中间表中关联自己ID的字段
     * inverseJoinColumns 用来指定中间表中关联对方ID的字段
     */
//    @JoinTable(name = "tb_employee_department",
//            joinColumns = {@JoinColumn(name = "department_id", referencedColumnName = "id")},
//            inverseJoinColumns = {@JoinColumn(name = "employee_id", referencedColumnName = "id")})
    private List<Employee> employees;
}

4、角色实体类:Role.java

@Entity
@Table(name = "tb_role")
@Comment("角色")
@Data
public class Role {

    @Id
    @GeneratedValue(generator = "seq_role_id")
    @SequenceGenerator(name = "seq_role_id", sequenceName = "seq_role_id")
    private Long id;

    @Column(name = "name", columnDefinition = "varchar(64) COMMENT '名称'", nullable = false)
    private String name;

    @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinTable(name = "tb_employee_role",
            joinColumns = {@JoinColumn(name = "role_id")},
            inverseJoinColumns = {@JoinColumn(name = "employee_id")})
    private List<Employee> employees; // 拥有角色的员工
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,关于在 Spring Boot 中插入一条数据,我们可以按照以下步骤进行操作: 1. 首先,我们需要在 pom.xml 中引入 Spring Boot 的相关依赖,包括 Spring Boot Starter 和 Spring Boot Starter Data JPA,如下所示: ```xml <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> </dependencies> ``` 2. 在 application.properties 或 application.yml 配置文件中,配置数据库连接信息,例如: ```properties spring.datasource.url=jdbc:mysql://localhost:3306/test spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.jdbc.Driver ``` 3. 创建一个实体类,用于映射数据库中的表结构,例如: ```java @Entity @Table(name = "user") public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; private Integer age; // 省略 getter 和 setter 方法 } ``` 4. 创建一个 Repository 接口,用于操作数据库,例如: ```java @Repository public interface UserRepository extends JpaRepository<User, Long> { } ``` 5. 在业务逻辑中调用 UserRepository 的 save() 方法即可插入一条数据,例如: ```java @Service public class UserService { @Autowired private UserRepository userRepository; public void addUser() { User user = new User(); user.setName("张三"); user.setAge(20); userRepository.save(user); } } ``` 以上就是在 Spring Boot 中插入一条数据的详细步骤。需要注意的是,在实际开发中,我们需要根据具体的业务需求进行适当的调整,例如增加数据校验、事务管理等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值