zoukankan      html  css  js  c++  java
  • Hibernate day03

    本节内容:

    1.表与表之间的关系

      一对一

     多对多

    2.hibernate一对多操作

      一对多映射配置

    一对多联级保存

    一对多联级删除

    inverse属性

    3.hibernate多对多操作

    多对多映射配置

    多对对联级保存

    多对多联级删除

    维护第三张表

    一、表与表之间的关系

          订单表  orders

          商品表  shop

         订单明细表 orderdetail

          用户表  user

         表关系分析

        hibernate实现了ORM思想,将关系数据库中表的数据映射成对象,使开发人员把对数据库的操作转化为对对象的操作,Hibernate的关联关系映射主要包括多表的映射配置,数据的增加。删除等。

    数据库表之间存在着三种关系:

    从图中可以看出,系统设计的三种实体关系分别为:多对多、一对多、和一对一关系,在数据库中,实体表之间的关系是采用外键关系来描述的

    表与表之间的3中关系

    一对多:  用户表与订单表他们拥有相同的字段用户id,建表原则:在多的一方创建外键指向一的一方的主键

    多对多:订单表与商品表,一个订单有多个商品,一个商品属于多个订单,建表原则:创建一个中间表,中间表至少2个字段作为外键分别指向多对多双方的主键。

    一对一: 建表原则:唯一外键对应,假设一对一的任意一方为多,在多的一方创建外键指向一的一方的主键,然后将外键设置为唯一。一方的主键作为另一方的主键。

    数据库表能够描述的实体数据之间的关系,通过对象也可以进行描述,所谓的关系映射,就是将关联关系 映射到数据库,在对象模型中就是一个或者多个引用。在hibernate中

    采用java对象关系映射来描述数据表之间的关系,

    二、hibernate中一对多操作

         hibernate的一对多关系映射

        表的创建:客户表  联系人表

    创建实体类:

       客户实体类:

    public class Customer {
        //客户id
        private Integer cid;
        //客户名称
        private String custName;
        //客户级别
        private String custLevel;
        //客户来源
        private String custSource;
        //联系电话
        private String custPhone;
        //手机
        private String custMobile;
        
        //在客户实体类里面表示多个联系人,一个客户有多个联系人
        //hibernate要求使用集合表示多的数据,使用set集合
        private Set<LinkMan> setLinkMan = new HashSet<LinkMan>();
        public Set<LinkMan> getSetLinkMan() {
            return setLinkMan;
        }
        public void setSetLinkMan(Set<LinkMan> setLinkMan) {
            this.setLinkMan = setLinkMan;
        }
        
        public Integer getCid() {
            return cid;
        }
        public void setCid(Integer cid) {
            this.cid = cid;
        }
        public String getCustName() {
            return custName;
        }
        public void setCustName(String custName) {
            this.custName = custName;
        }
        public String getCustLevel() {
            return custLevel;
        }
        public void setCustLevel(String custLevel) {
            this.custLevel = custLevel;
        }
        public String getCustSource() {
            return custSource;
        }
        public void setCustSource(String custSource) {
            this.custSource = custSource;
        }
        public String getCustPhone() {
            return custPhone;
        }
        public void setCustPhone(String custPhone) {
            this.custPhone = custPhone;
        }
        public String getCustMobile() {
            return custMobile;
        }
        public void setCustMobile(String custMobile) {
            this.custMobile = custMobile;
        }
    }
    View Code

      联系人实体类:

    public class LinkMan {
        private Integer lkm_id; // 联系人编号(主键)
        private String lkm_name;// 联系人姓名
        private String lkm_gender;// 联系人性别
        private String lkm_phone;// 联系人办公电话
        
        // 在联系人实体类里面表示所属客户,一个联系人只能属于一个客户
        private Customer customer;
        public Customer getCustomer() {
            return customer;
        }
        public void setCustomer(Customer customer) {
            this.customer = customer;
        }
        
        public Integer getLkm_id() {
            return lkm_id;
        }
        public void setLkm_id(Integer lkm_id) {
            this.lkm_id = lkm_id;
        }
        public String getLkm_name() {
            return lkm_name;
        }
        public void setLkm_name(String lkm_name) {
            this.lkm_name = lkm_name;
        }
        public String getLkm_gender() {
            return lkm_gender;
        }
        public void setLkm_gender(String lkm_gender) {
            this.lkm_gender = lkm_gender;
        }
        public String getLkm_phone() {
            return lkm_phone;
        }
        public void setLkm_phone(String lkm_phone) {
            this.lkm_phone = lkm_phone;
        }
    }
    View Code

    创建映射文件

    客户映射:

    <?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>
        <!-- 1 配置类和表对应 
            class标签
            name属性:实体类全路径
            table属性:数据库表名称
        -->
        <class name="cn.itcast.entity.Customer" table="t_customer">
            <id name="cid" column="cid">
                <generator class="native"></generator>
            </id>
            <property name="custName" column="custName"></property>
            <property name="custLevel" column="custLevel"></property>
            <property name="custSource" column="custSource"></property>
            <property name="custPhone" column="custPhone"></property>
            <property name="custMobile" column="custMobile"></property>
            
            <!-- 在客户映射文件中,表示所有联系人 
                使用set标签表示所有联系人
                set标签里面有name属性:
                     属性值写在客户实体类里面表示联系人的set集合名称
                     
                 inverse属性默认值:false不放弃关系维护
                                true表示放弃关系维护
            -->
            <set name="setLinkMan" inverse="true">
                <!-- 一对多建表,有外键
                    hibernate机制:双向维护外键,在一和多那一方都配置外键    
                    column属性值:外键名称
                 -->
                <key column="clid"></key>
                <!-- 客户所有的联系人,class里面写联系人实体类全路径 -->
                <one-to-many class="cn.itcast.entity.LinkMan"/>
            </set>
        </class>
    </hibernate-mapping>
    View Code

    联系人映射:

    <?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>
        <!-- 1 配置类和表对应 
            class标签
            name属性:实体类全路径
            table属性:数据库表名称
        -->
        <class name="cn.itcast.entity.LinkMan" table="t_linkman">
            <id name="lkm_id" column="lkm_id">
                <generator class="native"></generator>
            </id>
            <property name="lkm_name" column="lkm_name"></property>
            <property name="lkm_gender" column="lkm_gender"></property>
            <property name="lkm_phone" column="lkm_phone"></property>
            
            <!-- 表示联系人所属客户 
                name属性:因为在联系人实体类使用customer对象表示,写customer名称
                class属性:customer全路径
                column属性:外键名称
            -->
            <many-to-one name="customer" class="cn.itcast.entity.Customer" column="clid"></many-to-one>
        </class>
    </hibernate-mapping>
    View Code

    将映射添加到配置文件:

    <mapping resource="com/xx/entity/Customer.hbm.xml"/>
    <mapping resource="com/xx/entity/LinkMan.hbm.xml"/>

    hibernate的一对多的操作

    编写测试代码:

    public class HibernateOnetoMany {
        
        //演示一对多修改
        @Test
        public void testUpdate() {
            SessionFactory sessionFactory = null;
            Session session = null;
            Transaction tx = null;
            try {
                //得到sessionFactory
                sessionFactory = HibernateUtils.getSessionFactory();
                //得到session
                session = sessionFactory.openSession();
                //开启事务
                tx = session.beginTransaction();
                
                //1 根据id查询lucy联系人,根据id查询百度的客户
                Customer baidu = session.get(Customer.class, 1);
                LinkMan lucy = session.get(LinkMan.class, 2);
                //2 设置持久态对象值
                //把联系人放到客户里面
                baidu.getSetLinkMan().add(lucy);
                //把客户放到联系人里面
                lucy.setCustomer(baidu);
                
                //提交事务
                tx.commit();
    
            }catch(Exception e) {
                tx.rollback();
            }finally {
                session.close();
                //sessionFactory不需要关闭
                sessionFactory.close();
            }
        }
        //演示一对多级联删除
        @Test
        public void testDeleteDemo() {
            SessionFactory sessionFactory = null;
            Session session = null;
            Transaction tx = null;
            try {
                //得到sessionFactory
                sessionFactory = HibernateUtils.getSessionFactory();
                //得到session
                session = sessionFactory.openSession();
                //开启事务
                tx = session.beginTransaction();
                
                // 1 根据id查询客户对象
                Customer customer = session.get(Customer.class, 3);
                //2 调用方法删除
                session.delete(customer);
                
                //提交事务
                tx.commit();
    
            }catch(Exception e) {
                tx.rollback();
            }finally {
                session.close();
                //sessionFactory不需要关闭
                sessionFactory.close();
            }
        }
    
        //演示一对多级联保存
        @Test
        public void testAddDemo2() {
            SessionFactory sessionFactory = null;
            Session session = null;
            Transaction tx = null;
            try {
                //得到sessionFactory
                sessionFactory = HibernateUtils.getSessionFactory();
                //得到session
                session = sessionFactory.openSession();
                //开启事务
                tx = session.beginTransaction();
                
                // 添加一个客户,为这个客户添加一个联系人
                //1 创建客户和联系人对象
                Customer customer = new Customer();
                customer.setCustName("网易");
                customer.setCustLevel("普通客户");
                customer.setCustSource("网络");
                customer.setCustPhone("110");
                customer.setCustMobile("990");
                
                LinkMan linkman = new LinkMan();
                linkman.setLkm_name("小李");
                linkman.setLkm_gender("男");
                linkman.setLkm_phone("119");
                
                //2 把联系人放到客户里面
                customer.getSetLinkMan().add(linkman);
                
                //3 保存客户
                session.save(customer);
                
                //提交事务
                tx.commit();
    
            }catch(Exception e) {
                tx.rollback();
            }finally {
                session.close();
                //sessionFactory不需要关闭
                sessionFactory.close();
            }
        }
    
        //演示一对多级联保存
        @Test
        public void testAddDemo1() {
            SessionFactory sessionFactory = null;
            Session session = null;
            Transaction tx = null;
            try {
                //得到sessionFactory
                sessionFactory = HibernateUtils.getSessionFactory();
                //得到session
                session = sessionFactory.openSession();
                //开启事务
                tx = session.beginTransaction();
                
                // 添加一个客户,为这个客户添加一个联系人
                //1 创建客户和联系人对象
                Customer customer = new Customer();
                customer.setCustName("小希");
                customer.setCustLevel("vip");
                customer.setCustSource("网络");
                customer.setCustPhone("110");
                customer.setCustMobile("988");
                
                LinkMan linkman = new LinkMan();
                linkman.setLkm_name("小王");
                linkman.setLkm_gender("男");
                linkman.setLkm_phone("118");
                
                //2 在客户表示所有联系人,在联系人表示客户        
                // 建立客户对象和联系人对象关系
                //2.1 把联系人对象 放到客户对象的set集合里面
                customer.getSetLinkMan().add(linkman);
                //2.2 把客户对象放到联系人里面
                linkman.setCustomer(customer);
                
                //3 保存到数据库
                session.save(customer);
                session.save(linkman);
                
                //提交事务
                tx.commit();
    
            }catch(Exception e) {
                tx.rollback();
            }finally {
                session.close();
                //sessionFactory不需要关闭
                sessionFactory.close();
            }
        }
    }
    View Code

    inverse与cascade

    inverse强调外键维护inverse如果为true代表放弃维护外键,如果为false不放弃维护外键关系

    cascade强调的是操作一个对象的时候,是否操作其关联对象。

    Hibernate的多对多操作

    创建表:

     创建实体类:

    用户实体类:

    public class User {
          private Integer user_id;//用户id
          private String user_name;//用户名称
          private String user_password;//用户密码
          
          //一个用户可以有多个角色
          private Set<Role> setRole = new HashSet<Role>();
          
        public Set<Role> getSetRole() {
            return setRole;
        }
        public void setSetRole(Set<Role> setRole) {
            this.setRole = setRole;
        }
        public Integer getUser_id() {
            return user_id;
        }
        public void setUser_id(Integer user_id) {
            this.user_id = user_id;
        }
        public String getUser_name() {
            return user_name;
        }
        public void setUser_name(String user_name) {
            this.user_name = user_name;
        }
        public String getUser_password() {
            return user_password;
        }
        public void setUser_password(String user_password) {
            this.user_password = user_password;
        }
    }
    View Code

    角色实体来

    public class Role {
          private Integer role_id;//角色id
          private String role_name;//角色名称
          private String role_memo;//角色描述
          
          // 一个角色有多个用户
          private Set<User> setUser = new HashSet<User>();
          
        public Set<User> getSetUser() {
            return setUser;
        }
        public void setSetUser(Set<User> setUser) {
            this.setUser = setUser;
        }
        public Integer getRole_id() {
            return role_id;
        }
        public void setRole_id(Integer role_id) {
            this.role_id = role_id;
        }
        public String getRole_name() {
            return role_name;
        }
        public void setRole_name(String role_name) {
            this.role_name = role_name;
        }
        public String getRole_memo() {
            return role_memo;
        }
        public void setRole_memo(String role_memo) {
            this.role_memo = role_memo;
        }
    }
    View Code

    创建映射关系

    用户映射

    <?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>
        <!-- 1 配置类和表对应 
            class标签
            name属性:实体类全路径
            table属性:数据库表名称
        -->
        <class name="cn.itcast.manytomany.User" table="t_user">
            <id name="user_id" column="user_id">
                <generator class="native"></generator>
            </id>
            <property name="user_name" column="user_name"></property>
            <property name="user_password" column="user_password"></property>
            <!-- 在用户里面表示所有角色,使用set标签 
                name属性:角色set集合名称
                table属性:第三张表名称
            -->
            <set name="setRole" table="user_role" cascade="save-update,delete">
                <!-- key标签里面配置
                    配置当前映射文件在第三张表外键名称
                 -->
                <key column="userid"></key>
                <!-- class:角色实体类全路径
                     column:角色在第三张表外键名称
                 -->
                <many-to-many class="cn.itcast.manytomany.Role" column="roleid"></many-to-many>
            </set>
        </class>
    </hibernate-mapping>
    View Code

    角色映射

    <?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>
        <!-- 1 配置类和表对应 
            class标签
            name属性:实体类全路径
            table属性:数据库表名称
        -->
        <class name="cn.itcast.manytomany.Role" table="t_role">
            <id name="role_id" column="role_id">
                <generator class="native"></generator>
            </id>
            <property name="role_name" column="role_name"></property>
            <property name="role_memo" column="role_memo"></property>
            
            <!-- 在角色里面表示所有用户,使用set标签 -->
            <set name="setUser" table="user_role">
                <!-- 角色在第三张表外键 -->
                <key column="roleid"></key>
                <many-to-many class="cn.itcast.manytomany.User" column="userid"></many-to-many>
            </set>
        </class>
    </hibernate-mapping>
    View Code

    在核心配置文件中添加映射

    <mapping resource="cn/xx/manytomany/User.hbm.xml"/>
    <mapping resource="cn/xx/manytomany/Role.hbm.xml"/>

    测试代码

    public class HibernateManytoMany {
        
        //演示维护第三张表
        @Test
        public void testTable2() {
            SessionFactory sessionFactory = null;
            Session session = null;
            Transaction tx = null;
            try {
                //得到sessionFactory
                sessionFactory = HibernateUtils.getSessionFactory();
                //得到session
                session = sessionFactory.openSession();
                //开启事务
                tx = session.beginTransaction();
                
                // 让某个用户没有有某个角色
                User user = session.get(User.class, 2);
                Role role = session.get(Role.class, 3);
                
                //2 从用户里面把角色去掉
                user.getSetRole().remove(role);
                
                //提交事务
                tx.commit();
    
            }catch(Exception e) {
                tx.rollback();
            }finally {
                session.close();
                //sessionFactory不需要关闭
                sessionFactory.close();
            }
        }
        
        //演示维护第三张表
        @Test
        public void testTable1() {
            SessionFactory sessionFactory = null;
            Session session = null;
            Transaction tx = null;
            try {
                //得到sessionFactory
                sessionFactory = HibernateUtils.getSessionFactory();
                //得到session
                session = sessionFactory.openSession();
                //开启事务
                tx = session.beginTransaction();
                
                // 让某个用户有某个角色
                //让lucy有经纪人角色
                //1 查询lucy和经纪人
                User lucy = session.get(User.class, 1);
                Role role = session.get(Role.class, 1);
                
                //2 把角色放到用户的set集合里面
                lucy.getSetRole().add(role);
                
                //提交事务
                tx.commit();
    
            }catch(Exception e) {
                tx.rollback();
            }finally {
                session.close();
                //sessionFactory不需要关闭
                sessionFactory.close();
            }
        }
        
        //演示多对多修级联保存
        @Test
        public void testDelete() {
            SessionFactory sessionFactory = null;
            Session session = null;
            Transaction tx = null;
            try {
                //得到sessionFactory
                sessionFactory = HibernateUtils.getSessionFactory();
                //得到session
                session = sessionFactory.openSession();
                //开启事务
                tx = session.beginTransaction();
                
                User user = session.get(User.class, 1);
                session.delete(user);
                //提交事务
                tx.commit();
    
            }catch(Exception e) {
                tx.rollback();
            }finally {
                session.close();
                //sessionFactory不需要关闭
                sessionFactory.close();
            }
        }
        
        //演示多对多修级联保存
        @Test
        public void testSave() {
            SessionFactory sessionFactory = null;
            Session session = null;
            Transaction tx = null;
            try {
                //得到sessionFactory
                sessionFactory = HibernateUtils.getSessionFactory();
                //得到session
                session = sessionFactory.openSession();
                //开启事务
                tx = session.beginTransaction();
                
                //添加两个用户,为每个用户添加两个角色
                //1 创建对象
                User user1 = new User();
                user1.setUser_name("xiaowang");
                user1.setUser_password("123456");
                
                User user2 = new User();
                user2.setUser_name("xiaoming");
                user2.setUser_password("456789");
                
                Role r1 = new Role();
                r1.setRole_name("总经理");
                r1.setRole_memo("总经理");
                
                Role r2 = new Role();
                r2.setRole_name("秘书");
                r2.setRole_memo("秘书");
                
                Role r3 = new Role();
                r3.setRole_name("销售");
                r3.setRole_memo("销售");
                
                //2 建立关系,把角色放到用户里面
                // user1 -- r1/r2
                user1.getSetRole().add(r1);
                user1.getSetRole().add(r2);
                
                // user2 -- r2/r3
                user2.getSetRole().add(r2);
                user2.getSetRole().add(r3);
                
                //3 保存用户
                session.save(user1);
                session.save(user2);
                
                //提交事务
                tx.commit();
    
            }catch(Exception e) {
                tx.rollback();
            }finally {
                session.close();
                //sessionFactory不需要关闭
                sessionFactory.close();
            }
        }
    }
    View Code

     

  • 相关阅读:
    html5基础--canvas标签元素
    html5基础--audio标签元素
    html5基础--video标签元素
    SSH Secure Shell Client中文乱码的解决方法
    Response.End() 与Response.Close()的区别
    服务器控件的返回值问题
    常用数据库操作(一)
    DataTable 读取数据库操作时去掉空格
    回车触发Button
    404页面自动跳转javascript
  • 原文地址:https://www.cnblogs.com/wuzhilong/p/9953459.html
Copyright © 2011-2022 走看看