SprintBoot系列(十五):JPA级联操作

菜单

一、单向一对一级联操作

1.1单向一对一插入

1.1.1创建客户和账号的model层

customer

package com.fcors.fcors.model;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.*;
import java.sql.Timestamp;
import java.util.Objects;

@Entity
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "tb_customer")
public class TbCustomerEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String custAddress;
    private String custName;

    @OneToOne(cascade = CascadeType.ALL,fetch = FetchType.EAGER)
    @JoinColumn(name="account_id")
    private TbAccountEntity tbAccount;


}

Account

package com.fcors.fcors.model;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.*;
import java.sql.Timestamp;
import java.util.Objects;

@Entity
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "tb_account")
public class TbAccountEntity extends BaseEntity{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String password;
    private String username;
}

1.1.2 创建客户和账号的接口Repository

customer

package com.fcors.fcors.repository;

import com.fcors.fcors.model.TbCustomerEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

/*JpaRepository<@value1,@value2>
 * @value1:model类名
 * @value:model的主键即表的主键
 * */
@Repository
public interface CustomeRepository extends JpaRepository<TbCustomerEntity,Long> {

    TbCustomerEntity findOneByCustName(String name);
}

Account

package com.fcors.fcors.repository;

import com.fcors.fcors.model.TbAccountEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

/*JpaRepository<@value1,@value2>
 * @value1:model类名
 * @value:model的主键即表的主键
 * */
@Repository
public interface AccountRepository extends JpaRepository<TbAccountEntity,Long> {

}

1.1.3单元测试插入

package com.fcors.fcors;

import com.fcors.fcors.model.TbAccountEntity;
import com.fcors.fcors.model.TbCustomerEntity;
import com.fcors.fcors.repository.CustomeRepository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.Optional;

@SpringBootTest
public class OneToOneTest {

    @Autowired
    private CustomeRepository customeRepository;

    @Test
    public void insertCustomer(){
        /*创建Account*/
        TbAccountEntity tbAccount = TbAccountEntity.builder()
                .username("my_fox5L")
                .password("123")
                .build();
        /*创建Customer*/
        TbCustomerEntity tbCustomerEntity = TbCustomerEntity.builder()
                .custName("fox5L")
                .custAddress("FS")
                .tbAccount(tbAccount)
                .build();

        customeRepository.save(tbCustomerEntity);
    }
}
JAVA、基础技术、技术与框架SprintBoot系列(十五):JPA级联操作插图

1.2单向一对一查询

1.2.1创建客户和账号的model层(与 1.1.1 一致)

1.2.2 创建客户和账号的接口Repository(与1.1.2一致)

1.2.3单元测试一对一查询

package com.fcors.fcors;

import com.fcors.fcors.model.TbAccountEntity;
import com.fcors.fcors.model.TbCustomerEntity;
import com.fcors.fcors.repository.CustomeRepository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.Optional;

@SpringBootTest
public class OneToOneTest {

    @Autowired
    private CustomeRepository customeRepository;

    @Test
    public void getOneByName(){
        Long id = 5L;
        Optional<TbCustomerEntity> tbCustomerEntity =  customeRepository.findById(id);
        System.out.println(tbCustomerEntity.toString());
    }
}

1.3单向一对一更新

1.3.1创建客户和账号的model层(与 1.1.1 一致)

1.3.2 创建客户和账号的接口Repository(与1.1.2一致)

1.3.3单元测试一对一更新

package com.fcors.fcors;

import com.fcors.fcors.model.TbAccountEntity;
import com.fcors.fcors.model.TbCustomerEntity;
import com.fcors.fcors.repository.CustomeRepository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.Optional;

@SpringBootTest
public class OneToOneTest {

    @Autowired
    private CustomeRepository customeRepository;

    @Test
    public void UpdateCustomer(){
        /*创建Account*/
        TbAccountEntity tbAccount = TbAccountEntity.builder()
                .username("my_fox5LNew")
                .password("123")
                .id(5L)
                .build();
        /*创建Customer*/
        TbCustomerEntity tbCustomerEntity = TbCustomerEntity.builder()
                .id(5L)
                .custName("fox5LNew")
                .custAddress("FS")
                .tbAccount(tbAccount)
                .build();

        customeRepository.save(tbCustomerEntity);
    }
}
JAVA、基础技术、技术与框架SprintBoot系列(十五):JPA级联操作插图1

