JPA学习03

 

滴水穿石

 单向多对一

外键关联关系的创建

//映射单向多n-1的关联关系
    //使用@ManyToOne 来映射多对一的关联关系
    //使用@JoinColumn 来映射外键
    @JoinColumn(name = "CUSTOMER_ID")
    @ManyToOne
    public Customer getCustomer() {
        return customer;
    }

 

单元测试

@Test
    public void TestManyToOnePersist(){
        Customer customer = new Customer();
        customer.setAge(32);
        customer.setEmail("3232@cfb.com");
        customer.setName("azsd");
        
        Order order1 = new Order();
        order1.setOrderName("order1");
        
        Order order2 = new Order();
        order2.setOrderName("order2");
        
        order1.setCustomer(customer);
        order2.setCustomer(customer);
        
        entityManager.persist(customer);
        entityManager.persist(order1);
        entityManager.persist(order2);
    }

 

 

 

上边我们是先保存 customer ,后保存order 的,如果反着来呢?

@Test
    public void TestManyToOnePersist(){
        Customer customer = new Customer();
        customer.setAge(43);
        customer.setEmail("432@cfb.com");
        customer.setName("sras");
        
        Order order1 = new Order();
        order1.setOrderName("order1");
        
        Order order2 = new Order();
        order2.setOrderName("order2");
        
        order1.setCustomer(customer);
        order2.setCustomer(customer);
        
        entityManager.persist(order1);
        entityManager.persist(order2);
        entityManager.persist(customer);
    }

我们看到保存依然成功,但是SQL执行的顺序,先执行的order的插入操作并没有插入外键

而是在customer执行插入完成后,再执行了两个 update()操作

所以

保存多对一是,建议先保存 1 的一端,后保存 n 的一端,减少开销

 -----

查询

@Test
    public void TestFindOrder(){
        
        Order order = entityManager.find(Order.class, 1);
        
        System.out.println(order.toString());
    }

查询使用的左外连接来获取  n 的一端 和与其关联的 1 的一端

 ------

可以使用@ManyToOne 的fetch 属性来修改关联属性的加载策略

@ManyToOne(fetch=FetchType.LAZY)

测试结果:

 

 ---

删除有外键关联的数据

@Test
    public void TestManyToOneRemove(){
        
        Customer customer = entityManager.find(Customer.class, 5);
        
        entityManager.remove(customer);
    }

删除失败

不能删除被当做外键使用的 1 端的数据

 

 

如果是 @oneToMany的情况下就不同了

如果删除 1 的一端,会删除成功

默认会把 n 端的外键置空为 null

cascade 的属性来设置级联删除

cascade={CascadeType.REMOVE}

—————————————————————————————————————————————————————————————————————————

无论如何,心平气和

posted @ 2017-07-27 11:27  江湖一笑  阅读(147)  评论(0编辑  收藏  举报