A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

济南中心】JavaEE就业班同步笔记第三阶段:
Hibernate-part03

1.1 表关系的分析

1.2 Hibernate关联关系:一对多的映射
1.2.1 搭建Hibernate基本开发环境
1.2.2 搭建Hibernate的一对多的关联关系映射
1.2.2.1    创建客户表和联系人表
1.2.2.2    创建实体类
【客户的实体】
[Java] 纯文本查看 复制代码
public class Customer {
    private Long cust_id;
    private String cust_name;
    private String cust_source;
    private String cust_industry;
    private String cust_level;
    private String cust_phone;
    private String cust_mobile;
   
    // 联系人的集合:
    private Set<LinkMan> linkMans = new HashSet<LinkMan>();
}

【联系人的实体】
[Java] 纯文本查看 复制代码
public class LinkMan {
    private Long lkm_id;
    private String lkm_name;
    private String lkm_gender;
    private String lkm_phone;
    private String lkm_mobile;
    private String lkm_email;
    private String lkm_qq;
    private String lkm_position;
    private String lkm_memo;
   
    // private Long lkm_cust_id;
    private Customer customer;// 联系人对应的客户的对象
}

1.2.2.3    创建映射
【联系人的映射】
[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>
    <class name="com.itheima.hibernate.domain.LinkMan" table="cst_linkman">
        <id name="lkm_id">
            <generator class="native"></generator>
        </id>
        <property name="lkm_name"/>
        <property name="lkm_gender"/>
        <property name="lkm_phone"/>
        <property name="lkm_mobile"/>
        <property name="lkm_email"/>
        <property name="lkm_qq"/>
        <property name="lkm_position"/>
        <property name="lkm_memo"/>
       
        <!-- 在多的一方配置many-to-one -->
        <!--
            many-to-one标签:用来描述多对一的关系配置。
                * name        :一的一方的对象的属性名称。
                * class        :一的一方的类的全路径
                * column    :外键的名称
         -->
        <many-to-one name="customer" class="com.itheima.hibernate.domain.Customer" column="lkm_cust_id"/>
    </class>
</hibernate-mapping>

【客户的映射】
[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>
    <class name="com.itheima.hibernate.domain.Customer" table="cst_customer">
        <id name="cust_id">
            <generator class="native"/>
        </id>
       
        <property name="cust_name"/>
        <property name="cust_source"/>
        <property name="cust_industry"/>
        <property name="cust_level"/>
        <property name="cust_phone"/>
        <property name="cust_mobile"/>
       
        <!-- 配置一对多的关联映射 -->
        <!--
            set标签:用来描述一的一方存放的多的一方的集合
                * name:多的一方的集合属性名称
        -->
        <set name="linkMans">
            <!--
                key标签:
                    * column多的一方的外键的名称
            -->
            <key column="lkm_cust_id"/>
            <!--
                one-to-many标签:描述一对多的关系
                    * class:多的一方的类的全路径
             -->
            <one-to-many class="com.itheima.hibernate.domain.LinkMan"/>
        </set>
    </class>
</hibernate-mapping>

1.2.2.4    在核心配置中加载映射

1.2.2.5    编写测试方法
   
[Java] 纯文本查看 复制代码
 @Test
    /**
     * 保存数据
     */
    public void demo1(){
        Session session = HibernateUtils.getCurrentSession();
        Transaction tx = session.beginTransaction();
       
        // 创建两个客户
        Customer customer1 = new Customer();
        customer1.setCust_name("柳岩");
        Customer customer2 = new Customer();
        customer2.setCust_name("马蓉");
       
        // 创建三个联系人
        LinkMan linkMan1 = new LinkMan();
        linkMan1.setLkm_name("梁大鹏");
        LinkMan linkMan2 = new LinkMan();
        linkMan2.setLkm_name("梁宝强");
        LinkMan linkMan3 = new LinkMan();
        linkMan3.setLkm_name("梁喆");
       
        // 建立关系:双向关系.
        customer1.getLinkMans().add(linkMan1);
        customer2.getLinkMans().add(linkMan2);
        customer2.getLinkMans().add(linkMan3);
        linkMan1.setCustomer(customer1);
        linkMan2.setCustomer(customer2);
        linkMan3.setCustomer(customer2);
       
        session.save(customer1);
        session.save(customer2);
        session.save(linkMan1);
        session.save(linkMan2);
        session.save(linkMan3);
       
        tx.commit();
    }

1.2.3 Hibernate的一对多的级联操作
1.2.3.1    级联保存或更新
级联操作:操作一个对象的时候,同时操作其关联的对象。
    级联是有方向性的,保存客户级联联系人,还是要保存联系人级联客户。
【保存客户的同时级联保存联系人】
   
[Java] 纯文本查看 复制代码
 @Test
    /**
     * 级联保存:
     *     * 保存客户同时级联保存联系人。
     *     * 保存的主体对象是客户对象,那么就需要在Customer.hbm.xml文件中配置。
     *         * 在<set>标签上配置cascade="save-update"
     */
    public void demo3(){
        Session session = HibernateUtils.getCurrentSession();
        Transaction tx = session.beginTransaction();
       
        // 创建客户
        Customer customer1 = new Customer();
        customer1.setCust_name("柳岩");
       
        // 创建联系人
        LinkMan linkMan1 = new LinkMan();
        linkMan1.setLkm_name("梁大鹏");

       
        // 建立关系:双向关系.
        customer1.getLinkMans().add(linkMan1);
        linkMan1.setCustomer(customer1);
       
       
        session.save(customer1);
       
        tx.commit();
    }

【保存联系人同时级联保存客户】
   
[Java] 纯文本查看 复制代码
@Test
    /**
     * 级联保存:
     *     * 保存联系人同时级联保存客户。
     *     * 保存的主体对象是联系人对象,那么就需要在LinkMan.hbm.xml文件中配置。
     *         * 在<many-to-one>标签上配置cascade="save-update"
     */
    public void demo4(){
        Session session = HibernateUtils.getCurrentSession();
        Transaction tx = session.beginTransaction();
       
        // 创建客户
        Customer customer1 = new Customer();
        customer1.setCust_name("马蓉");
       
        // 创建联系人
        LinkMan linkMan1 = new LinkMan();
        linkMan1.setLkm_name("烦司机");
       
        // 建立关系:双向关系.
        customer1.getLinkMans().add(linkMan1);
        linkMan1.setCustomer(customer1);
       
        session.save(linkMan1);
       
        tx.commit();
    }

1.2.3.2    测试对象导航
   
[Java] 纯文本查看 复制代码
 @Test
    /**
     * 测试对象导航
     *     * 一对多的双方都配置了cascade="save-update"
     */
    public void demo5(){
        Session session = HibernateUtils.getCurrentSession();
        Transaction tx = session.beginTransaction();
       
        // 创建1个客户和3个联系人
        Customer customer1 = new Customer();
        customer1.setCust_name("梁某");
       
        // 创建3个联系人
        LinkMan linkMan1 = new LinkMan();
        linkMan1.setLkm_name("如花");
        LinkMan linkMan2 = new LinkMan();
        linkMan2.setLkm_name("凤姐");
        LinkMan linkMan3 = new LinkMan();
        linkMan3.setLkm_name("芙蓉");
       
        // 建立了关系
        linkMan1.setCustomer(customer1);
        customer1.getLinkMans().add(linkMan2);
        customer1.getLinkMans().add(linkMan3);
       
        // session.save(linkMan1); // 发送几条insert语句? 4条
        // session.save(customer1); // 发送几条insert语句? 3条
        session.save(linkMan2); // 发送几条insert语句?1条
       
        tx.commit();
    }

1.2.3.3    级联删除
【删除客户同时级联删除联系人】
   
[Java] 纯文本查看 复制代码
 @Test
    /**
     * 级联删除:
     *     * 删除客户同时级联删除联系人。
     *     * 在Customer.hbm.xml中的<set>上配置cascade="delete"
     */
    public void demo7(){
        Session session = HibernateUtils.getCurrentSession();
        Transaction tx = session.beginTransaction();
       
        // 删除2号客户
        Customer customer = session.get(Customer.class, 2l);
        session.delete(customer);
       
        tx.commit();
    }
【删除联系人同时级联删除客户】
    @Test
    /**
     * 级联删除:
     *     * 删除联系人同时级联删除客户。
     *     * 在LinkMan.hbm.xml中在<many-to-one>上配置cascade="delete"
     */
    public void demo8(){
        Session session = HibernateUtils.getCurrentSession();
        Transaction tx = session.beginTransaction();
       
        // 删除1号联系人
        LinkMan linkMan = session.get(LinkMan.class, 1l);
        session.delete(linkMan);
       
        tx.commit();
    }

1.2.4 双向维护关系产生多余的SQL
1.2.4.1    编写代码测试:
   
[Java] 纯文本查看 复制代码
 @Test
    /**
     * 双向维护关系 导致多余的SQL
     */
    public void demo9(){
        Session session = HibernateUtils.getCurrentSession();
        Transaction tx = session.beginTransaction();
       
        Customer customer = session.get(Customer.class, 1l);
        LinkMan linkMan = session.get(LinkMan.class, 2l);
       
        customer.getLinkMans().add(linkMan);
        linkMan.setCustomer(customer);
       
        tx.commit();
    }

1.2.4.2    区分cascade和inverse
  
[Java] 纯文本查看 复制代码
  @Test
    /**
     * 区分cascade和inverse
     *     * 在客户端配置cascade="save-update" inverse="true"
     */
    public void demo10(){
        Session session = HibernateUtils.getCurrentSession();
        Transaction tx = session.beginTransaction();
       
        Customer customer = new Customer();
        customer.setCust_name("高松");
       
        LinkMan linkMan = new LinkMan();
        linkMan.setLkm_name("高凤儿");
       
        customer.getLinkMans().add(linkMan);
       
        session.save(customer);
       
        tx.commit();
    }

1.3 Hibernate关联关系:多对多
1.3.1 搭建Hibernate多对多开发环境
1.3.1.1    创建实体
【用户的实体】
[Java] 纯文本查看 复制代码
public class User {
    private Long user_id;
    private String user_code;
    private String user_name;
    private String user_password;
    private String user_state;
   
    // 一个用户选择多个角色
    private Set<Role> roles = new HashSet<Role>();
}

【角色实体】
[Java] 纯文本查看 复制代码
public class Role {
    private Long role_id;
    private String role_name;
    private String role_memo;
   
    // 一个角色被多个用户选择:
    private Set<User> users = new HashSet<User>();
}

1.3.1.2    创建映射
【用户的映射】
[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>
    <class name="com.itheima.hibernate.domain.User" table="sys_user">
        <id name="user_id" >
            <generator class="native"/>
        </id>
        <property name="user_code"/>
        <property name="user_name"/>
        <property name="user_password"/>
        <property name="user_state"/>
       
        <!-- 配置多对多的映射 -->
        <!--
            set标签
                * name    :多对多另一方的集合的属性名称
                * table    :多对多建立的中间表的名称。
         -->
        <set name="roles" table="sys_user_role">
            <!--
                key标签:描述外键
                    * column:当前对象在中间表的外键的名称
             -->
            <key column="user_no"/>
            <!--
                many-to-many标签:多对多配置
                    * class:对方的类的全路径
                    * column:对方在中间表的外键名称
             -->
             <many-to-many class="com.itheima.hibernate.domain.Role" column="role_no"/>
        </set>
    </class>
</hibernate-mapping>

【角色的映射】
[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>
    <class name="com.itheima.hibernate.domain.Role" table="sys_role">
        <id name="role_id">
            <generator class="native"/>
        </id>
       
        <property name="role_name"/>
        <property name="role_memo"/>
       
        <set name="users" table="sys_user_role">
            <key column="role_no"/>
            <many-to-many class="com.itheima.hibernate.domain.User" column="user_no"/>
        </set>
    </class>
</hibernate-mapping>

1.3.1.3    在核心配置中加载映射

1.3.1.4    编写测试类:
   
[Java] 纯文本查看 复制代码
@Test
    /**
     * 保存数据:
     *     * 多对多保存的时候,需要单向关联。如果是双向关联需要有一方放弃外键维护权。
     */
    public void demo1(){
        Session session = HibernateUtils.getCurrentSession();
        Transaction tx = session.beginTransaction();
       
        // 创建2个用户
        User user1 = new User();
        user1.setUser_name("梁司机");
        User user2 = new User();
        user2.setUser_name("梁蓉");
       
        // 创建3个角色
        Role role1 = new Role();
        role1.setRole_name("司机");
        Role role2 = new Role();
        role2.setRole_name("经济人");
        Role role3 = new Role();
        role3.setRole_name("讲师");
       
        // 建立关系:
        user1.getRoles().add(role1);
        user1.getRoles().add(role3);
        user2.getRoles().add(role1);
        user2.getRoles().add(role2);
        role1.getUsers().add(user1);
        role1.getUsers().add(user2);
        role2.getUsers().add(user2);
        role3.getUsers().add(user1);
       
        session.save(user1);
        session.save(user2);
        session.save(role1);
        session.save(role2);
        session.save(role3);
        tx.commit();
    }

1.3.2 Hibernate的多对多的级联操作
1.3.2.1    级联保存或更新
【保存用户同时级联角色】
   
[Java] 纯文本查看 复制代码
 @Test
    /**
     * 保存用户同时级联角色
     * 在User.hbm.xml中的<set>上配置cascade="save-update"
     */
    public void demo2(){
        Session session = HibernateUtils.getCurrentSession();
        Transaction tx = session.beginTransaction();
       
        User user = new User();
        user.setUser_name("梁某");
       
        Role role = new Role();
        role.setRole_name("司机");
       
        user.getRoles().add(role);
        role.getUsers().add(user);
       
        session.save(user);
       
        tx.commit();
    }

【保存角色同时级联用】
   
[Java] 纯文本查看 复制代码
 @Test
    /**
     * 保存角色同时级联用户
     * 在Role.hbm.xml中的<set>上配置cascade="save-update"
     */
    public void demo3(){
        Session session = HibernateUtils.getCurrentSession();
        Transaction tx = session.beginTransaction();
       
        User user = new User();
        user.setUser_name("梁某");
       
        Role role = new Role();
        role.setRole_name("司机");
       
        user.getRoles().add(role);
        role.getUsers().add(user);
       
        session.save(role);
       
        tx.commit();
    }

1.3.2.2    级联删除(了解)
【删除用户级联删除角色】
   
[Java] 纯文本查看 复制代码
@Test
    /**
     * 删除用户同时级联删除角色
     * 在User.hbm.xml中配置cascade="delete"
     */
    public void demo4(){
        Session session = HibernateUtils.getCurrentSession();
        Transaction tx = session.beginTransaction();
       
        User user = session.get(User.class, 2l);
        session.delete(user);
       
        tx.commit();
    }

【删除角色级联删除用户】
   
[Java] 纯文本查看 复制代码
@Test
    /**
     * 删除角色同时级联删除用户
     * 在Role.hbm.xml中配置cascade="delete"
     */
    public void demo5(){
        Session session = HibernateUtils.getCurrentSession();
        Transaction tx = session.beginTransaction();
       
        Role role = session.get(Role.class, 3l);
        session.delete(role);
       
        tx.commit();
    }

1.3.3 Hibernate多对多的其他的操作:
1.3.3.1    为某个用户添加角色
   
[Java] 纯文本查看 复制代码
@Test
    /**
     * 给1号用户添加2号角色
     */
    public void demo6(){
        Session session = HibernateUtils.getCurrentSession();
        Transaction tx = session.beginTransaction();
        // 查询一号用户
        User user = session.get(User.class, 1l);
        // 查询二号角色
        Role role = session.get(Role.class, 2l);
        user.getRoles().add(role);
       
        tx.commit();
    }

1.3.3.2    为用户删除某个角色
   
[Java] 纯文本查看 复制代码
@Test
    /**
     * 给1号用户添加1号角色
     */
    public void demo7(){
        Session session = HibernateUtils.getCurrentSession();
        Transaction tx = session.beginTransaction();
        // 查询一号用户
        User user = session.get(User.class, 1l);
        // 查询一号角色
        Role role = session.get(Role.class, 1l);
        user.getRoles().remove(role);
       
        tx.commit();
    }

1.3.3.3    为用户改选角色
   
[Java] 纯文本查看 复制代码
@Test
    /**
     * 给2号用户将2号角色改为3号角色
     */
    public void demo8(){
        Session session = HibernateUtils.getCurrentSession();
        Transaction tx = session.beginTransaction();
       
        User user = session.get(User.class, 2l);
       
        Role role2 = session.get(Role.class, 2l);
        Role role3 = session.get(Role.class, 3l);
        user.getRoles().remove(role2);
        user.getRoles().add(role3);
       
        tx.commit();
    }

4 个回复

倒序浏览
回复 使用道具 举报

回帖奖励 +1

越看越觉得自己菜
回复 使用道具 举报

回帖奖励 +1


笔记做的很详细,谢谢分享
回复 使用道具 举报

笔记做的很详细,很认真``//
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马