1.4单向一对一全删除

1.4.1创建客户和账号的model层(与 1.1.1 一致)

1.4.2 创建客户和账号的接口Repository(与1.1.2一致)

1.4.3单元测试一对一全删除

package com.fcors.fcors;

import com.fcors.fcors.model.TbAccountEntity;
import com.fcors.fcors.model.TbCustomerEntity;
import com.fcors.fcors.repository.CustomeRepository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.Optional;

@SpringBootTest
public class OneToOneTest {

    @Autowired
    private CustomeRepository customeRepository;

    @Test
    public void deleteCustomer(){
        Long id = 5L;
        customeRepository.deleteById(id);
    }
}

结果是客户表和账号表都删除了

1.5关联删除

orphanRemoval = true

关联数据设置成null或者修改为其他关联数据时,删除关联数据

1.5.1创建客户和账号的model层

package com.fcors.fcors.model;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.*;
import java.sql.Timestamp;
import java.util.Objects;

@Entity
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "tb_customer")
public class TbCustomerEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String custAddress;
    private String custName;

    @OneToOne(cascade = CascadeType.ALL,fetch = FetchType.LAZY,orphanRemoval = true)
    @JoinColumn(name="account_id")
    private TbAccountEntity tbAccount;


}

1.5.2 创建客户和账号的接口Repository(与1.1.2一致)

1.5.3单元测试一对一关联删除

package com.fcors.fcors;

import com.fcors.fcors.model.TbAccountEntity;
import com.fcors.fcors.model.TbCustomerEntity;
import com.fcors.fcors.repository.CustomeRepository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.Optional;

@SpringBootTest
public class OneToOneTest {

    @Autowired
    private CustomeRepository customeRepository;

    @Test
    public void deleteRelateCustomer(){
        /*创建Customer*/
        TbCustomerEntity tbCustomerEntity = TbCustomerEntity.builder()
                .id(7L)
                .custName("fox5L")
                .custAddress("FS")
                .tbAccount(null)
                .build();

        customeRepository.save(tbCustomerEntity);   
    }
}
JAVA、基础技术、技术与框架SprintBoot系列(十五):JPA级联操作插图2

关联数据修改(没有指明Account的id)会把关联删除

    @Test
    public void UpdateCustomer(){
        /*创建Account*/
        TbAccountEntity tbAccount = TbAccountEntity.builder()
                .username("2345")
                .password("12311")
                .build();
        /*创建Customer*/
        TbCustomerEntity tbCustomerEntity = TbCustomerEntity.builder()
                .id(8L)
                .custName("fox5LNew")
                .custAddress("FS")
                .tbAccount(tbAccount)
                .build();

        customeRepository.save(tbCustomerEntity);
    }
JAVA、基础技术、技术与框架SprintBoot系列(十五):JPA级联操作插图3

二、双向一对一级联操作

一般来说为了提高性能,都会使用懒加载的方式,从现在开始例子全部使用懒加载

2.1双向一对一级联查询

2.1.1创建客户和账号的model层

Customer

package com.fcors.fcors.model;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.*;
import java.sql.Timestamp;
import java.util.Objects;

@Entity
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "tb_customer")
public class TbCustomerEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String custAddress;
    private String custName;
    @Override
    public String toString() {
        return "TbCustomerEntity{" +
                "id=" + id +
                ", custAddress='" + custAddress + '\'' +
                ", custName='" + custName + '\'' +
                ", tbAccount{" +
                "  id=" + id +
                ", password='" + tbAccount.getPassword() + '\'' +
                ", username='" + tbAccount.getUsername() + '\'' +
                " }"+
                '}';
    }
//    @OneToOne(mappedBy = "tbCustomer",cascade = CascadeType.ALL,fetch = FetchType.LAZY)
//    @OneToOne(cascade = CascadeType.ALL,fetch = FetchType.LAZY)
    @OneToOne(cascade = CascadeType.ALL,fetch = FetchType.LAZY,orphanRemoval = true)
    @JoinColumn(name="account_id",referencedColumnName = "id")
    private TbAccountEntity tbAccount;


}

Account

package com.fcors.fcors.model;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.*;
import java.sql.Timestamp;
import java.util.Objects;

