JPA--一对多和多对多

一对多

需求分析:

    有客户Customer和房子Houst两个实体类,每个客户可以有多个房子,一个房子属于一个客户

  客户是一的一方,房子是多的一方。

  jpa_customer是主表,jpa_houst是从表

代码实现

1.编写实体类

客户Customer类

package com.domain;

import org.hibernate.annotations.Target;

import javax.persistence.*;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

/**
 * 客户实体类
 * 使用注解时JPA规范,所以导包都需要导入javax.persistence下的包
 */
@Entity  //表明当前类是一个实体类
@Table(name = "jpa_customer")  //建立与数据库表之间的联系
public class Customer implements Serializable {
    @Id //表明当前字段是主键
    @Column(name = "c_id")  //对应数据库中的字段名
    @GeneratedValue(strategy =GenerationType.IDENTITY ) //使用JAP中的主键生成策略
    private Integer id;
    @Column(name = "c_name")
    private String name;
    @Column(name = "c_lovel")
    private String lovel;

    //一对多关系,少的一方,一个客户多所房子
    // @OneToMany:注释一的一方;targetEntity:目标类;mappedBy:放弃控制,参数为对方属性类get方法的参数。
    @OneToMany(targetEntity = House.class,mappedBy = "customer")
    private Set<House> houses=new HashSet<House>(0);

    public Set<House> getHouses() {
        return houses;
    }

    public void setHouses(Set<House> houses) {
        this.houses = houses;
    }

    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;
    }

    public String getLovel() {
        return lovel;
    }

    public void setLovel(String lovel) {
        this.lovel = lovel;
    }

    public Customer(String name, String lovel) {
        this.name = name;
        this.lovel = lovel;
    }

    public Customer() {
    }

    public Customer(Integer id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public String toString() {
        return "Customer [id=" + id + ", name=" + name + ", lovel=" + lovel + "]";
    }

}

Houst类

package com.domain;

import javax.persistence.*;
import java.io.Serializable;

@Entity
@Table(name = "jpa_house")
public class House implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name ="h_id")
    private Integer hId;
    @Column(name ="h_iddress")
    private String hIddress;
    @Column(name ="h_price")
    private Double hPrice;

    //一对多,多的一方
    //@ManyToOne 多的一方;
    //JoinColumn加入外键列   referencedColumnName对应主表的列
    @ManyToOne(targetEntity = Customer.class)
    @JoinColumn(name = "h_c_id",referencedColumnName = "c_id")
    private Customer customer;

    @Override
    public String toString() {
        return "House{" +
                "hId=" + hId +
                ", hIddress='" + hIddress + '\'' +
                ", hPrice=" + hPrice +
                ", customer=" + customer +
                '}';
    }

    public Customer getCustomer() {
        return customer;
    }

    public void setCustomer(Customer customer) {
        this.customer = customer;
    }

    public Integer gethId() {
        return hId;
    }

    public void sethId(Integer hId) {
        this.hId = hId;
    }

    public String gethIddress() {
        return hIddress;
    }

    public void sethIddress(String hIddress) {
        this.hIddress = hIddress;
    }

    public Double gethPrice() {
        return hPrice;
    }

    public void sethPrice(Double hPrice) {
        this.hPrice = hPrice;
    }

}

2.运行生成数据库表

3.测试

保存测试

    //保存操作
    //需求:实现锁房子属于同一客户
    @Test
    public void Test01(){
        //1.获取EntityManager
        EntityManager em= JPAUtils.createEntityManager();
        //2.获取事务开启事务
        EntityTransaction tx = em.getTransaction();
        tx.begin();
        //3.创建客户和房子类
        Customer c1=new Customer();
        c1.setName("袁绍");
        House h1=new House();
        House h2=new House();
        h1.sethIddress("幽州");
        h2.sethIddress("豫州");
        //4.将房子添加给客户
        c1.getHouses().add(h1);
        c1.getHouses().add(h2);
        //5.将客户添加给房子
        h1.setCustomer(c1);
        h2.setCustomer(c1);
        //6.执行保存
        em.persist(c1);
        em.persist(h1);
        em.persist(h2);
        //释放资源
        tx.commit();
        em.close();
    }

更新测试

//更新操作
    //需求:实现锁房子属于同一客户
    @Test
    public void Test02(){
        //1.获取EntityManager
        EntityManager em= JPAUtils.createEntityManager();
        //2.获取事务开启事务
        EntityTransaction tx = em.getTransaction();
        tx.begin();
        //获取一个客户
        Customer customer = em.find(Customer.class, 5);
        //给客户一个房子
        House h1=new House();
        h1.sethIddress("北魏");
        customer.getHouses().add(h1); //快照机制自动保存
        //将房子属性设给客户
        h1.setCustomer(customer);
        //执行操作
        //em.merge(customer);
        em.persist(h1);
        //释放资源
        tx.commit();
        em.close();
    }

