即日起在codingBlog上分享您的技术经验即可获得积分,积分可兑换现金哦。

jpa级联操作详细解析1-级联保存(CascadeType.PERSIST)

编程语言 u013036792 73℃ 0评论

不论是对于jpa或者是hibernate来说字段的数据库映射都不是难点,而是很多初学者都对jpa级联操作等一系列的东西不大明白,在这一系列的文章中我通过简单的java实体对象来与大家共同理解jpa(hibernate做实现产品)的级联操作等难点知识,希望能够共同提高。为了保证简单易懂,本系列文章避免光讲理论知识,而忽视实际动手,在下面的例子中都有简单易懂的例子,为了加深理解大家也可以在自己的机器上调试。同时为了方便理解本系列文章采用对比讲解,能让人一目了然。同时欢迎大家共同探讨,一起完善这教程


jpa级联操作详解1(cascade) 之 cascade={CascadeType.PERSIST}


onetomany 一对多关联 实体bean:汽车和车库

(一)
Java代码  收藏代码
package com.hibernate.jpa.bean1;  

import javax.persistence.Entity;  
import javax.persistence.GeneratedValue;  
import javax.persistence.Id;  
import javax.persistence.JoinColumn;  
import javax.persistence.ManyToOne;  
@Entity  
public class Auto {  

    /** 
     * one to many 一对多关联 
     */  
    private Integer autoId;  
    private String autotype;  
    private String autonum;  
    private Garage garage;  

    @Id @GeneratedValue  
    public Integer getAutoId() {  
        return autoId;  
    }  
    public void setAutoId(Integer autoId) {  
        this.autoId = autoId;  
    }  
    public String getAutotype() {  
        return autotype;  
    }  
    public void setAutotype(String autotype) {  
        this.autotype = autotype;  
    }  
    public String getAutonum() {  
        return autonum;  
    }  
    public void setAutonum(String autonum) {  
        this.autonum = autonum;  
    }  
    @ManyToOne  
    @JoinColumn(name="garageid")  
    public Garage getGarage() {  
        return garage;  
    }  
    public void setGarage(Garage garage) {  
        this.garage = garage;  
    }  

}  
------车库  
package com.hibernate.jpa.bean1;  

import java.util.HashSet;  
import java.util.Set;  

import javax.persistence.Column;  
import javax.persistence.Entity;  
import javax.persistence.GeneratedValue;  
import javax.persistence.Id;  
import javax.persistence.OneToMany;  
@Entity  
public class Garage {  

    /** 
     * many to one 多对一 
     */  
    private Integer gid;  
    private String garagenum;  
    private Set autos = new HashSet();  

    @Id @GeneratedValue  
    public Integer getGid() {  
        return gid;  
    }  
    public void setGid(Integer gid) {  
        this.gid = gid;  
    }  
    @Column(length=20)  
    public String getGaragenum() {  
        return garagenum;  
    }  
    public void setGaragenum(String garagenum) {  
        this.garagenum = garagenum;  
    }  
    @OneToMany(mappedBy="garage")  
    public Set getAutos() {  
        return autos;  
    }  
    public void setAutos(Set autos) {  
        this.autos = autos;  
    }  
    public void addGarageAuto(Auto auto) {  
        auto.setGarage(this);  
        this.autos.add(auto);  
    }  

}  
 ---------junit保存方法  
    @Test public void save() {  
        EntityManagerFactory factory = Persistence.createEntityManagerFactory("jpa-hibernate");  
        EntityManager em = factory.createEntityManager();  
        em.getTransaction().begin();  

        Garage garage = new Garage();  
        garage.setGaragenum("room1");  

        Auto auto1 = new Auto();  
        auto1.setAutonum("bj0000");  
        auto1.setAutotype("car");  

        Auto auto2 = new Auto();  
        auto2.setAutonum("bj1231");  
        auto2.setAutotype("bus");  

        garage.addGarageAuto(auto1);  
        garage.addGarageAuto(auto2);  

        em.persist(garage);  
        em.getTransaction().commit();  
        em.close();  
        factory.close();  
    }  

运行以上save()方法之后,数据库中只对应的表,但是只有garage表中被存入了数据,而auto表中没有被存入数据,仅仅是生成了表而已。


数据库中的表数据:


+—–+———–+


| gid | garagenum |


+—–+———–+


| 1 | room1 |


+—–+———–+

mysql> select * from auto;


Empty set (0.00 sec)


这儿可以注意到虽然生成了auto数据库表,但是无法存储有关auto的数据,因为没有先保存auto或设置级联保存


观察发出的sql语句:


Hibernate: insert into Garage (garagenum) values (?)

(二)先保存auto


将junit测试类中的save方法改为

@Test public void save() {
EntityManagerFactory factory = Persistence.createEntityManagerFactory("jpa-hibernate");
EntityManager em = factory.createEntityManager();
em.getTransaction().begin();

Garage garage = new Garage();
garage.setGaragenum("room1");

Auto auto1 = new Auto();
auto1.setAutonum("bj0000");
auto1.setAutotype("car");

Auto auto2 = new Auto();
auto2.setAutonum("bj1231");
auto2.setAutotype("bus");

garage.addGarageAuto(auto1);
garage.addGarageAuto(auto2);
em.persist(auto1);
em.persist(auto2);
em.persist(garage);
em.getTransaction().commit();
em.close();
factory.close();
}

观察发出的sql语句:


Hibernate: insert into Auto (autonum, autotype, garageid) values (?, ?, ?)


Hibernate: insert into Auto (autonum, autotype, garageid) values (?, ?, ?)


Hibernate: insert into Garage (garagenum) values (?)


Hibernate: update Auto set autonum=?, autotype=?, garageid=? where autoId=?


Hibernate: update Auto set autonum=?, autotype=?, garageid=? where autoId=?


当然也生成了对应的数据记录,但是对数据库进行了5次操作

mysql> select * from garage;
+-----+-----------+
| gid | garagenum |
+-----+-----------+
| 1 | room1 |
+-----+-----------+

mysql> select * from auto;
+--------+---------+----------+----------+
| autoId | autonum | autotype | garageid |
+--------+---------+----------+----------+
| 1 | bj0000 | car | 1 |
| 2 | bj1231 | bus | 1 |
+--------+---------+----------+----------+
-----------------------------------------------------------------------

(三)设置cascade={CascadeType.PERSIST}


当把


@OneToMany(mappedBy=”garage”)


public Set getAutos() {


return autos;


}


改为:


@OneToMany(cascade={CascadeType.PERSIST} ,mappedBy=”garage”)


public Set getAutos() {


return autos;


}


即多添加了一行cascade={CascadeType.PERSIST} 申明级联级联保存


删除前面生成的数据库表garage 和 auto


再次运行save()方法


这是我们看到数据库中都有对应的记录


+—–+———–+


| gid | garagenum |


+—–+———–+


| 1 | room1 |


+—–+———–+

+——–+———+———-+———-+


| autoId | autonum | autotype | garageid |


+——–+———+———-+———-+


| 1 | bj0000 | car | 1 |


| 2 | bj1231 | bus | 1 |


+——–+———+———-+———-+


观察发出的sql语句:


Hibernate: insert into Garage (garagenum) values (?)


Hibernate: insert into Auto (autonum, autotype, garageid) values (?, ?, ?)


Hibernate: insert into Auto (autonum, autotype, garageid) values (?, ?, ?)

转载请注明:CodingBlog » jpa级联操作详细解析1-级联保存(CascadeType.PERSIST)

喜欢 (0)or分享 (0)
发表我的评论
取消评论

*

表情