@Entity
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "tb_account")
public class TbAccountEntity extends BaseEntity{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String password;
    private String username;

    @OneToOne(mappedBy = "tbAccount",cascade = CascadeType.ALL)
    @JoinColumn(name="id",referencedColumnName = "account_id")
    private TbCustomerEntity tbCustomer;
}

2.1.2创建客户和账号的接口Repository(与1.1.2一致)

2.1.3单元测试双向一对一查看

package com.fcors.fcors;

import com.alibaba.fastjson.JSONObject;
import com.fcors.fcors.model.TbAccountEntity;
import com.fcors.fcors.model.TbCustomerEntity;
import com.fcors.fcors.repository.AccountRepository;
import com.fcors.fcors.repository.CustomeRepository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.transaction.annotation.Transactional;

import java.util.Optional;

@SpringBootTest
public class OneToOneTest {

    @Autowired
    private CustomeRepository customeRepository;

    @Autowired
    private AccountRepository accountRepository;

    /*从Account查看*/
    @Test
    @Transactional(readOnly = true)
    public  void findOneByName(){
        Long id = 36L;
        Optional<TbAccountEntity> tbAccountEntity =  accountRepository.findById(id);
        System.out.println(JSONObject.toJSONString(tbAccountEntity));
        System.out.println("===================");
        System.out.println(tbAccountEntity.map(TbAccountEntity::getUsername));

    }
    /*从Customer查看*/
    @Test
    @Transactional(readOnly = true)
    public void getOneByName(){
        Long id = 34L;
        Optional<TbCustomerEntity> tbCustomerEntity =  customeRepository.findById(id);

        System.out.println(tbCustomerEntity.toString());
        System.out.println("===================");
        System.out.println(tbCustomerEntity.map(TbCustomerEntity::getCustAddress));
    }
JAVA、基础技术、技术与框架SprintBoot系列(十五):JPA级联操作插图4

2.2双向一对一级联插入

2.2.1创建客户和账号的model层(与2.1.1一致)

2.2.2创建客户和账号的接口Repository(与1.1.2一致)

2.2.3单元测试双向一对一级联插入

懒加载时,不需要加入事务注解

因为mappby写在Account中,所以调用级联插入的时候,调用CustomerRepository

package com.fcors.fcors;

import com.fcors.fcors.model.TbAccountEntity;
import com.fcors.fcors.model.TbCustomerEntity;
import com.fcors.fcors.repository.AccountRepository;
import com.fcors.fcors.repository.CustomeRepository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.transaction.annotation.Transactional;

import java.util.Optional;

@SpringBootTest
public class OneToOneTest {

    @Autowired
    private CustomeRepository customeRepository;

    @Autowired
    private AccountRepository accountRepository;

    @Test
    public void insertCustomer(){
        /*创建Account*/
        TbAccountEntity tbAccount = TbAccountEntity.builder()
                .username("my_fox5L")
                .password("123")

                .build();
        /*创建Customer*/
        TbCustomerEntity tbCustomerEntity = TbCustomerEntity.builder()
                .custName("fox5L")
                .custAddress("FS")
                .tbAccount(tbAccount)
                .build();

        customeRepository.save(tbCustomerEntity);
    }
}

2.2双向一对一级联更新

因为mappby写在Account中,所以调用级联插入的时候,调用customeRepository

    @Test
    public void UpdateRelateCustomer(){
        /*创建Account*/
        TbAccountEntity tbAccount = TbAccountEntity.builder()
                .id(39L)
                .username("2345")
                .password("12311")
                .build();
        /*创建Customer*/
        TbCustomerEntity tbCustomerEntity = TbCustomerEntity.builder()
                .id(36L)
                .custName("fox5LNew")
                .custAddress("FS")
                .tbAccount(tbAccount)
                .build();

        customeRepository.save(tbCustomerEntity);
    }

2.3双向一对一级联删除

    @Test
    public void deleteCustomer(){
        Long id = 34L;
        customeRepository.deleteById(id);

    }

跟单向一对一删除一致。

三、单向一对多级联操作

3.1单向一对多级联查询

3.1.1创建客户和消息的model

客户

package com.fcors.fcors.model;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.*;
import java.util.List;

@Entity
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "tb_customer")
public class CustomerEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String custAddress;
    private String custName;

    @OneToMany(cascade = CascadeType.ALL,fetch = FetchType.LAZY)
    @JoinColumn(name="customer_id",referencedColumnName = "id")
    private List<TbMessageEntity> tbMessageEntityList;
}

