Spring Data JPA ---多表关联

多表关联操作

	<dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.22</version>
    </dependency>

一对一

客户表 —> 老婆表
客户表 —> 账户表

在这里插入图片描述
实现:

@OneToOne
@JoinColumn(name="外键字段名")
 @OneToOne(mappedBy	= "customer",cascade	= {CascadeType.PERSIST,CascadeType.REMOVE})
@JoinColumn(name="wife_id")
private Wife wife;

wife

@Entity
@Table(name="tb_account")
@Data
/*@Getter // 生成所有属性的get方法
@Setter // 生成所有属性的set方法
@RequiredArgsConstructor // 生成final属性的构造函数, 如果没有final就是无参构造函数
@EqualsAndHashCode*/ public class Account {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY) private Long id;
private String username;
private String password;
}

2.配置关联操作

  // 单向关联 一对一
   /*
   * cascade 设置关联操作
   * ALL, 所有持久化操作
   PERSIST 只有插入才会执行关联操作
   MERGE, 只有修改才会执行关联操作
   REMOVE, 只有删除才会执行关联操作
   fetch 设置是否懒加载
   EAGER 立即加载(默认)
   LAZY 懒加载( 直到用到对象才会进行查询,因为不是所有的关联对象 都需要用到)
   orphanRemoval 关联移除(通常在修改的时候会用到)
   一旦把关联的数据设置null ,或者修改为其他的关联数据, 如果想删除关联数据, 就可以设置true
   optional 限制关联的对象不能为null
    true 可以为null(默认 ) false 不能为null
   mappedBy 将外键约束执行另一方维护(通常在双向关联关系中,会放弃一方的外键约束)
   值= 另一方关联属性名
   * */
	@OneToOne(mappedBy = "customer",
	cascade = CascadeType.ALL,fetch = FetchType.LAZY,orphanRemoval=true,optional=false)
	   // 设置外键的字段名
	@JoinColumn(name="account_id")
	private Account account;
  }

测试 :

@ContextConfiguration(classes = SpringDataJPAConfig.class)
@RunWith(SpringJUnit4ClassRunner.class)
public class OneToOneTest {
@Autowired
CustomerRepository repository;

// 插入
@Test
public void testC(){
// 初始化数据
Account account = new Account(); account.setUsername("xushu");

Customer customer = new Customer();
customer.setCustName("张三"); 
customer.setAccount(account);

account.setCustomer(customer);

repository.save(customer);
}

// 插入
@Test
// 为什么懒加载要配置事务 :
// 当通过repository调用完查询方法,session就会立即关闭, 一旦session你就不能查询,
// 加了事务后, 就能让session直到事务方法执行完毕后才会关闭
@Transactional(readOnly = true) public void testR(){
Optional<Customer> customer = repository.findById(3L); // 只查询出客户, session关闭
System.out.println("================="); System.out.println(customer.get()); // toString
}

@Test
public void testD(){ 
	repository.deleteById(1L);
}

@Test
public void testU(){

Customer customer = new Customer();
customer.setCustId(7L); 
customer.setCustName("张三");
customer.setAccount(null);
repository.save(customer);
   }
 }

差异:

这两个设置之间的区别在于对断开关系。例如,当设置地址字段设置为null或另一个Address对象。
如果指定了 orphanRemovel = true , 则会自动删除断开连接的Address实例。这对于清理很有用 没有一个不应该存在的相关对象(例如地址) 来自所有者对象(例如员工)的引用。

如果仅指定 cascade = CascadeType.REMOVE , 则不会执行任何自动操作,因为断开关系不是删除操作

一对多

一个客户 有多条信息
在这里插入图片描述

1.配置管理关系

@OneToMany
@JoinColumn(name="customer_id")
@OneToMany
@JoinColumn(name="customer_id")
private List<Message> message;

2.配置关联操作

多对一

实现:

1.配置管理关系
@ManyToOne
@JoinColumn(name=“customer_id”)
@ManyToOne
@JoinColumn(name=“customer_id”)
private List message;

2.配置关联操作

多对多
在这里插入图片描述

1.配置管理关系
@ManyToMany
@JoinColumn(name=“customer_id”)
@ManyToMany
@JoinTable(name=“tb_customer_role”,joinColumns={@JoinColumn(name=“c_id”)},inverseJoinColumns={@JoinColumn(name=“r_i d”)})
private List roles;

2.配置关联操作

。。。

3.测试

 // 保存
    /*
    1.如果保存的关联数据  希望使用已有的 ,就需要从数据库中查出来(持久状态)。否则 提示 游离状态不能持久化
    2.如果一个业务方法有多个持久化操作, 记得加上@Transactional ,否则不能共用一个session
    3. 在单元测试中用到了@Transactional , 如果有增删改的操作一定要加@Commit
    4. 单元测试会认为你的事务方法@Transactional,  只是测试而已, 它不会为你提交事务,  需要单独加上 @Commit
     */
    @Test
    @Transactional
    @Commit
    public void testC() {

        List<Role> roles=new ArrayList<>();
        roles.add(roleRepository.findById(9L).get());
        roles.add(roleRepository.findById(10L).get());

        Customer customer = new Customer();
        customer.setCustName("盘古");
        customer.setRoles(roles);

        repository.save(customer);
    }


    @Test
    @Transactional(readOnly = true)
    public void testR() {


        System.out.println(repository.findById(14L));

        //repository.save(customer);
    }


    /*
    * 注意加上
    * @Transactional
        @Commit
      多对多其实不适合删除, 因为经常出现数据出现可能除了和当前这端关联还会关联另一端,此时删除就会: ConstraintViolationException。
      * 要删除, 要保证没有额外其他另一端数据关联
    * */
    @Test
    @Transactional
    @Commit
    public void testD() {


        Optional<Customer> customer = repository.findById(14L);

        repository.delete(customer.get());
    }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值