SSH-Hibernate(4)

一.表与表之间的关系

一对一:如一个丈夫对应一个妻子;

一对多:一个班级对应多个学生(建表时在多的一方建立外键指向一的一方的主键);

多对多:一个课程对应多个学生,一个学生对应多个课程。

二.Hibernate的一对多

以客户和联系人为例

1.新建实体类

package com.lgh.entity;

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

/**
 * Created by LGH on 2018/3/10.
 */
public class Customer {
    private Integer cId;
    private String cName;
    private String cSource;
    private String cPhone;
    //一个客户对应多个联系人
    private Set<ContactMan> contactManSet=new HashSet<ContactMan>();

    public Set<ContactMan> getContactManSet() {
        return contactManSet;
    }

    public void setContactManSet(Set<ContactMan> contactManSet) {
        this.contactManSet = contactManSet;
    }

    public Integer getcId() {
        return cId;
    }

    public void setcId(Integer cId) {
        this.cId = cId;
    }

    public String getcName() {
        return cName;
    }

    public void setcName(String cName) {
        this.cName = cName;
    }

    public String getcSource() {
        return cSource;
    }

    public void setcSource(String cSource) {
        this.cSource = cSource;
    }

    public String getcPhone() {
        return cPhone;
    }

    public void setcPhone(String cPhone) {
        this.cPhone = cPhone;
    }
}


package com.lgh.entity;

/**
 * Created by LGH on 2018/3/10.
 */
public class ContactMan {
    private Integer conId;
    private String conName;
    private String conGender;
    private String conPhone;
   //多个联系人对应一个客户
    private Customer customer;

    public Customer getCustomer() {
        return customer;
    }

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

    public Integer getConId() {
        return conId;
    }

    public void setConId(Integer conId) {
        this.conId = conId;
    }

    public String getConName() {
        return conName;
    }

    public void setConName(String conName) {
        this.conName = conName;
    }

    public String getConGender() {
        return conGender;
    }

    public void setConGender(String conGender) {
        this.conGender = conGender;
    }

    public String getConPhone() {
        return conPhone;
    }

    public void setConPhone(String conPhone) {
        this.conPhone = conPhone;
    }
}

2.一对多映射配置

Customer.hbm.xml

<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.lgh.entity">
    <class name="Customer" table="customer">
        <id name="cId" column="cid">
            <generator class="native"/>
        </id>
        <property name="cName" column="cName"/>
        <property name="cPhone" column="cPhoe"/>
        <property name="cSource" column="cSource"/>
        <set name="contactManSet">
            <!--column:外键名称
            Hibernate机制:双向维护外键,在一和多的一方都要配置外键
            -->
            <key column="cid"/>
            <!--class:为多的一方的全路径-->
            <one-to-many class="ContactMan"/>
        </set>
    </class>
</hibernate-mapping>

ContactMan.hbm.xml

<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.lgh.entity">
    <class name="ContactMan" table="contactMan">
        <id name="conId" column="conId">
            <generator class="native"/>
        </id>
        <property name="conName" column="conName"/>
        <property name="conPhone" column="conPhone"/>
        <property name="conGender" column="conGender"/>
        <!--name:一的一方属性名,class:一的一方的全路径,column:外键名称-->
        <many-to-one name="customer" class="Customer" column="cid"/>
    </class>
</hibernate-mapping>

3.在核心配置文件中引入一对多映射配置文件

<mapping resource="com/lgh/entity/ContactMan.hbm.xml"/>
<mapping resource="com/lgh/entity/Customer.hbm.xml"/>

.一对多的级联操作

1.级联保存

(1)保存一个客户,为这个客户添加多个联系人

  需求:添加一个客户,为该客户添加一个联系人

方式一:

        Session session=null;
        Transaction transaction=null;
        try {
            session=HibernateUtils.getSession();
            transaction=session.beginTransaction();
            Customer c = new Customer();
            c.setcName("百度");

            ContactMan man = new ContactMan();
            man.setConName("小李");
            man.setConPhone("11111");
            c.getContactManSet().add(man);
            man.setCustomer(c);

            session.save(c);
            session.save(man);

            transaction.commit();
        }
        catch (Exception e){
            transaction.rollback();
        }
        finally {
            session.close();
        }

方式二:在一的一方添加级联操作cascade

        <set name="contactManSet" cascade="save-update">
            <!--column:外键名称
            Hibernate机制:双向维护外键,在一和多的一方都要配置外键
            -->
            <key column="cid"/>
            <!--class:为多的一方的全路径-->
            <one-to-many class="ContactMan"/>
        </set>

