博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JPA(六):映射关联关系------映射单向一对多的关联关系
阅读量:6889 次
发布时间:2019-06-27

本文共 10838 字,大约阅读时间需要 36 分钟。

映射单向一对多的关联关系

新建项目项目请参考《》,基于上一章讲解的《》中的例子进行修改(需要清空数据中的表,因为本例子还是使用customer,order表来测试,但是关联关系发生了变化):

Customer.java

package com.dx.jpa.singlemanytoone;import java.util.Date;import java.util.HashSet;import java.util.Set;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.OneToMany;import javax.persistence.Table;import javax.persistence.Temporal;import javax.persistence.TemporalType;import javax.persistence.Transient;@Entity@Table(name = "jpa_customer")public class Customer {    private Integer id;    private String fullName;    private Integer age;    private Date birth;    private Date createDate;    private Set
orders = new HashSet<>(); @Id @GeneratedValue(strategy = GenerationType.AUTO) public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } @Column(name = "FULL_NAME", length = 64, nullable = false) public String getFullName() { return fullName; } public void setFullName(String fullName) { this.fullName = fullName; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Temporal(TemporalType.DATE) public Date getBirth() { return birth; } public void setBirth(Date birth) { this.birth = birth; } @Temporal(TemporalType.TIMESTAMP) public Date getCreateDate() { return createDate; } public void setCreateDate(Date createDate) { this.createDate = createDate; } // 映射一对多的关联关系 // @JoinColumn 用来映射一对多的关联关系 // @OneToMany 用来映射外键列 @JoinColumn(name = "CUSTOMER_ID") @OneToMany() public Set
getOrders() { return orders; } public void setOrders(Set
orders) { this.orders = orders; } // 帮助方法,不希望保存到数据库,但是需要动态获取Customer对象的属性。 @Transient public String getCustomerInfo() { return "username:" + fullName + ",age:" + age; }}
View Code

注意:这里在Customer.java中添加了一对多的注解@OneToMany:

// 映射一对多的关联关系    // @JoinColumn 用来映射一对多的关联关系    // @OneToMany 用来映射外键列    @JoinColumn(name = "CUSTOMER_ID")    @OneToMany()    public Set
getOrders() { return orders; }

Order.java

package com.dx.jpa.singlemanytoone;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.Table;@Entity@Table(name = "jpa_order")public class Order {    private Integer id;    private String name;    @Id    @GeneratedValue(strategy = GenerationType.AUTO)    public Integer getId() {        return id;    }    public void setId(Integer id) {        this.id = id;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }}
View Code

初始化JPA项目时,创建表语句如下:

Hibernate:         create table hibernate_sequence (       next_val bigint    ) engine=InnoDBHibernate:         insert into hibernate_sequence values ( 1 )Hibernate:         insert into hibernate_sequence values ( 1 )Hibernate:         create table jpa_customer (       id integer not null,        age integer,        birth date,        createDate datetime,        FULL_NAME varchar(64) not null,        primary key (id)    ) engine=InnoDBHibernate:         create table jpa_order (       id integer not null,        name varchar(255),        CUSTOMER_ID integer,        primary key (id)    ) engine=InnoDBHibernate:         alter table jpa_order        add constraint FK7glkngwj74nr8h2amofkp1fjd        foreign key (CUSTOMER_ID)        references jpa_customer (id)
View Code

persistence.xml

org.hibernate.jpa.HibernatePersistenceProvider
com.dx.jpa.singlemanytoone.Customer
com.dx.jpa.singlemanytoone.Order
View Code

此时在order表中创建了外键关联关系:

添加测试

添加测试函数:

@Test    public void testPersist() {        Customer customer = new Customer();        customer.setFullName("AA");        customer.setAge(26);        customer.setBirth(new Date());        customer.setCreateDate(new Date());        Order order1 = new Order();        order1.setName("O-AA-01");        Order order2 = new Order();        order2.setName("O-AA-02");                customer.getOrders().add(order1);        customer.getOrders().add(order2);                entityManager.persist(customer);        entityManager.persist(order1);        entityManager.persist(order2);    }

此时执行sql如下:

Hibernate:     select        next_val as id_val     from        hibernate_sequence for update            Hibernate:     update        hibernate_sequence     set        next_val= ?     where        next_val=?Hibernate:     select        next_val as id_val     from        hibernate_sequence for update            Hibernate:     update        hibernate_sequence     set        next_val= ?     where        next_val=?Hibernate:     select        next_val as id_val     from        hibernate_sequence for update            Hibernate:     update        hibernate_sequence     set        next_val= ?     where        next_val=?Hibernate:     insert     into        jpa_customer        (age, birth, createDate, FULL_NAME, id)     values        (?, ?, ?, ?, ?)Hibernate:     insert     into        jpa_order        (name, id)     values        (?, ?)Hibernate:     insert     into        jpa_order        (name, id)     values        (?, ?)Hibernate:     update        jpa_order     set        CUSTOMER_ID=?     where        id=?Hibernate:     update        jpa_order     set        CUSTOMER_ID=?     where        id=?
View Code

此时并不是因为customer,order保存顺序导致的(即使调换添加先后顺序也会多处update语句),因为多的一端在插入时不会插入外键列,因此一定会多处update语句。

查询测试

添加测试函数:

@Test    public void testFind() {        Customer customer = entityManager.find(Customer.class, 1);        System.out.println(customer.getFullName());        System.out.println(customer.getOrders().size());    }
View Code

执行打印结果:

Hibernate:     select        customer0_.id as id1_0_0_,        customer0_.age as age2_0_0_,        customer0_.birth as birth3_0_0_,        customer0_.createDate as createDa4_0_0_,        customer0_.FULL_NAME as FULL_NAM5_0_0_     from        jpa_customer customer0_     where        customer0_.id=?AAHibernate:     select        orders0_.CUSTOMER_ID as CUSTOMER3_1_0_,        orders0_.id as id1_1_0_,        orders0_.id as id1_1_1_,        orders0_.name as name2_1_1_     from        jpa_order orders0_     where        orders0_.CUSTOMER_ID=?2

从打印结果上可以看出默认采用懒加载的方式,修改Customer.java中的@OneToMany()中的fetch属性为:@OneToMany(fetch=FetchType.EAGER),此时才会出现非懒加载:

此时,再次执行插叙测试函数,执行打印结果如下:

Hibernate:     select        customer0_.id as id1_0_0_,        customer0_.age as age2_0_0_,        customer0_.birth as birth3_0_0_,        customer0_.createDate as createDa4_0_0_,        customer0_.FULL_NAME as FULL_NAM5_0_0_,        orders1_.CUSTOMER_ID as CUSTOMER3_1_1_,        orders1_.id as id1_1_1_,        orders1_.id as id1_1_2_,        orders1_.name as name2_1_2_     from        jpa_customer customer0_     left outer join        jpa_order orders1_             on customer0_.id=orders1_.CUSTOMER_ID     where        customer0_.id=?AA2

修改测试

修改测试函数:

@Test    public void testUpdate() {        Customer customer = entityManager.find(Customer.class, 1);        customer.getOrders().iterator().next().setName("O-XX-01");    }

此时执行打印结果为:

Hibernate:     select        customer0_.id as id1_0_0_,        customer0_.age as age2_0_0_,        customer0_.birth as birth3_0_0_,        customer0_.createDate as createDa4_0_0_,        customer0_.FULL_NAME as FULL_NAM5_0_0_,        orders1_.CUSTOMER_ID as CUSTOMER3_1_1_,        orders1_.id as id1_1_1_,        orders1_.id as id1_1_2_,        orders1_.name as name2_1_2_     from        jpa_customer customer0_     left outer join        jpa_order orders1_             on customer0_.id=orders1_.CUSTOMER_ID     where        customer0_.id=?Hibernate:     update        jpa_order     set        name=?     where

注意:这时@OneToMany(fetch=FetchType.EAGER)

删除测试

删除测试函数:

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

此时customer表内容记录如下:

order表记录如下:

此时执行删除,可以删除成功,删除后customer.id=4的记录被删除了,而order表中id=5,6记录的customer_id值被置为null。

删除后结果为:

customer表记录:

order表记录:

从执行打印语句可以看出:

Hibernate:     select        customer0_.id as id1_0_0_,        customer0_.age as age2_0_0_,        customer0_.birth as birth3_0_0_,        customer0_.createDate as createDa4_0_0_,        customer0_.FULL_NAME as FULL_NAM5_0_0_,        orders1_.CUSTOMER_ID as CUSTOMER3_1_1_,        orders1_.id as id1_1_1_,        orders1_.id as id1_1_2_,        orders1_.name as name2_1_2_     from        jpa_customer customer0_     left outer join        jpa_order orders1_             on customer0_.id=orders1_.CUSTOMER_ID     where        customer0_.id=?Hibernate:     update        jpa_order     set        CUSTOMER_ID=null     where        CUSTOMER_ID=?Hibernate:     delete     from        jpa_customer     where        id=?

 实际上,我们可以通过配置@OneToMany的级联删除属性,可以通过删除customer来实现级联删除的。

修改Customer.java中的@OneToMany注解信息:

这里修改配置后Customer的getOrders()方法的注解为:

// 映射一对多的关联关系    // @JoinColumn 用来映射一对多的关联关系    // @OneToMany 用来映射外键列    @JoinColumn(name = "CUSTOMER_ID")    @OneToMany(fetch=FetchType.EAGER,cascade=CascadeType.REMOVE)    public Set
getOrders() { return orders; }

此时,测试通过删除customer.id=1的记录,测试结果可以成功级联删除,执行打印结果为:

Hibernate:     select        customer0_.id as id1_0_0_,        customer0_.age as age2_0_0_,        customer0_.birth as birth3_0_0_,        customer0_.createDate as createDa4_0_0_,        customer0_.FULL_NAME as FULL_NAM5_0_0_,        orders1_.CUSTOMER_ID as CUSTOMER3_1_1_,        orders1_.id as id1_1_1_,        orders1_.id as id1_1_2_,        orders1_.name as name2_1_2_     from        jpa_customer customer0_     left outer join        jpa_order orders1_             on customer0_.id=orders1_.CUSTOMER_ID     where        customer0_.id=?Hibernate:     update        jpa_order     set        CUSTOMER_ID=null     where        CUSTOMER_ID=?Hibernate:     delete     from        jpa_order     where        id=?Hibernate:     delete     from        jpa_order     where        id=?Hibernate:     delete     from        jpa_customer     where        id=?

 

转载地址:http://heqbl.baihongyu.com/

你可能感兴趣的文章
【原创翻译】布尔值(boolean)
查看>>
关于scrapy的piplines
查看>>
通向架构师的道路(第一天)之Apache整合Tomcat - lifetragedy的专栏 - 博客频道 - CSDN.NET...
查看>>
项目、软件开发过程中版本术语
查看>>
T-SQL中INSERT、UPDATE
查看>>
openSUSE13.2安装ruby和rails
查看>>
python 高级函数
查看>>
F.Cards with Numbers
查看>>
简单入门Buffer
查看>>
OO第四阶段总结
查看>>
javascript总结02
查看>>
创建windows服务
查看>>
用main函数传参做简单的计算器的代码
查看>>
python中struct.unpack的用法
查看>>
体绘制(Volume Rendering)概述之4:光线投射算法(Ray Casting)实现流程和代码(基于CPU的实现)...
查看>>
Python实践之(七)逻辑回归(Logistic Regression)
查看>>
PAT (Advanced Level) 1107. Social Clusters (30)
查看>>
【开源社群系统研发日记五】ThinkSNS+ 是如何计算字符显示长度的
查看>>
Nodejs日志管理log4js
查看>>
python获取昨日日期
查看>>