JPA

来源:互联网 发布:网络骗局如何报警 编辑:程序博客网 时间:2024/05/29 15:46

【1】Customer与Order

Order:Customer=N:1;

Order如下:

import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.FetchType;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.ManyToOne;import javax.persistence.Table;@Table(name="JPA_ORDERS")@Entitypublic class Order {    private Integer id;    private String orderName;    private Customer customer;    @GeneratedValue    @Id    public Integer getId() {        return id;    }    public void setId(Integer id) {        this.id = id;    }    @Column(name="ORDER_NAME")    public String getOrderName() {        return orderName;    }    public void setOrderName(String orderName) {        this.orderName = orderName;    }    //映射单向 n-1的关联关系    //使用@ManyToOne来映射多对一的关联关系    //使用@JoinColumn 来映射外键               //可使用 @ManyToOne 的fetch 属性来修改默认的关联属性的加载策略    @JoinColumn(name="CUSTOMER_ID")//  @ManyToOne(fetch=FetchType.LAZY)    @ManyToOne(fetch=FetchType.EAGER)    public Customer getCustomer() {        return customer;    }    public void setCustomer(Customer customer) {        this.customer = customer;    }}

Customer如下:

import java.util.Date;import java.util.HashSet;import java.util.Set;import javax.persistence.Cacheable;import javax.persistence.CascadeType;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.FetchType;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.NamedQuery;import javax.persistence.OneToMany;import javax.persistence.Table;import javax.persistence.Temporal;import javax.persistence.TemporalType;import javax.persistence.Transient;@NamedQuery(name="testNamedQuery", query="FROM Customer c WHERE c.id = ?")@Cacheable(true)@Table(name="JPA_CUTOMERS")@Entitypublic class Customer {    private Integer id;    private String lastName;    private String email;    private int age;    private Date createdTime;    private Date birth;    public Customer() {    }    public Customer(String lastName, int age) {        super();        this.lastName = lastName;        this.age = age;    }//  @TableGenerator(name="ID_GENERATOR",//          table="jpa_id_generators",//          pkColumnName="PK_NAME",//          pkColumnValue="CUSTOMER_ID",//          valueColumnName="PK_VALUE",//          allocationSize=100)//  @GeneratedValue(strategy=GenerationType.TABLE,generator="ID_GENERATOR")    @GeneratedValue(strategy=GenerationType.AUTO)    @Id    public Integer getId() {        return id;    }    public void setId(Integer id) {        this.id = id;    }    @Column(name="LAST_NAME",length=50,nullable=false)    public String getLastName() {        return lastName;    }    public void setLastName(String lastName) {        this.lastName = lastName;    }    public String getEmail() {        return email;    }    public void setEmail(String email) {        this.email = email;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }    @Temporal(TemporalType.TIMESTAMP)    public Date getCreatedTime() {        return createdTime;    }    public void setCreatedTime(Date createdTime) {        this.createdTime = createdTime;    }    @Temporal(TemporalType.DATE)    public Date getBirth() {        return birth;    }    public void setBirth(Date birth) {        this.birth = birth;    }    @Transient    public String getInfo(){        return "lastName: " + lastName + ", email: " + email;    }    @Override    public String toString() {        return "Customer [id=" + id + ", lastName=" + lastName + ", email="                + email + ", age=" + age + ", createdTime=" + createdTime                + ", birth=" + birth + "]";    }}

【2】多对一的持久化操作

/**     * 保存多对一时,建议先保存1的一端,后保存n的一端,这样不会多出额外的update语句     */    @Test    public void testManyToOnePersist(){        Customer customer = new Customer();        customer.setAge(18);        customer.setBirth(new Date());        customer.setCreatedTime(new Date());        customer.setEmail("gg@163.com");        customer.setLastName("GG");        Order order1 = new Order();        order1.setOrderName("G-GG-1");        Order order2 = new Order();        order2.setOrderName("G-GG-2");        //设置关联关系        order1.setCustomer(customer);        order2.setCustomer(customer);        //ִ执行保存操作        entityManager.persist(customer);        entityManager.persist(order1);        entityManager.persist(order2);    }

控制台输出如下:

Hibernate:     insert     into        JPA_CUTOMERS        (age, birth, createdTime, email, LAST_NAME)     values        (?, ?, ?, ?, ?)Hibernate:     insert     into        JPA_ORDERS        (CUSTOMER_ID, ORDER_NAME)     values        (?, ?)Hibernate:     insert     into        JPA_ORDERS        (CUSTOMER_ID, ORDER_NAME)     values        (?, ?)

即,连续三条插入语句。

如果先保存Order呢?

        //ִ执行保存操作        entityManager.persist(order1);        entityManager.persist(order2);        entityManager.persist(customer);

控制台输出如下:

Hibernate:     insert     into        JPA_ORDERS        (CUSTOMER_ID, ORDER_NAME)     values        (?, ?)Hibernate:     insert     into        JPA_ORDERS        (CUSTOMER_ID, ORDER_NAME)     values        (?, ?)Hibernate:     insert     into        JPA_CUTOMERS        (age, birth, createdTime, email, LAST_NAME)     values        (?, ?, ?, ?, ?)Hibernate:     update        JPA_ORDERS     set        CUSTOMER_ID=?,        ORDER_NAME=?     where        id=?Hibernate:     update        JPA_ORDERS     set        CUSTOMER_ID=?,        ORDER_NAME=?     where        id=?

总结如下:

保存多对一时,建议先保存1的一端,后保存n的一端,这样不会多出额外的update语句。


【3】多对一的获取操作

    //默认情况下,使用左外连接的方式来获取n的一端的对象和其关联的1的一端的对象    //可使用 @ManyToOne 的fetch 属性来修改默认的关联属性的加载策略    @Test    public void testManyToOneFind(){        Order order = entityManager.find(Order.class, 1);        System.out.println(order.getOrderName());        System.out.println(order.getCustomer().getLastName());    }

此时Order实体类中fetch为eager(默认值):

    @JoinColumn(name="CUSTOMER_ID")    @ManyToOne(fetch=FetchType.EAGER)    public Customer getCustomer() {        return customer;    }

这里写图片描述

即,默认使用左外连接方式来获取n的一端的对象和其关联的1的一端的对象。

如果将feteh属性改为lazy:

    @JoinColumn(name="CUSTOMER_ID")    @ManyToOne(fetch=FetchType.LAZEY)    public Customer getCustomer() {        return customer;    }

其控制台输出如下:

这里写图片描述


【4】多对一的删除操作

可以任意删除n的一端,但是不能随意删除1的一端,因为有外键约束。

示例如下:

    //不能直接删除1的一端,因为有外键约束    @Test    public void testManyToOneRemove(){        Order order = entityManager.find(Order.class, 6);        entityManager.remove(order);    }

这里写图片描述


如果删除1的一端将会抛出异常:

    //不能直接删除1的一端,因为有外键约束    @Test    public void testManyToOneRemove(){        Customer customer = entityManager.find(Customer.class, 4);        entityManager.remove(customer);    }

这里写图片描述


如果外键约束不存在,则可以删除1的一端:

这里写图片描述


删除一个不存在的实体,同样会抛出异常:

这里写图片描述


【5】多对一的更新操作

示例如下:

    @Test    public void testManyToOneUpdate(){        Order order = entityManager.find(Order.class, 2);        order.getCustomer().setLastName("FFF");    }

控制台输出如下:

Hibernate:     select        order0_.id as id1_1_1_,        order0_.CUSTOMER_ID as CUSTOMER3_1_1_,        order0_.ORDER_NAME as ORDER_NA2_1_1_,        customer1_.id as id1_0_0_,        customer1_.age as age2_0_0_,        customer1_.birth as birth3_0_0_,        customer1_.createdTime as createdT4_0_0_,        customer1_.email as email5_0_0_,        customer1_.LAST_NAME as LAST_NAM6_0_0_     from        JPA_ORDERS order0_     left outer join        JPA_CUTOMERS customer1_             on order0_.CUSTOMER_ID=customer1_.id     where        order0_.id=?Hibernate:     update        JPA_CUTOMERS     set        age=?,        birth=?,        createdTime=?,        email=?,        LAST_NAME=?     where        id=?
原创粉丝点击