消息

package com.fcors.fcors.model;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.*;
import java.util.Objects;

@Entity
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "tb_message")
public class TbMessageEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String info;
    private Long customerId;


}

3.1.2创建客户和消息的Repository

客户

package com.fcors.fcors.repository;

import com.fcors.fcors.model.CustomerEntity;
import org.springframework.data.jpa.repository.JpaRepository;

public interface CustomerRepository extends JpaRepository<CustomerEntity,Long> {

}

消息

package com.fcors.fcors.repository;

import com.fcors.fcors.model.TbMessageEntity;
import org.springframework.data.jpa.repository.JpaRepository;


public interface MessageRepository extends JpaRepository<TbMessageEntity,Long> {
}

3.1.3单元测试一对多查询

    @Test
    public void findOne(){
        Optional<CustomerEntity> customerEntity = customerRepository.findById(43L);
        System.out.println(JSONObject.toJSONString(customerEntity));
        System.out.println("===================");
        System.out.println(customerEntity.map(CustomerEntity::getTbMessageEntityList));

    }
JAVA、基础技术、技术与框架SprintBoot系列(十五):JPA级联操作插图5

3.2单向一对多级联插入

3.2.1创建客户和消息的model(与3.1.1一致)

3.2.2创建客户和消息的Repository(与3.1.2一致)

3.2.3单元测试一对多插入

package com.fcors.fcors;

import com.fcors.fcors.model.CustomerEntity;
import com.fcors.fcors.model.TbMessageEntity;
import com.fcors.fcors.repository.CustomerRepository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.ArrayList;
import java.util.List;

@SpringBootTest
public class OneToMany {
    @Autowired
    private CustomerRepository customerRepository;

    @Test
    public void insert(){
        List<TbMessageEntity> tbMessageEntityList = new ArrayList<>();
        for(int i=0;i<=3;i++) {
            tbMessageEntityList.add(TbMessageEntity.builder().info(String.format("Hello%d",i)).build());
        }

        CustomerEntity customerEntity = CustomerEntity.builder()
                .custName("fox")
                .tbMessageEntityList(tbMessageEntityList)
                .build();

        customerRepository.save(customerEntity);
    }

}

3.3单向一对多级联更新

3.3.1创建客户和消息的model(与3.1.1一致)

3.3.2创建客户和消息的Repository(与3.1.2一致)

3.3.3单元测试一对多更新

@Test
    public void update(){
        List<TbMessageEntity> tbMessageEntityList = new ArrayList<>();
        for(int i=0;i<=3;i++) {
            tbMessageEntityList.add(TbMessageEntity.builder()
                    .info(String.format("Hello%d",i+2))
                    .customerId(42L)
                    .id(Long.valueOf(18+i))
                    .build());
        }

        CustomerEntity customerEntity = CustomerEntity.builder()
                .id(42L)
                .custName("fox")
                .tbMessageEntityList(tbMessageEntityList)
                .build();

        customerRepository.save(customerEntity);
    }

3.4单向一对多级联删除

3.4.1创建客户和消息的model(与3.1.1一致)

3.4.2创建客户和消息的Repository(与3.1.2一致)

3.4.3单元测试一对多删除

   @Test
    public void delete(){

        customerRepository.deleteById(42L);
    }

四、双向一对多级联操作

4.1双向一对多级联插入

4.1.1创建客户和信息的model

客户

package com.fcors.fcors.model;

import com.fcors.fcors.vo.MessageVO;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.*;
import java.util.List;
import java.util.stream.Collectors;

@Entity
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "tb_customer")
public class CustomerEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String custAddress;
    private String custName;

    @Override
    public String toString() {
        return "CustomerEntity{" +
                "id=" + id +
                ", custAddress='" + custAddress + '\'' +
                ", custName='" + custName + '\'' +
//                ", tbMessageEntityList=" + tbMessageEntityList.stream().map(MessageVO::new).toString() + '\'' +
                '}';
    }

    @OneToMany(cascade = CascadeType.ALL,fetch = FetchType.LAZY)
    @JoinColumn(name="customer_id",referencedColumnName = "id")
    private List<TbMessageEntity> tbMessageEntityList;
}

