Hibernate -- 映射实体关联关系(一对多关联关系)

以客户和订单之间的关系为例

客户表为t_customers,订单表为t_orders
选择t_orders为主表, t_customers为从表

1.编写实体类 Orders

/**
 * Hibernate的注解类包名为javax.persistence
 */

@Entity                   // 将一个Java类声明为一个POJO类(实体类)
@Table(name = "t_orders") //声明了该实体映射所指定的表,该类属性name指定表名
public class Orders implements java.io.Serializable {

    private Integer oid;
    private String oname;
    private String oprice;

    private Customers customer;// 持有一个客户对象,在many端持有one端对象

    public Orders() {

    }

    public Orders(String oname, String oprice) {
        this.oname = oname;
        this.oprice = oprice;
    }


    @Id   //声明了该实体的标识属性,该属性对应表中的主键
    @GeneratedValue(strategy = GenerationType.IDENTITY)//声明了主键的生成策略,该注解的strategy属性指定了主键生成策略,默认值为GenerationType.AUTO  GenerationType.IDENTITY, 对于MySQL、SQL Server这样的数据库选择自增长的注解生成策略
    @Column(name = "oid")  //声明了属性到列的映射
    public Integer getOid() {
        return oid;
    }

    public void setOid(Integer oid) {
        this.oid = oid;
    }

    @Column(name = "o_name")
    public String getOname() {
        return oname;
    }

    public void setOname(String oname) {
        this.oname = oname;
    }

    @Column(name = "o_price")
    public String getOprice() {
        return oprice;
    }

    public void setOprice(String oprice) {
        this.oprice = oprice;
    }

    @ManyToOne(fetch = FetchType.LAZY, targetEntity = Customers.class, cascade = CascadeType.ALL)
    @JoinColumn(name = "cid") //为了映射外键列的信息,需要在外键列所对应的实体定义@JoinColumn注解,name为指定该外键列的列名
    public Customers getCustomer() {
        return customer;
    }

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

}

2.编写实体类 Customers

@Entity
@Table(name = "t_customers")
public class Customers implements java.io.Serializable {

    private Integer cid;
    private String cname;
    private String ctel;
    private String carea;

    private Set<Orders> ords = new HashSet<Orders>();// 在one方,加入多方的集合,必须set类型。


    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "cid")
    public Integer getCid() {
        return cid;
    }

    public void setCid(Integer cid) {
        this.cid = cid;
    }

    @Column(name = "c_name")
    public String getCname() {
        return cname;
    }

    public void setCname(String cname) {
        this.cname = cname;
    }

    @Column(name = "c_tel")
    public String getCtel() {
        return ctel;
    }

    public void setCtel(String ctel) {
        this.ctel = ctel;
    }

    @Column(name = "c_area")
    public String getCarea() {
        return carea;
    }

    public void setCarea(String carea) {
        this.carea = carea;
    }

    @OneToMany(mappedBy = "customer", cascade = CascadeType.ALL, fetch = FetchType.LAZY, 
    targetEntity = Orders.class)  // mappedBy属性指定关联对象的属性名,表明由对方Order维护关联关系
    public Set<Orders> getOrds() {
        return ords;
    }

    public void setOrds(Set<Orders> ords) {
        this.ords = ords;
    }

}

3.编写测试文件 DemoOneToMany

public class DemoOneToMany {

    public static void main(String[] args) {

        savess();
        System.out.println("操作成功!");
    }

    private static void savess() {
        Session s = HibernateSessionFactory.getSession();// 建立会话工厂,获得会话!

        Transaction t = s.beginTransaction();// 事务。事务的四大特性:原子性,一致性,隔离性,持久性

        Customers c = new Customers();
        c.setCname("马超");
        c.setCtel("13223587890");
        c.setCarea("三国时代");

        Orders o1 = new Orders();
        o1.setOname("冰洁羽绒服");
        o1.setOprice("788");
        o1.setCustomer(c);

        Orders o2 = new Orders();
        o2.setOname("意尔康皮鞋");
        o2.setOprice("380");
        o2.setCustomer(c);

        o1.setCustomer(c);
        o2.setCustomer(c);

        s.persist(o1);
        s.persist(o2);

        t.commit();
        s.close();

    }
}

4.配置文件

这里写图片描述

5.知识点汇总

  • 如果没有在属性上添加@Column,则表明该属性所映射字段的名称与其同名 注解既可放在属性上,也可放在属性的getter方法上。

  • cascade指定对关联实体所采用的级联策略,该级联策略支持如下五个属性值:
    CascadeType.ALL包含所有;
    CascadeType.PERSIST只有A类新增时,会级联B对象新增。若B对象在数据库存(跟新)在则抛异常(让B变为持久态)
    CascadeType.MERGE指A类新增或者变化,会级联B对象(新增或者变化)
    CascadeType.REFRESH级联保存:当多个用户同时作操作一个实体,为了用户取到的数据是实时的,在用实体中的数据之前就可以调用一下refresh()方法

  • 指定抓取关联实体时的抓取策略,该属性支持以下两个属性值:
    FetchType.EAGER:抓取实体时,立即抓取关联实体,这是默认值
    FetchType.LAZY:抓取实体时,延迟抓取关联实体,等到真正用到关联实体时才去抓取

  • 由于在@ManyToOne中设置了cascade=CascadeType.All,所以当保存
    Order实体时将级联保存它的Customer关联实体

  • hibernate 之所以提供与save()功能几乎完全类似的persist()方法,一方面是为了照顾JPA的用法习惯。
    另一方面,save()和 persist()方法还有一个区别: 使用 save()
    方法保存持久化对象时,该方法返回该持久化对象的标识属性值(即对应记录的主键值); 但使用 persist()
    方法来保存持久化对象时,该方法没有任何返回值。 因为 save() 方法需要立即返回持久化对象的标识属性,所以程序执行 save()
    会立即将持久化对象对应的数据插入数据库; 而 persist() 则保证当它在一个事物外部被调用时,并不立即转换成 insert 语句,
    这个功能是很有用的,尤其当我们封装一个长会话流程的时候,persist() 方法就显得尤为重要了。

    主要内容区别:
    1,persist把一个瞬态的实例持久化,但是并”不保证”标识符(identifier主键对应的属性)被立刻填入到持久化实例中,标识符的填入可能被推迟到flush的时候。
    2,save, 把一个瞬态的实例持久化标识符,及时的产生,它要返回标识符,所以它会立即执行Sql insert

6.小秘籍

  • 一对多,在many方实体类(如order)中需要定义一个one方属性,而在one方实体类无须存放many方对象集合属性。

  • 一对多,维护权在many方,配置注解 @ManyToOne(fetch = FetchType.LAZY, targetEntity = Customers.class, cascade = CascadeType.ALL) @JoinColumn(name = “cid”)

    则one方配置注解 @OneToMany(mappedBy = “customer”, cascade = CascadeType.ALL, fetch = FetchType.EAGER, targetEntity = Orders.class)

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值