hibernate框架—表与表之间关系

一、表关系分析

这里写图片描述

1.明确表中字段关系
2.编写实体类中的映射文件
3.对表进行操作

分析表关系:一对一,一对多/多对一,多对多
1.谁是主谁从(分清主表主键和从表外键)--外键在从表
2.分析实体类中的属性
3.写实体类
4.编写映射文件
二、一对多/多对一表关系的插入和删除
Customer(客户类)---LinkMan(联系人):一对多(一个客户会有多个联系方式)
1.这里我们确认了是一对多表关系,然后我们分析实体类中
的属性,写实体类:Customer(客户类)

public class Customer {

//下面是客户表中字段
    /*
     CREATE TABLE `cst_customer` (
    `cust_id` BIGINT (32) NOT NULL AUTO_INCREMENT COMMENT '客户编号(主键)',
    `cust_name` VARCHAR (32) NOT NULL COMMENT '客户名称(公司名称)',
    `cust_source` VARCHAR (32) DEFAULT NULL COMMENT '客户信息来源',
    `cust_industry` VARCHAR (32) DEFAULT NULL COMMENT '客户所属行业',
    `cust_level` VARCHAR (32) DEFAULT NULL COMMENT '客户级别',
    `` VARCHAR (64) DEFAULT NULL COMMENT '联系人',
    `cust_phone` VARCHAR (64) DEFAULT NULL COMMENT '固定电话',
    `cust_mobile` VARCHAR (16) DEFAULT NULL COMMENT '移动电话',
    PRIMARY KEY (`cust_id`)
     */
    private long  cust_id;
    private String  cust_name;
    private String cust_source;
    private String cust_industry;
    private String cust_level;
    private String cust_linkman;
    private String cust_phone;
    private String cust_mobile;
    //表示一对多关系的容器
    //这里一定注意:容器必须要初始化了,才能保存东西
    private Set<LinkMan> linkMans = new HashSet<>();
   //get/set/有参无参/toString()省略
LinkMan实体类:
public class LinkMan {
    /*
     * CREATE TABLE `cst_linkman` (
      `lkm_id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '联系人编号(主键)',
      `lkm_name` varchar(16) DEFAULT NULL COMMENT '联系人姓名',
      `lkm_cust_id` bigint(32) NOT NULL COMMENT '客户id',
      `lkm_gender` char(1) DEFAULT NULL COMMENT '联系人性别',
      `lkm_phone` varchar(16) DEFAULT NULL COMMENT '联系人办公电话',
      `lkm_mobile` varchar(16) DEFAULT NULL COMMENT '联系人手机',
      `lkm_email` varchar(64) DEFAULT NULL COMMENT '联系人邮箱',
      `lkm_qq` varchar(16) DEFAULT NULL COMMENT '联系人qq',
      `lkm_position` varchar(16) DEFAULT NULL COMMENT '联系人职位',
      `lkm_memo` varchar(512) DEFAULT NULL COMMENT '联系人备注',
      PRIMARY KEY (`lkm_id`),
      KEY `FK_cst_linkman_lkm_cust_id` (`lkm_cust_id`),
      CONSTRAINT `FK_cst_linkman_lkm_cust_id` FOREIGN KEY (`lkm_cust_id`) REFERENCES `cst_customer` (`cust_id`) ON DELETE NO ACTION ON UPDATE NO ACTION
    )
     */
    private long  lkm_id;
    private String  lkm_name;
    private long  lkm_cust_id;
    private char 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 Customer customer;
    //get/set/有参无参/toString()省略
实体类写出来后,我们将配置各个实体类的映射文件

1.Customer映射文件
<?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="com.lanou3g.bean">
    <class name="Customer" table="cst_customer">
     <id name="cust_id" column="cust_id">
     <generator class="native"></generator>
     </id>
       <property name="cust_name" column="cust_name"></property>
       <property name="cust_source" column="cust_source"></property>
       <property name="cust_industry" column="cust_industry"></property>
       <property name="cust_level" column="cust_level"></property>
       <property name="cust_linkman" column="cust_linkman"></property>
       <property name="cust_phone" column="cust_phone"></property>
       <property name="cust_mobile" column="cust_mobile"></property>
       <!--配置表示关系的容器
         -->
         <!--name中填写的是实体类中集合属性名字 
     inverse:反转,默认维护外键关系,默认值是false
    控制是否维护外键关系
    false:维护
    true:不维护
    结语:inverse可以减少hibernate无用操作,提高效率 -->
      <!--
        cascade:级联操作
        save-update 级联保存
        delete   级联删除
        all == save-update + delete
        建议:如果要用级联的话,就用save-update,请慎用delete

        -->

