hibernate关系映射管理(一对多,多对一,一对一,多对多)

来源:互联网 发布:mac 用户主目录在哪里 编辑:程序博客网 时间:2024/06/04 22:51

1、什么是关系映射

所谓的关系映射指的是数据库表与表之间的关联关系,通常我们会把表之间的关系总结为4种,一对一,一对多,多对一,多对多。 这里面我们数据库通常是通过外键和关联表来进行表示的。而对于我们hiberante来说,也需要通过相应的配置去管理这种关系。
我们hibernate通过这种能表现关联关系的配置去创建表的时候,就可以在表结构上把这种关联关系给创建出来

1、一对多
首先我们先理解一对多的什么意思,在数据库A表上的一条数据,可以映射B表的多条数据库,也就是站在A表的角度,就被B表的都跳数据引用,
hiberante就认为A表拥有一个B表的集合,所以配置如下

 package com.xingxue.entity;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;//关联我们的表@Entity  //该类被hibernate当做实体给管理@Table(name="xx_plat_role")   //对应数据库的表public class Role {    @Id         //配置主键    @GeneratedValue(strategy=GenerationType.IDENTITY)  //自增策略    @Column(name="role_id")  //关联字段名和数据类型    private int id;    @Column(name="role_name")  //关联字段名和数据类型    private String name;    @Column(name="role_status")  //关联字段名和数据类型    private String status;    @Column(name="createdate", columnDefinition="DATETIME")  //关联字段名和数据类型    private Date createdate;    @OneToMany   //一对多配置,    @JoinColumn(name="admin_role")  // 外键的名字    private Set<Admin> admins = new HashSet<Admin>();}

此处一对多配置,只配置1端,多端不用管理,所以Admin不需要任何配置
测试代码:

public boolean add(Admin param, int roleId) {        Session session = this.sessionFactory.openSession();        //开启事务        Transaction t = session.beginTransaction();        //get我们的role对象,让hibernate管理起来        Role role = (Role) session.get(Role.class, roleId);        //关联role和admin的关系        role.getAdmins().add(param);        int result = (Integer) session.save(param);        //提交事务        t.commit();        //关闭回话        session.close();        return result > 0;    }  

结果如下
这里写图片描述

根据测试结果我们发现,如果我们想要关联两张表的关系,:
1、hibernate配置了关联关系
2、当操作数据的时候,两个关联对象被hibernate管理起来,
3、两个对象之间必须建立关联关系

查询数据测试

@Override    public List<Role> list() {        Session session = this.sessionFactory.openSession();        String SQL = "select * from xx_plat_role";        List<Role> list = session.createSQLQuery(SQL).addEntity(Role.class).list();        return list;    }

结果如下:
这里写图片描述
我们发现在查询role的时候,实际上hibernate自动帮我们查询了当前role下面的所有admin信息,并且封装到了set里面,也就是数据已经包装好了。省去了我们以前的链接查询的操作。
但是通过测试我们发现,在查admin的时候没有把admin相关的role给查询出来,那是因为admin没有配置映射关系,多对一,所以admin无效果,

懒加载设置
其实有的时候我们不需要查询admin信息,所以关联数据hiberante默认使用懒加载机制,所谓的懒加载就是我们需要使用这个数据他 才去查询,你不使用,H就不查询,但是必须建立在session不关闭的情况下,

    @OneToMany(fetch=FetchType.EAGER)   //没有懒加载,    @OneToMany(fetch=FetchType.LAZY)   //使用懒加载,

由于不使用懒加载效率很低,所以我们默认都使用懒加载,如果在dao有需要进行关联数据加载,建议手动用代码访问一下关联数据

2、多对一

多对一实际上就是和一对多站的角度不一样,表之间的关系,如果是一对多,我们换个角度就是多对一,所以一般一对多和多对一都是双向关联配置,还是Admin和role为例
站在admin的角度多对一:

@Table(name="xx_plat_admin")public class Admin {    @Id    @GeneratedValue(strategy=GenerationType.IDENTITY)    @Column(name="admin_id")    private int id;    @Column(name="admin_username",length=20)    private String userName;    @Column(name="admin_pwd",length=20)    private String pwd;    @ManyToOne    @JoinColumn(name="admin_role")    private Role role;
@Entity  //该类被hibernate当做实体给管理@Table(name="xx_plat_role")   //对应数据库的表public class Role {    @Id         //配置主键    @GeneratedValue(strategy=GenerationType.IDENTITY)  //自增策略    @Column(name="role_id")  //关联字段名和数据类型    private int id;    @Column(name="role_name")  //关联字段名和数据类型    private String name;    @Column(name="role_status")  //关联字段名和数据类型    private String status;    @Column(name="createdate", columnDefinition="DATETIME")  //关联字段名和数据类型    private Date createdate;    @OneToMany(mappedBy="role", fetch=FetchType.LAZY)   //一对多配置,    private Set<Admin> admins = new HashSet<Admin>();

双向关联是如上配置, 同时需要注意的是,此种配置,我们的关系管理就交给了多端来进行管理了。
所以代码如下:

@Override    public boolean add(Admin param, int roleId) {        Session session = this.sessionFactory.openSession();        //开启事务        Transaction t = session.beginTransaction();        //get我们的role对象,让hibernate管理起来        Role role = (Role) session.get(Role.class, roleId);        //关联role和admin的关系//      role.getAdmins().add(param);        param.setRole(role);        int result = (Integer) session.save(param);        //提交事务        t.commit();        //关闭回话        session.close();        return result > 0;    }

多对一默认不是用懒加载,如果需要使用。需要手动开启

@ManyToOne(fetch=FetchType.LAZY)

所以我们双向关联和单项关联有很多的区别,但是开发当中常用双向关联。

阅读全文
0 0
原创粉丝点击