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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 指尖的舞者 于 2017-7-5 15:01 编辑

济南中心】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();
        }
【删除联系人同时级联删除客户】
        
[Java] 纯文本查看 复制代码
@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 创建映射
【用户的映射】
[Java] 纯文本查看 复制代码
<?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>

【角色的映射】
[Java] 纯文本查看 复制代码
<?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();
        }










扫码关注“黑马程序员视频库”公众号
获取更多学习资料


3 个回复

倒序浏览

回帖奖励 +1

不错,收藏学习ing
回复 使用道具 举报

回帖奖励 +1

刚上就业班或许用得着
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马