      <set name="linkMans" inverse="true" cascade="delete">
      <!--colum对应表外键名  -->
      <key column="lkm_cust_id"></key>
      <!--class填写的,表示一对多中,多表的类(全类名)  -->
      <one-to-many class="LinkMan"/>
      </set>
    </class>
    </hibernate-mapping>
2.LinkMan配置文件
<?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="com.lanou3g.bean">
    <class name="LinkMan" table="cst_linkman">
     <id name="lkm_id" column="lkm_id">
     <generator class="native"></generator>
     </id>
       <property name="lkm_name" column="lkm_name"></property>
<!--        <property name="lkm_cust_id" column="lkm_cust_id"></property>-->    
        <property name="lkm_gender" column="lkm_gender"></property>
       <property name="lkm_phone" column="lkm_phone"></property>
       <property name="lkm_mobile" column="lkm_mobile"></property>
       <property name="lkm_email" column="lkm_email"></property>
       <property name="lkm_qq" column="lkm_qq"></property>
        <property name="lkm_position" column="lkm_position"></property>
        <property name="lkm_memo" column="lkm_memo"></property>
       <!--配置表关系  -->
       <!--
       name:表示关系对象的属性名
       column:表中的外键名
       class:多对一关系中,对应的实体类的全类名
       注意:外键的属性,不要重复配置
         -->
        <many-to-one name="customer" column="lkm_cust_id" class="Customer"></many-to-one>
    </class>
    </hibernate-mapping>
3.添加和删除
public class Demo01 {
    /*
     *添加一个客户,两个联系人 
     *
     *对hibernate执行的sql语句进行优化
     *
     *打印的插入语句,是linkMan在维护自己的表
     *并且在插入的时候,已经插入了外键(外键已经有了)
     *
     *打印的更新语句,是Customer来维护从而打印出来的
     *
     *这里外键的维护,两个表都维护了一遍,造成多余的sql语句操作
     *
     */
    @Test
   public void fun1() {
       //获取session
        Session session = HibernateUtils.getSession();
        //开启事物
        Transaction transaction = session.beginTransaction();
        //_______
        //创建客户
        Customer customer = new Customer();
         customer.setCust_name("蓝鸥科技");
         customer.setCust_phone("123");
        //创建联系人
        LinkMan l1 = new LinkMan();
        l1.setLkm_name("yangyuanhu");
        LinkMan l2 = new LinkMan();
        l2.setLkm_name("liuchangkai");
        //添加实体类中的关系
        //把联系人添加到集合中
        customer.getLinkMans().add(l1);
        customer.getLinkMans().add(l2);
        //给联系人设置客户
        l1.setCustomer(customer);
        l2.setCustomer(customer);

        //保存到数据库
        session.save(customer);
        session.save(l1);
        session.save(l2);


        //提交事务
      transaction.commit();
        //关闭资源
    session.close();
    //为客户id为1的删除联系人id为2


   }
    //为客户id为1的,增加联系人
    @Test
       public void fun2() {
           //获取session
            Session session = HibernateUtils.getSession();
            //开启事物
            Transaction transaction = session.beginTransaction();
//          //_______

              //获取id为1的客户
            //持久态,在事物提交的时候,如果该对象被修改了,
            //那么修改的数据,会被同步到数据库中
             Customer customer = session.get(Customer.class, 1l);

            //获取id为2的联系人
             LinkMan linkMan = session.get(LinkMan.class, 2l);
            //处理实体类中的关系
             customer.getLinkMans().remove(linkMan);
             linkMan.setCustomer(null);
            //从数据库中删除
             //session.delete(linkMan);


            //提交事务
          transaction.commit();
            //关闭资源
        session.close();



       }
    //为客户id为1的,增加联系人
        @Test
           public void fun3() {
               //获取session
                Session session = HibernateUtils.getSession();
                //开启事物
                Transaction transaction = session.beginTransaction();
//              //_______

                Customer customer = session.get(Customer.class, 1l);
                LinkMan l3 = new LinkMan();
                l3.setLkm_name("添加");
                customer.getLinkMans().add(l3);
                l3.setCustomer(customer);
                session.save(customer);
                session.save(l3);
                //提交事务
              transaction.commit();
                //关闭资源
            session.close();

           }
        /*
         * 新增客户,新增联系人
         * 级联操作作用:可以让你减少几行代码的工作量
         *  但是出问题,就大事
         */
        @Test
           public void fun4() {
               //获取session
                Session session = HibernateUtils.getSession();
                //开启事物
                Transaction transaction = session.beginTransaction();
//              //_______
                //创建客户
                Customer customer = new Customer();
                 customer.setCust_name("芬欧科技");
                //创建联系人
                LinkMan l1 = new LinkMan();
                l1.setLkm_name("李胜云");
                customer.getLinkMans().add(l1);
                //给联系人设置客户
                l1.setCustomer(customer);
                //保存到数据库
                session.save(customer);
//              session.save(l1);
                //提交事务
              transaction.commit();
                //关闭资源
            session.close();

           }
        /*
         * 删除客户id为1的,联系人也删除
         */
        @Test
           public void fun5() {
               //获取session
                Session session = HibernateUtils.getSession();
                //开启事物
                Transaction transaction = session.beginTransaction();
//              //_______
                //创建客户
                Customer customer = session.get(Customer.class, 1l);
                session.delete(customer);
                //提交事务
              transaction.commit();
                //关闭资源
            session.close();

           }
}
三、多对多表(User用户实体类和Role角色实体类)
User实体类
public class User {
    /*
       CREATE TABLE `sys_user` (
      `user_id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '用户id',
      `user_code` varchar(32) NOT NULL COMMENT '用户账号',
      `user_name` varchar(64) NOT NULL COMMENT '用户名称',
      `user_password` varchar(32) NOT NULL COMMENT '用户密码',
      `user_state` char(1) NOT NULL COMMENT '1:正常,0:暂停',
      PRIMARY KEY (`user_id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;
     */
    private Long user_id;
    private String  user_code;
    private String  user_name;
    private String user_password;
    private Character user_state;
    //表示多对多关系
    private Set<Role> role = new HashSet<>();
Role实体类:
public class Role {
    /* 
     CREATE TABLE `sys_role` (
      `role_id` bigint(32) NOT NULL AUTO_INCREMENT,
      `role_name` varchar(32) NOT NULL COMMENT '角色名称',
      `role_memo` varchar(128) DEFAULT NULL COMMENT '备注',
      PRIMARY KEY (`role_id`)
    ) ;
         */
    private Long  role_id;
    private String role_name;
    private String role_memo;

