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();
      }

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章