级联删除测试

修改修改数据库表的数据库级联删除为空

//一对多关系,少的一方,一个客户多所房子
// @OneToMany:注释一的一方;targetEntity:目标类;mappedBy:放弃控制,参数为对方属性类get方法的参数。
//cascade = CascadeType.REMOVE,级联删除 CascadeType.PERSIST不级联删除
@OneToMany(targetEntity = House.class,mappedBy = "customer",cascade = CascadeType.PERSIST)
private Set<House> houses=new HashSet<House>(0);
 //删除操作
    @Test
    public void Test03(){
        //1.获取EntityManager
        EntityManager em= JPAUtils.createEntityManager();
        //2.获取事务开启事务
        EntityTransaction tx = em.getTransaction();
        tx.begin();
        //获取一个客户
        Customer customer = em.find(Customer.class, 4);
        em.remove(customer);

        //释放资源
        tx.commit();
        em.close();
    }

查询测试

 //查询操作
    @Test
    public void Test04(){
        //1.获取EntityManager
        EntityManager em= JPAUtils.createEntityManager();
        //2.获取事务开启事务
        EntityTransaction tx = em.getTransaction();
        tx.begin();
        //获取一个客户
        Customer customer = em.find(Customer.class, 7);
        System.out.println(customer);
     //获取客户关联的所有房子 Set
<House> houses = customer.getHouses(); for (House house : houses) { System.out.println(house); } //释放资源 tx.commit(); em.close(); }

 

多对多

需求分析:

  房子类House对应家具类Furniture

  一个房子有多种家具,一个家具可以为多种房子所有

  jpa_houst表和furniture表

代理示例:

1.创建实体类

House类

package com.domain;

import org.hibernate.annotations.GenericGenerator;

import javax.persistence.*;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

@Entity
@Table(name = "jpa_house")
public class House implements Serializable {

    @Id
    @GenericGenerator(name = "uuid",strategy = "uuid")
    @GeneratedValue(generator = "uuid",strategy = GenerationType.IDENTITY)
    @Column(name ="h_id")
    private Integer hId;
    @Column(name ="h_iddress")
    private String hIddress;
    @Column(name ="h_price")
    private Double hPrice;

    //一对多,多的一方
    //@ManyToOne 多的一方;
    //JoinColumn加入外键列   referencedColumnName对应主表的列
    @ManyToOne(targetEntity = Customer.class)
    @JoinColumn(name = "h_c_id",referencedColumnName = "c_id")
    private Customer customer;

    //多对多
    @ManyToMany
    //加入一张表,name表明,joinColumns = {@JoinColumnpei配置本类在表的列,inverseJoinColumns = {@JoinColumn对方列配置,放弃床表的类
    @JoinTable(name = "jpa_house_furniture",joinColumns = {@JoinColumn(name="h_id",referencedColumnName = "h_id")},
        inverseJoinColumns = {@JoinColumn(name="f_id",referencedColumnName = "f_id")}
    )
    private Set<Furniture> furnitures =new HashSet<Furniture>(0);


    @Override
    public String toString() {
        return "House{" +
                "hId=" + hId +
                ", hIddress='" + hIddress + '\'' +
                ", hPrice=" + hPrice +
                ", customer=" + customer +
                ", furnitures=" + furnitures +
                '}';
    }

    public Set<Furniture> getFurnitures() {
        return furnitures;
    }

    public void setFurnitures(Set<Furniture> furnitures) {
        this.furnitures = furnitures;
    }

    public Customer getCustomer() {
        return customer;
    }

    public void setCustomer(Customer customer) {
        this.customer = customer;
    }

    public Integer gethId() {
        return hId;
    }

    public void sethId(Integer hId) {
        this.hId = hId;
    }

    public String gethIddress() {
        return hIddress;
    }

    public void sethIddress(String hIddress) {
        this.hIddress = hIddress;
    }

    public Double gethPrice() {
        return hPrice;
    }

    public void sethPrice(Double hPrice) {
        this.hPrice = hPrice;
    }

}

 

Furniture类

package com.domain;

import org.hibernate.annotations.GenericGenerator;

import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;

@Entity
@Table(name = "jpa_furnitrue")
public class Furniture {
    @Id
    @Column(name = "f_id")
    //生成主键的生成器,name给生成器取名,strategy hibernata的生成策略
    @GenericGenerator(name = "uuid",strategy = "uuid")
    @GeneratedValue(generator = "uuid")
    private Integer fId;
    @Column(name = "f_name")
    private String fName;
    @Column(name = "f_price")
    private Double fPrice;

    @ManyToMany(mappedBy = "furnitures")
    private Set<House> houses =new HashSet<House>(0);

    public Integer getfId() {
        return fId;
    }

    public void setfId(Integer fId) {
        this.fId = fId;
    }

    public String getfName() {
        return fName;
    }

    public void setfName(String fName) {
        this.fName = fName;
    }

    public Double getfPrice() {
        return fPrice;
    }

    public void setfPrice(Double fPrice) {
        this.fPrice = fPrice;
    }

    @Override
    public String toString() {
        return "Furniture{" +
                "fId=" + fId +
                ", fName='" + fName + '\'' +
                ", fPrice=" + fPrice +
                ", houses=" + houses +
                '}';
    }

    public Set<House> getHouses() {
        return houses;
    }

    public void setHouses(Set<House> houses) {
        this.houses = houses;
    }
}

2.测试

添加

 //保存操作
    //需求:实现锁多所房子里面有多种家具
    @Test
    public void Test01(){
        //1.获取EntityManager
        EntityManager em= JPAUtils.createEntityManager();
        //2.获取事务开启事务
        EntityTransaction tx = em.getTransaction();
        tx.begin();
        //3.创建房子和家具对象
        House h1=new House("81房");
        House h2=new House("82房");
        Furniture f1=new Furniture("双人床");
        Furniture f2=new Furniture("桌子");
        Furniture f3=new Furniture("担任床");
        //4.将家电给房子
        h1.getFurnitures().add(f1);
        h1.getFurnitures().add(f2);
        h1.getFurnitures().add(f3);
        h2.getFurnitures().add(f1);
        h2.getFurnitures().add(f3);
        //5.将房子给家电
        f1.getHouses().add(h1);
        f1.getHouses().add(h2);
        f2.getHouses().add(h1);
        f3.getHouses().add(h1);
        f3.getHouses().add(h2);
        //6.执行保存操作
        //级联保存可以在属性上面配置  @ManyToMany(cascade = CascadeType.ALL)
        em.persist(h1);
//        em.persist(h2);
//        em.persist(f1);
//        em.persist(f2);
//        em.persist(f3);
        //释放资源
        tx.commit();
        em.close();
    }

删除

//删除操作 ;级联删除一般不允许用
    @Test
    public void Test02(){
        //1.获取EntityManager
        EntityManager em= JPAUtils.createEntityManager();
        //2.获取事务开启事务
        EntityTransaction tx = em.getTransaction();
        tx.begin();
        Furniture furniture = em.find(Furniture.class, "402881e870b9a6af0170b9a6b26f0004");
        em.remove(furniture);
        //释放资源
        tx.commit();
        em.close();
    }

 查询

//查询操作
    @Test
    public void test03(){
        EntityManager em= JPAUtils.createEntityManager();
        EntityTransaction tx = em.getTransaction();
        tx.begin();
        //先查询一个对象
        Customer c1=em.find(Customer.class,1);
        System.out.println(c1.getName());
        //再查询对象的所有房子
        Set<House> houses = c1.getHouses();
        for (House house : houses) {
            System.out.println(house.gethIddress());
            //再根据每个房子查询对应的家具
            for (Furniture f : house.getFurnitures()) {
                System.out.println(f.getfName());
            }
        }
        tx.commit();
        em.close();

    }

查询输出结果

Hibernate: select customer0_.c_id as c_id1_0_0_, customer0_.c_lovel as c_lovel2_0_0_, customer0_.c_name as c_name3_0_0_ from jpa_customer customer0_ where customer0_.c_id=?
曹操
Hibernate: select houses0_.h_c_id as h_c_id4_2_0_, houses0_.h_id as h_id1_2_0_, houses0_.h_id as h_id1_2_1_, houses0_.h_c_id as h_c_id4_2_1_, houses0_.h_iddress as h_iddres2_2_1_, houses0_.h_price as h_price3_2_1_ from jpa_house houses0_ where houses0_.h_c_id=?
蜀国
Hibernate: select furnitures0_.h_id as h_id1_3_0_, furnitures0_.f_id as f_id2_3_0_, furniture1_.f_id as f_id1_1_1_, furniture1_.f_name as f_name2_1_1_, furniture1_.f_price as f_price3_1_1_ from jpa_house_furniture furnitures0_ inner join jpa_furnitrue furniture1_ on furnitures0_.f_id=furniture1_.f_id where furnitures0_.h_id=?
担任床
双人床
北魏
Hibernate: select furnitures0_.h_id as h_id1_3_0_, furnitures0_.f_id as f_id2_3_0_, furniture1_.f_id as f_id1_1_1_, furniture1_.f_name as f_name2_1_1_, furniture1_.f_price as f_price3_1_1_ from jpa_house_furniture furnitures0_ inner join jpa_furnitrue furniture1_ on furnitures0_.f_id=furniture1_.f_id where furnitures0_.h_id=?
桌子
担任床
双人床

posted @ 2020-03-08 17:11  Jason–json  阅读(567)  评论(0编辑  收藏  举报