    private Set<User> users = new HashSet<>();
配置文件
1.User
<?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="com.lanou3g.bean">
    <class name="User" table="sys_user">
        <id name="user_id" column="user_id">
            <generator class="native"></generator>
        </id>   
        <property name="user_code" column="user_code"></property>
        <property name="user_name" column="user_name"></property>
        <property name="user_password" column="user_password"></property>
        <property name="user_state" column="user_state"></property>

        <!-- 表示多对多关系 -->
        <!-- 
            name: 对应容器的名
            table: 中间表的名字 
            column: 被引用的外键
            ____________________
            class: 与之对应的表的类名
            column: 前面class中被应用的外键
        -->
        <set name="role" table="sys_user_role" inverse="true">
            <key column="user_id"></key>
            <many-to-many class="Role" column="role_id"></many-to-many>
        </set>
    </class>

</hibernate-mapping>

Role映射文件
<?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="com.lanou3g.bean">
    <class name="Role" table="sys_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 name="users" table="sys_user_role" cascade="delete">
            <key column="role_id"></key>
            <many-to-many class="User" column="user_id"></many-to-many>
        </set>
    </class>
    <!--设计两张表,是1对多,练习操作 增删  -->
    <!--设计多对多     -->
</hibernate-mapping>
多对多表的添加和删除
public class Demo02 {
/*
 * 测试多对多
 * 
 */
    /*
     * 两个表都会默认维护自己的外键关系
     *中间表使用的是联合主键,如果两张表都维护外键关系
     *也就是说,都会对中间表进行操作,这时会发生重复插入的相同外键值
     *所以多对多操作,必须要有一张表,放弃对外键关系的维护
     */
    @Test
      public  void fun1() {
          Session session = HibernateUtils.getSession();
          Transaction transaction = session.beginTransaction();
          //---------
          User user1 = new User();
          user1.setUser_name("杨元虎");
          User user2 = new User();
          user2.setUser_name("刘长凯");

          Role role1 = new Role();
          role1.setRole_name("保姆");
          Role role2 = new Role();
          role1.setRole_name("保安");

        //设置关系
          user1.getRole().add(role1);
          user1.getRole().add(role2);

          user2.getRole().add(role1);
          user2.getRole().add(role2); 

          role1.getUsers().add(user1);
          role1.getUsers().add(user2);

          role2.getUsers().add(user1);
          role2.getUsers().add(user2);

          session.save(user1);
          session.save(user2);
          session.save(role1);
          session.save(role2);
          //-----------
          transaction.commit();
          session.close();
      }
    //为员工id为1的员工增加一个角色(保洁)
    @Test
      public  void fun2() {
          Session session = HibernateUtils.getSession();
          Transaction transaction = session.beginTransaction();
          //---------
          User user = session.get(User.class, 1l);
          //注意:双侧关系都要添加上
          Role role = new Role();
          role.setRole_name("保洁");
          user.getRole().add(role);
          role.getUsers().add(user);
//        session.save(user);
          session.save(role);
          //-----------
          transaction.commit();
          session.close();
      }
    //为id为1的员工解除一个角色(角色id为2)
    @Test
      public  void fun3() {
          Session session = HibernateUtils.getSession();
          Transaction transaction = session.beginTransaction();
          //---------
         User user = session.get(User.class, 1l);
         Role role = session.get(Role.class, 2l);
         user.getRole().remove(role);
         role.getUsers().remove(user);

         session.save(role);
         session.save(user);
          //-----------
          transaction.commit();
          session.close();
      }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值