简化代码:

        Session session=null;
        Transaction transaction=null;
        try {
            session=HibernateUtils.getSession();
            transaction=session.beginTransaction();
            Customer c = new Customer();
            c.setcName("百度");

            ContactMan man = new ContactMan();
            man.setConName("小李");
            man.setConPhone("11111");
            c.getContactManSet().add(man);

            session.save(c);
            
            transaction.commit();
        }
        catch (Exception e){
            transaction.rollback();
        }
        finally {
            session.close();
        }

2.级联删除

(1)删除一个客户,这个客户下的所有联系人也删除

1.保留之前的级联操作在一的一方加入级联delete

 <set name="contactManSet" cascade="save-update,delete">
            <!--column:外键名称
            Hibernate机制:双向维护外键,在一和多的一方都要配置外键
            -->
            <key column="cid"/>
            <!--class:为多的一方的全路径-->
            <one-to-many class="ContactMan"/>
 </set>

示例:

        Session session=null;
        Transaction transaction=null;
        try {
            session=HibernateUtils.getSession();
            transaction=session.beginTransaction();
            Customer c = session.get(Customer.class, 4);
            
            session.delete(c);
            transaction.commit();
        }
        catch (Exception e){
            transaction.rollback();
        }
        finally {
            session.close();
        }

3.关系维护

        Session session=null;
        Transaction transaction=null;
        try {
            session=HibernateUtils.getSession();
            transaction=session.beginTransaction();
            ContactMan contactMan = session.get(ContactMan.class, 1);
            Customer customer = session.get(Customer.class, 2);
            customer.getContactManSet().add(contactMan);
            contactMan.setCustomer(customer);
            transaction.commit();
        }
        catch (Exception e){
            transaction.rollback();
        }
        finally {
            session.close();
        }

执行sql:

可见update执行了两次,是因为它进行了两次关系维护,Hibernate中默认不放弃关系维护,通过配置在一的一方放弃关系维护,inverse默认值为false,true放弃关系,这样就只更新一次

<set name="contactManSet" cascade="save-update,delete" inverse="true">
            <!--column:外键名称
            Hibernate机制:双向维护外键,在一和多的一方都要配置外键
            -->
            <key column="cid"/>
            <!--class:为多的一方的全路径-->
            <one-to-many class="ContactMan"/>
</set>

三.Hibernate的多对多

以用户和角色为例

1.新建实体类

package com.lgh.entity;

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

/**
 * Created by LGH on 2018/3/8.
 */
public class User {
    //hibernate要求实体类有一个唯一属性
    private String id;
    private String userName;
    private String password;
    //一个用户中有多个角色
    private Set<Role> roleSet=new HashSet<Role>();
   .....
}
package com.lgh.entity;

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

/**
 * Created by LGH on 2018/3/11.
 */
public class Role {
    private Integer rId;
    private String name;
    //一个角色对应多个用户
    private Set<User> userSet=new HashSet<User>();
    ...
}

2.新建配置文件

User.hbm.xml

<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.lgh.entity">
    <!--配置表和类映射关系-->
    <class name="User" table="tb_user">
        <id name="id" column="u_id">
            <generator class="native"></generator>
        </id>
        <property name="userName" column="username"/>
        <property name="password" column="password"/>
        <!--table:第三张表-->
        <set name="roleSet" table="user_role" cascade="save-update,delete">
            <!--column:当前表在第三张表中外键-->
            <key column="u_id" ></key>
            <!--另外一张表在第三张表中的id-->
            <many-to-many class="Role" column="r_id"/>
        </set>
    </class>
</hibernate-mapping>

Role.hbm.xml

<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.lgh.entity">
    <class name="Role" table="role">
        <id name="rId" column="rId">
            <generator class="native"/>
        </id>
        <property name="name" column="name"/>
        <set name="userSet" table="user_role">
            <key column="r_id"/>
            <many-to-many class="User" column="u_id"/>
        </set>
    </class>
</hibernate-mapping>

3.在核心配置文件中引入

<mapping resource="com/lgh/entity/User.hbm.xml"/>
<mapping resource="com/lgh/entity/Role.hbm.xml"/>

.添加操作

        try {
            session=HibernateUtils.getSession();
            transaction=session.beginTransaction();
            User user1 = new User();
            user1.setUserName("李");
            User user2 = new User();
            user2.setUserName("张");

            Role role1 = new Role();
            role1.setName("司机");
            Role role2 = new Role();
            role2.setName("策划");
            Role role3 = new Role();
            role2.setName("总裁");

            user1.getRoleSet().add(role1);
            user1.getRoleSet().add(role2);
            user2.getRoleSet().add(role3);

            session.save(user1);
            session.save(user2);


            transaction.commit();
        }
        catch (Exception e){
            transaction.rollback();
        }
        finally {
            session.close();
        }

在多对多中一般不用级联删除,一般通过维护第三张表

(1)让某个用户拥有某个角色













评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值