Hibernate 中对象关系映射(ObjectRelationMapping)

1.什么是对象关系映射?

      解析:对象-关系映射Object Relational Mapping,简称ORM对象关系映射)是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。 简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将java程序中的对象自动持久化到关系数据库中。本质上就是将数据从一种形式转换到另外一种形式。

      对象和关系数据是业务实体的 两种表现形式,业务实体在内存中表现为对象,在数据库中表现为关系数据。内存中的对象之间存在关联和继承关系,而在数据库中,关系数据无法直接表达多对多 关联和继承关系。因此,对象-关系映射(ORM)系统一般以中间件的形式存在,主要实现程序对象到关系数据库数据的映射。

2.多对一的关联映射(类型表(Type)和房间表(House))

    (1)准备Type和House实体类

public class Type {
    private Integer id;
    private String name;
    
    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 class House {
    private Integer id;
    private String title;
    private Integer price;
    private String description;
    private String pubdate;
    private Integer floorage;
    private String contact;
    private Integer userid;
    private Integer streetid;
    private Type type;
  
    public Integer getPrice() {
        return price;
    }

    public void setPrice(Integer price) {
        this.price = price;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getPubdate() {
        return pubdate;
    }

    public void setPubdate(String pubdate) {
        this.pubdate = pubdate;
    }

    public Integer getFloorage() {
        return floorage;
    }

    public void setFloorage(Integer floorage) {
        this.floorage = floorage;
    }

    public String getContact() {
        return contact;
    }

    public void setContact(String contact) {
        this.contact = contact;
    }

    public Integer getUserid() {
        return userid;
    }

    public void setUserid(Integer userid) {
        this.userid = userid;
    }

    public Integer getStreetid() {
        return streetid;
    }

    public void setStreetid(Integer streetid) {
        this.streetid = streetid;
    }

    public Type getType() {
        return type;
    }

    public void setType(Type type) {
        this.type = type;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }
}

(2)书写HibernateUtil工具类    

public class HibernateUtil {
    private static final ThreadLocal<Session> thLocal=new ThreadLocal<Session>();
    private static Configuration cfg;
    private final static SessionFactory factory;
    static{
        cfg=new Configuration().configure();
        factory=cfg.buildSessionFactory();
    }
    /**
     *静态的方法  返回session
     */
    public static Session currentSession(){
        Session session = thLocal.get();
        if(session==null){
            session=factory.openSession();
            thLocal.set(session);
        }
        return session;

    }

    /**
     * 静态的方法  关闭session连接
     */
    public static void closeSession(){
        Session session = thLocal.get();
        if(session!=null){
            thLocal.set(null);
        }
        session.close();
    }
}

(3)配置Type.hbm.xml和House.hbm.xml文件

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.lex.entity">
    <class name="Type" table="TYPE">
        <id name="id" >
            <generator class="native"></generator>
        </id>
        <property name="name"></property>
        
    </class>
</hibernate-mapping>
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.lex.entity">
    <class name="House" table="HOUSE">
        <id name="id" >
            <generator class="native"></generator>
        </id>
        <property name="title"></property>
        <property name="contact"></property>
        <property name="description"></property>
        <property name="floorage"></property>
        <property name="price"></property>
        <property name="userid"></property>
        <property name="streetid"></property>
        <property name="pubdate"></property>
        <many-to-one name="type" class="cn.lex.entity.Type" column="typeid"></many-to-one>
    </class>
</hibernate-mapping>

   (4)书写测试类

     (1)第一个示例:

   /**
     *按照指定的Type类型对象,查询相关的House对象
     */
    @Test
    public void select(){
        Session session = HibernateUtil.currentSession();
        String hql="from House h where h.type.id=6";
        Query query = session.createQuery(hql);
        List<House> list = query.list();
        for (House item:list) {
            System.out.println("房间的标题:"+item.getTitle()+"	房间的类型:"+item.getType().getName());
        }
         HibernateUtil.closeSession();
    }


       (2)第二个示例:

    /**
     * 输出House集合中的所有house对象及其所关联的type对象的信息
     */
    @Test
    public void selectAll(){
        Session session = HibernateUtil.currentSession();
        String hql="from House";
        Query query = session.createQuery(hql);
        List<House> list = query.list();
        for (House house:list) {
            System.out.println("房间的标题"+house.getTitle()+"	房间的类型:"+  house.getType().getName());

        }
        HibernateUtil.closeSession();
    }

 


     (3)第三个示例:

/**
     * 修改编号为2的房间的房间类型为2
     */
    @Test
    public void update(){
        Session session = HibernateUtil.currentSession();
        //先跟踪到房间
        House house = session.load(House.class, 2);
        //跟踪到房间类型
        Type type = session.load(Type.class, 2);
        house.setType(type);
        HibernateUtil.closeSession();
    }

  3.一对多双向关联
       (1)只要在Type类中添加上一个Set<House>集合

 private Set<House> house=new HashSet<House>();

    public Set<House> getHouse() {
        return house;
    }

    public void setHouse(Set<House> house) {
        this.house = house;
    }

      (2)在Type.hbm.xml中添加上<set>元素,指定哪一方维护关联,级联。

  <set name="house" cascade="save-update" inverse="true" >
             <key column="typeid" ></key>
             <one-to-many class="cn.lex.entity.House" ></one-to-many>
  </set>

      (3)书写测试类

          (1)第一个示例:

    /**
     * 可以通过房间类型获取该部分下所有房间信息
     */
    @Test
    public void select(){
        Session session = HibernateUtil.currentSession();
        Transaction tx = session.beginTransaction();
        String hql="from Type";
        Query query = session.createQuery(hql);
        List<Type> list = query.list();
        for (Type type  :list ) {
            System.out.println("类型为"+type.getName());
            for (House house:type.getHouse() ) {
                System.out.println("房间信息:"+house.getTitle());
                System.out.println(house.getPrice());
                System.out.println(house.getContact());
                System.out.println(house.getDescription());
                System.out.println(house.getFloorage());

            }
        }
        tx.commit();
        HibernateUtil.closeSession();
    }

解析:

Hibernate: select type0_.id as id1_2_, type0_.name as name2_2_ from TYPE type0_
类型为豪华套间
Hibernate: select house0_.typeid as typeid10_0_0_, house0_.id as id1_0_0_, house0_.id as id1_0_1_, house0_.title as title2_0_1_, house0_.contact as contact3_0_1_, house0_.description as description4_0_1_, house0_.floorage as floorage5_0_1_, house0_.price as price6_0_1_, house0_.userid as userid7_0_1_, house0_.streetid as streetid8_0_1_, house0_.pubdate as pubdate9_0_1_, house0_.typeid as typeid10_0_1_ from HOUSE house0_ where house0_.typeid=?
类型为小平房
Hibernate: select house0_.typeid as typeid10_0_0_, house0_.id as id1_0_0_, house0_.id as id1_0_1_, house0_.title as title2_0_1_, house0_.contact as contact3_0_1_, house0_.description as description4_0_1_, house0_.floorage as floorage5_0_1_, house0_.price as price6_0_1_, house0_.userid as userid7_0_1_, house0_.streetid as streetid8_0_1_, house0_.pubdate as pubdate9_0_1_, house0_.typeid as typeid10_0_1_ from HOUSE house0_ where house0_.typeid=?
房间信息:简单干净
3000
黄家驹
位于小镇北面,那里环境优美,适合老人居住,配套设施齐全
50
类型为四合院
Hibernate: select house0_.typeid as typeid10_0_0_, house0_.id as id1_0_0_, house0_.id as id1_0_1_, house0_.title as title2_0_1_, house0_.contact as contact3_0_1_, house0_.description as description4_0_1_, house0_.floorage as floorage5_0_1_, house0_.price as price6_0_1_, house0_.userid as userid7_0_1_, house0_.streetid as streetid8_0_1_, house0_.pubdate as pubdate9_0_1_, house0_.typeid as typeid10_0_1_ from HOUSE house0_ where house0_.typeid=?
房间信息:让你找到古时候的感觉
6000
喵喵喵
那里环境优美,适合老人居住,配套设施齐全
550
类型为三居室
Hibernate: select house0_.typeid as typeid10_0_0_, house0_.id as id1_0_0_, house0_.id as id1_0_1_, house0_.title as title2_0_1_, house0_.contact as contact3_0_1_, house0_.description as description4_0_1_, house0_.floorage as floorage5_0_1_, house0_.price as price6_0_1_, house0_.userid as userid7_0_1_, house0_.streetid as streetid8_0_1_, house0_.pubdate as pubdate9_0_1_, house0_.typeid as typeid10_0_1_ from HOUSE house0_ where house0_.typeid=?
房间信息:通州小镇
6500
大头
优质房源--地处通州开发区繁华地段,周围配套设施齐全,肯定满足你平时的逛街购物,房间采光好,干净整洁,绝对不让你白白花钱的...
200
房间信息:临近机场高端小区
5000
川哥
优质房源--地处顺义开发区繁华地段,周围配套设施齐全,肯定满足你平时的逛街购物,房间采光好,干净整洁,绝对不让你白白花钱的...
105
类型为两居室
Hibernate: select house0_.typeid as typeid10_0_0_, house0_.id as id1_0_0_, house0_.id as id1_0_1_, house0_.title as title2_0_1_, house0_.contact as contact3_0_1_, house0_.description as description4_0_1_, house0_.floorage as floorage5_0_1_, house0_.price as price6_0_1_, house0_.userid as userid7_0_1_, house0_.streetid as streetid8_0_1_, house0_.pubdate as pubdate9_0_1_, house0_.typeid as typeid10_0_1_ from HOUSE house0_ where house0_.typeid=?
类型为一居室
Hibernate: select house0_.typeid as typeid10_0_0_, house0_.id as id1_0_0_, house0_.id as id1_0_1_, house0_.title as title2_0_1_, house0_.contact as contact3_0_1_, house0_.description as description4_0_1_, house0_.floorage as floorage5_0_1_, house0_.price as price6_0_1_, house0_.userid as userid7_0_1_, house0_.streetid as streetid8_0_1_, house0_.pubdate as pubdate9_0_1_, house0_.typeid as typeid10_0_1_ from HOUSE house0_ where house0_.typeid=?
房间信息:拆迁补贴房源
2500
坑哥
优质房源--地处昌平开发区繁华地段,周围配套设施齐全,肯定满足你平时的逛街购物,房间采光好,干净整洁,绝对不让你白白花钱的...
85
房间信息:通州优质房源
3800
刘二雄
优质房源--地处通州开发区繁华地段,周围配套设施齐全,肯定满足你平时的逛街购物,房间采光好,干净整洁,绝对不让你白白花钱的...
120
房间信息:开发区优质房源
4800
刀哥
优质房源--地处通州繁华地段,周围配套设施齐全,肯定满足你平时的逛街购物,房间采光好,干净整洁,绝对不让你白白花钱的...
86
类型为合租房
Hibernate: select house0_.typeid as typeid10_0_0_, house0_.id as id1_0_0_, house0_.id as id1_0_1_, house0_.title as title2_0_1_, house0_.contact as contact3_0_1_, house0_.description as description4_0_1_, house0_.floorage as floorage5_0_1_, house0_.price as price6_0_1_, house0_.userid as userid7_0_1_, house0_.streetid as streetid8_0_1_, house0_.pubdate as pubdate9_0_1_, house0_.typeid as typeid10_0_1_ from HOUSE house0_ where house0_.typeid=?
房间信息:朴素的小区
1500
飘哥
优质房源--地处大兴开发区繁华地段,周围配套设施齐全,肯定满足你平时的逛街购物,房间采光好,干净整洁,绝对不让你白白花钱的...
123
类型为别墅房
Hibernate: select house0_.typeid as typeid10_0_0_, house0_.id as id1_0_0_, house0_.id as id1_0_1_, house0_.title as title2_0_1_, house0_.contact as contact3_0_1_, house0_.description as description4_0_1_, house0_.floorage as floorage5_0_1_, house0_.price as price6_0_1_, house0_.userid as userid7_0_1_, house0_.streetid as streetid8_0_1_, house0_.pubdate as pubdate9_0_1_, house0_.typeid as typeid10_0_1_ from HOUSE house0_ where house0_.typeid=?
房间信息:海淀中关村便宜房源
2700
GAY达
优质房源--地处海淀开发区繁华地段,周围配套设施齐全,肯定满足你平时的逛街购物,房间采光好,干净整洁,绝对不让你白白花钱的...
145
房间信息:高端住宅
5050
凤飞飞
位于小镇南面,那里环境优美,配套设施齐全,绝对是你居家的首选
400
类型为LOFT公寓
Hibernate: select house0_.typeid as typeid10_0_0_, house0_.id as id1_0_0_, house0_.id as id1_0_1_, house0_.title as title2_0_1_, house0_.contact as contact3_0_1_, house0_.description as description4_0_1_, house0_.floorage as floorage5_0_1_, house0_.price as price6_0_1_, house0_.userid as userid7_0_1_, house0_.streetid as streetid8_0_1_, house0_.pubdate as pubdate9_0_1_, house0_.typeid as typeid10_0_1_ from HOUSE house0_ where house0_.typeid=?
房间信息:高端住宅
4000
凤飞飞
那里环境优美,交通便利,周围配套设施齐全,绝对是你居家的首选
260


     (2)第二个示例:

    /**
     * 可以通过某个房间获取该房间所在的类型
     */
    @Test
    public void select1(){
        Session session = HibernateUtil.currentSession();
        Transaction tx = session.beginTransaction();
        House house = session.load(House.class, 1);
        System.out.println(house.getType().getName());
        tx.commit();
        HibernateUtil.closeSession();
    }


     (3)第三个示例:

/**
     * 保存一个房间类型  使用级联保存房间信息  cascade
     */
    @Test
    public void add(){
        Session session = HibernateUtil.currentSession();
        Transaction tx =  session.beginTransaction();
        //先创建类型
        Type type=new Type();
        type.setName("小平房");
        //创建房间
        House house=new House();
        house.setTitle("简单干净");
        house.setDescription("位于小镇北面,那里环境优美,适合老人居住,配套设施齐全");
        house.setPrice(3000);
        house.setFloorage(50);
        house.setContact("黄家驹");
        house.setPubdate("2017-1-16");
        house.setUserid(2);
        house.setStreetid(2);
        house.setType(type);
        //关联类型和房间
        type.getHouse().add(house);
        //保存
        session.save(type);
        tx.commit();
        HibernateUtil.closeSession();
    }

    (4)第四个示例:

    /**
     * 保存一个房间类型  使用级联保存房间信息  inverse 位false
     */
    @Test
    public void add1(){
        Session session = HibernateUtil.currentSession();
        Transaction tx =  session.beginTransaction();
        //先创建类型
        Type type=new Type();
        type.setName("四合院");
        //创建房间
        House house=new House();
        house.setTitle("让你找到古时候的感觉");
        house.setDescription("位于小镇南面,那里环境优美,适合老人居住,配套设施齐全");
        house.setPrice(6000);
        house.setFloorage(550);
        house.setContact("喵喵喵");
        house.setPubdate("2017-1-16");
        house.setUserid(1);
        house.setStreetid(2);
        house.setType(type);
        //关联类型和房间
        type.getHouse().add(house);
        //保存
        session.save(type);
        tx.commit();
        HibernateUtil.closeSession();
    }

      (5)第五个示例:

   /**
     * order by 排序
     */
    @Test
    public void select2(){
        Session session = HibernateUtil.currentSession();
        Transaction tx = session.beginTransaction();
        String hql="from Type";
        Query query = session.createQuery(hql);
        List<Type> list = query.list();
        for (Type type  :list ) {
            for (House house  :type.getHouse()) {
                System.out.println(house.getId()+house.getTitle());
            }
        }
        tx.commit();
        HibernateUtil.closeSession();
    }

3.多对多单向关联(House类和Users类)

  (1)House类中添加Set<Users>集合

 Users实体类:

public class Users {
    private Integer id;
    private String name;
    private String password;
    private String telephone;
    private String username;
    private String isadmin;
   

    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 getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getTelephone() {
        return telephone;
    }

    public void setTelephone(String telephone) {
        this.telephone = telephone;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getIsadmin() {
        return isadmin;
    }

    public void setIsadmin(String isadmin) {
        this.isadmin = isadmin;
    }
}
 private Set<Users> users=new HashSet<Users>();

    public Set<Users> getUsers() {
        return users;
    }

    public void setUsers(Set<Users> users) {
        this.users = users;
    }

   (2)在House.hbm.xml中添加<set>元素

<set name="users" table="PROHOUSE" inverse="true">
            <key column="RHOUSEID"></key>
            <many-to-many class="cn.lex.entity.Users" column="PROID"></many-to-many>
 </set>

    (3)测试:

 /**
     * 多对多单向关联
     */
    @Test
    public  void add(){
        Session session = HibernateUtil.currentSession();
        Transaction tx = session.beginTransaction();
        //创建用户
        Users users=new Users();
        users.setName("奈克");
        users.setPassword("000120");
        users.setTelephone("2131313213");
        users.setUsername("DDS");
        users.setIsadmin("0");

        //创建房子
        House house=new House();
        house.setTitle("高端住宅");
        house.setDescription("位于小镇南面,那里环境优美,配套设施齐全,绝对是你居家的首选");
        house.setPrice(5050);
        house.setFloorage(400);
        house.setContact("凤飞飞");
        house.setPubdate("2017-1-14");
        house.setUserid(1);
        house.setStreetid(3);

        House house2=new House();
        house2.setTitle("高端住宅");
        house2.setDescription("那里环境优美,交通便利,周围配套设施齐全,绝对是你居家的首选");
        house2.setPrice(4000);
        house2.setFloorage(260);
        house2.setContact("凤飞飞");
        house2.setPubdate("2017-1-06");
        house2.setUserid(5);
        house2.setStreetid(1);

        //关联关系
        users.getHouse().add(house);
        users.getHouse().add(house2);
        session.save(users);
        tx.commit();
        HibernateUtil.closeSession();
    }

4.多对多双向关联
   (1)在Users类中添加Set<House>集合

private Set<House> house=new HashSet<House>();
public Set<House> getHouse() {     return house; }
public void setHouse(Set<House> house) {     this.house = house; }

   (2)在Users.hbm.xml中添加<set>元素

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.lex.entity">
    <class name="Users" table="USERS">
        <id name="id" >
            <generator class="native"></generator>
        </id>
        <property name="name"></property>
        <property name="username"></property>
        <property name="password"></property>
        <property name="isadmin"></property>
        <property name="telephone"></property>
        <set name="house" cascade="save-update" table="PROHOUSE">
            <key column="PROID"></key>
            <many-to-many class="cn.lex.entity.House" column="RHOUSEID"></many-to-many>
        </set>

    </class>
</hibernate-mapping>

   (3)测试类:

 /**
     * 多对多双向关联
     */

    @Test
    public void add1(){
        Session session = HibernateUtil.currentSession();
        Transaction tx = session.beginTransaction();
        //创建用户
        Users users=new Users();
        users.setName("娜娜");
        users.setPassword("123456");
        users.setTelephone("1111111111");
        users.setUsername("噜啦啦");
        users.setIsadmin("0");

        //创建房子
        House house=new House();
        house.setTitle("普通住宅");
        house.setDescription("位于小镇南面,那里环境优美,配套设施齐全,绝对是你居家的首选");
        house.setPrice(1000);
        house.setFloorage(400);
        house.setContact("飞飞");
        house.setPubdate("2017-01-01");
        house.setUserid(2);
        house.setStreetid(6);

        House house2=new House();
        house2.setTitle("高端住宅");
        house2.setDescription("那里环境优美,交通便利,周围配套设施齐全,绝对是你居家的首选");
        house2.setPrice(4000);
        house2.setFloorage(260);
        house2.setContact("凤飞飞");
        house2.setPubdate("2017-1-06");
        house2.setUserid(5);
        house2.setStreetid(1);

        //关联关系
       users.getHouse().add(house);
       house.getUsers().add(users);
       session.save(users);
        tx.commit();
        HibernateUtil.closeSession();
    }

看完了,就去实践一下吧,巩固最重要,后续会继续书写......

 

 

  

原文地址:https://www.cnblogs.com/wl0000-03/p/6289665.html