信息

多方不需要增加@JoinColumn和关联字段

package com.fcors.fcors.model;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.*;
import java.util.Objects;

@Entity
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "tb_message")
public class TbMessageEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String info;
//    @Column(name="customer_id")
//    private Long customerId;

    @ManyToOne(cascade = CascadeType.ALL,fetch = FetchType.LAZY)
    private CustomerEntity customer;
}

4.1.2创建客户和信息的Repository(与3.1.2一致)

4.1.3单元测试双向一对多级联插入

 @Test
    public void insertByCustomer(){

        List<TbMessageEntity> tbMessageEntityList = new ArrayList<>();
        for(int i=1;i<=4;i++) {
            tbMessageEntityList.add(TbMessageEntity.builder()
                    .info(String.format("Hello%d",i))
//                    .customer(customerEntity)
                    .build());
        }
        CustomerEntity customerEntity = CustomerEntity.builder()
                .custName("fox")
                .tbMessageEntityList(tbMessageEntityList)
                .build();
        customerRepository.save(customerEntity);

    }

    @Test
    public void insertByMessage(){
        CustomerEntity customerEntity = CustomerEntity.builder()
                .custName("fox")
                .build();
        List<TbMessageEntity> tbMessageEntityList = new ArrayList<>();
        for(int i=1;i<=4;i++) {
            tbMessageEntityList.add(TbMessageEntity.builder()
                           .info(String.format("Hello%d",i))
                            .customer(customerEntity)
                            .build());
        }

        messageRepository.saveAll(tbMessageEntityList);

    }

4.2双向一对多更新

貌似不能这样操作

4.3双向一对多删除

4.4.1创建客户和消息的model(与3.1.1一致)

4.4.2创建客户和消息的Repository(与3.1.2一致)

4.4.3双向一对多单元测试删除

    @Test
    public void deleteAll(){
        customerRepository.deleteAll();
    }

    @Test
    public void delete(){
        messageRepository.deleteAll();
    }

4.5双向一对多查询

4.4.1创建客户和消息的model

修改客户的model;重载tostring方法

package com.fcors.fcors.model;

import com.fcors.fcors.vo.MessageVO;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.*;
import java.util.List;
import java.util.stream.Collectors;

@Entity
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "tb_customer")
public class CustomerEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String custAddress;
    private String custName;

    @Override
    public String toString() {
        return "CustomerEntity{" +
                "id=" + id +
                ", custAddress='" + custAddress + '\'' +
                ", custName='" + custName + '\'' +
//                ", tbMessageEntityList=" + tbMessageEntityList.stream().map(MessageVO::new).toString() + '\'' +
                '}';
    }

    @OneToMany(cascade = CascadeType.ALL,fetch = FetchType.LAZY)
    @JoinColumn(name="customer_id",referencedColumnName = "id")
    private List<TbMessageEntity> tbMessageEntityList;
}

4.4.2创建客户和消息的Repository(与3.1.2一致)

单元测试双向一对多查询

@Test
    @Transactional(readOnly = true)
    public  void searchCustomer2(){
        Optional<TbMessageEntity> tbMessageEntity = messageRepository.findById(50L);
        System.out.println("===================");
        System.out.println(tbMessageEntity);
        System.out.println("===================");
        System.out.println(tbMessageEntity.map(TbMessageEntity::getCustomer));



    }

    @Test
    @Transactional(readOnly = true)
    public  void searchCustomer1(){
        Optional<CustomerEntity> customerEntity = customerRepository.findById(50L);
        System.out.println("===================");
        System.out.println(customerEntity);
        System.out.println("===================");
        System.out.println(customerEntity.map(CustomerEntity::getTbMessageEntityList));
        System.out.println(customerEntity.map(CustomerEntity::getTbMessageEntityList));
    }

多对多的场景,我们可以通过spu、sku、spec来进行讲解。根据关系,我们不难得到以下的关联关系。spec由spec_key表和spec_value两个表组成

  • spec_key===spec_value=====>1对多
  • spu======sku==========>1对多
  • spu======spec_key======>多对多
  • sku======spec_value====>多对多