zoukankan      html  css  js  c++  java
  • Hibernate(7)关联关系_单向1对n

    1.单向一对多(@OneToMany)关联是比较少用的(一般用双向一对多代替)。
    2.实体类:
    1端:Publishers.java

    public class Publishers {
    
        private Integer id;
        private String Name;
        //集合属性
        private Set bks = new HashSet<>();
        //忽略getter和setter方法
        ...
    }

    n端:Books.java

    public class Books {
    
        private Integer Id;
        private String Title;
        private String Author;
        private String ISBN;
        private int WordCount;
        private double UnitPrice;
        private String ContentDescription;
        //忽略getter和setter方法
        ... 
    }

    3.映射文件
    1端:Publishers.hbm.xml

    <hibernate-mapping>
    
        <class name="com.withXml.oneTomany.entity.Publishers" table="PUBLISHERS">
    
            <id name="id" type="java.lang.Integer" access="field">
                <column name="ID" />
                <generator class="native" />
            </id>
    
            <property name="Name" type="java.lang.String">
                <column name="NAME" />
            </property>
            <!-- 配置单向一对多配置,在一的一方进行配置 -->
             <!--set节点: 
                cascade(级联)级联的意思是指两个对象之间的操作联运关系,对一个对象执行了操作之后,
                对其指定的级联对象也需要执行相同的操作,取值:all,none,save_update,delete。
                  1.all:代码在所有情况下都执行级联操作
                  2.none:在所有情况下都不执行级联操作
                  3.save-update:在保存和更新的情况下执行级联操作
                  4.delete:在删除的时候执行级联操作
                 name:保存多端对象集合的属性。
                 table:多端的数据表。
                 <key>:指定多端的外键。
             -->
            <set name="bks" lazy="false" table="BOOKS" cascade="save-update,delete">
                <key column="PUBLISHER_ID"></key>
                <one-to-many class="com.withXml.oneTomany.entity.Books"/>
            </set>
        </class>
    </hibernate-mapping>
    

    n端:Books.hbm.xml

    <hibernate-mapping package="com.withXml.oneTomany.entity">
    
        <class name="Books" table="BOOKS">
    
            <id name="Id" type="java.lang.Integer" access="field">
                <column name="ID" />
                <generator class="native" />
            </id>
    
            <property name="Title" type="java.lang.String">
                <column name="TITLE" />
            </property>
    
            <property name="Author" type="java.lang.String">
                <column name="AUTHOR" />
            </property>
    
            <property name="ISBN" type="java.lang.String">
                <column name="ISBN" />
            </property>
    
            <property name="WordCount" type="integer">
                <column name="WORD_COUNT"/>
            </property>
    
            <!-- 映射数据表字段你的类型,可以在property 里面使用type设置,也可以在column里面使用 sql-type设置-->
            <property name="UnitPrice">
                <column name="UNIT_PRICE" sql-type="double" />
            </property>
    
            <property name="ContentDescription" type="java.lang.String">
                <column name="CONTENT_DESCRIPTION" />
            </property>
    
        </class>
    </hibernate-mapping>
    

    5.CRUD测试
    ①保存

    /**
         * 添加操作
         * 添加图书和出版社信息
         */
        @Test
        public void testOneToManySave(){
            //新建出版社对象
            Publishers publisher = new Publishers();
            publisher.setName("北京大学出版社");
            //新建图书对象
            Books book = new Books();
            book.setTitle("大学英语");
            book.setISBN("2018012103");
            book.setAuthor("李玲");
            book.setWordCount(10000);
            book.setUnitPrice(95.5);
            book.setContentDescription("无");
    
            //新建图书对象
            Books book2 = new Books();
            book2.setTitle("管理学");
            book2.setISBN("2018012104");
            book2.setAuthor("张青");
            book2.setWordCount(10000);
            book2.setUnitPrice(95.5);
            book2.setContentDescription("无");
    
            //设定关联关系,从多的一端维护关系,想要从多端维护关联关系需要在多端配置many-to-one,三条insert语句,推荐使用这种方式
            //book.setPublisher(publisher);
            //book2.setPublisher(publisher);
    
            //设定关联关系,从一的一端维护关系,想要从一端维护关联关系需要在一端配置one-to-many,三条insert语句,两条update语句,不推荐使用这种方式,因为这里需要演示1对n关联关系,所以使用该方法
            publisher.getBks().add(book);
            publisher.getBks().add(book2);
    
            //执行保存操作,先保存1的一端,在保存n的一端
            session.save(publisher);
            session.save(book);
            session.save(book2);
    
        }

    ②获取

    /**
         * 获取操作
         * 通过出版社获取图书信息
         */
        @Test
        public void testOneToManyGet(){
            //根据id获取出版社对象
            Publishers publisher = (Publishers) session.get(Publishers.class, 1);
            System.out.println(publisher.getName() + "出版的图书有:");
            //获取集合的迭代器
            Iterator iterators = publisher.getBks().iterator();
            while(iterators.hasNext()){
                Books book = (Books) iterators.next();
                System.out.println(book.getTitle());
            }
    
        }

    ③修改

    /**
         * 修改操作
         * 功能:修改id为1的出版社的名字
         */
        @Test
        public void testOneToManyUpdate(){
            Publishers publisher = (Publishers) session.get(Publishers.class, 2);
            publisher.setName("同济大学出版社");
            session.update(publisher);
        }

    ④删除

    /**
         * 删除操作,在多对一映射中,无法从1的一端删除,在一对多映射中,可以中1的一端删除记录,
         *同时还会强制把n端的外键也删除
         *功能:删除出版社,同时引用该记录的外键也删除。
         */
        @Test
        public void testOneToManyDelete(){
            //从n端删除
            Books book = (Books) session.get(Books.class, 1);
            session.delete(book);
    
            //从1端删除,同时n端引用的外键也会被删除
    //      Publishers publisher = (Publishers) session.get(Publishers.class, 1);
    //      session.delete(publisher);
        }

    级联操作需要在1端的映射文件中set节点下,设置级联属性:
    cascade(级联)级联的意思是指两个对象之间的操作联运关系,对一个对象执行了操作之后,
    对其指定的级联对象也需要执行相同的操作,取值:all,none,save_update,delete。
    1.all:代码在所有情况下都执行级联操作
    2.none:在所有情况下都不执行级联操作
    3.save-update:在保存和更新的情况下执行级联操作
    4.delete:在删除的时候执行级联操作

    ⑤级联添加

    /**
         * 级联添加
         * 需求:添加出版社时,把出版社出版的图书添加到数据表中
         */
        @Test
        public void testOneToManyCascadeSave(){
            //新建出版社对象
            Publishers publisher = new Publishers();
            publisher.setName("北京大学出版社");
            //新建图书对象
            Books book = new Books();
            book.setTitle("大学英语");
            book.setISBN("2018012103");
            book.setAuthor("李玲");
            book.setWordCount(10000);
            book.setUnitPrice(95.5);
            book.setContentDescription("无");
    
            //新建图书对象
            Books book2 = new Books();
            book2.setTitle("管理学");
            book2.setISBN("2018012104");
            book2.setAuthor("张青");
            book2.setWordCount(10000);
            book2.setUnitPrice(95.5);
            book2.setContentDescription("无");
    
            //设定关联关系,从多的一端维护关系,想要从多端维护关联关系需要在多端配置many-to-one,三条insert语句,推荐使用这种方式
            //book.setPublisher(publisher);
            //book2.setPublisher(publisher);
    
            //设定关联关系,从一的一端维护关系,想要从一端维护关联关系需要在一端配置one-to-many,三条insert语句,两条update语句,不推荐使用这种方式,因为演示1对n,所以使用该方法
            publisher.getBks().add(book);
            publisher.getBks().add(book2);
    
            //设置cascade级联属性之后,可只保存1的一端即可。可省略多的一端的保存操作,反之则不行因为没有多对一映射
            session.save(publisher);
            //session.save(book);
            //session.save(book2);
    
        }

    ⑥级联更新

        /**
         * 级联更新
         *需求:把id为3的书的出版社改为出版社id为1的出版社
         */
    
        @Test
        public void testOneToManyCascadeUpdate(){
            //获取id为1的图书对象
            Books book = (Books) session.get(Books.class, 3);
            //获取id为1的出版社对象
            Publishers publisher = (Publishers) session.get(Publishers.class, 1);
    
            publisher.getBks().add(book);
            //保存出版社对象,三个select,一个update
            //session.save(publisher);
    
            //保存图书对象,三个select,一个update
            session.save(book);
        }

    ⑦级联删除

        /**
         * 级联删除
         * 需求:删除出版社时,删除该出版社所出版社的图书
         */
        @Test
        public void testOneToManyCascadeDelete(){
            Publishers publisher = (Publishers) session.get(Publishers.class, 4);
            //两个select、一个update、三个delete
            session.delete(publisher);
        }

    一对多关联关系
    总结:
    1端:
    ①实体类中添加一个集合属性
    ②映射文件中使用set元素映射数据库字段,并在set节点中配置<one-to-many> 子节点以映射关联关系
    ③保存操作时,有没有发送多余的update语句在于哪端维护关联关系,而哪端维护关联关系在于是<one-to-many> 还是 <many-to-one>
    即推荐使用由n端维护关联关系,使用<many-to-one> 来映射关系,在保存时使用n端实体类中的setter方法

    //n端保存1端,订单中设置客户信息
    order.setCustomer(customer);
    order2.setCustomer(customer);

    ④级联操作少用

    n端:
    实体类:普通的JavaBean
    映射文件:类属性和数据库字段一一映射即可

  • 相关阅读:
    opencv行列式按行(列)展开
    线性方程组
    opencvVideoCapture视频和摄像头读写
    浅谈测试的成就感
    关于软件测试职业规划的讨论 .
    多进程,多线程,就是这么回事儿
    测试计划的制定
    写给测试新手 .
    测试最需要的是淡定
    用一个比喻说明项目里各个成员的角色
  • 原文地址:https://www.cnblogs.com/tengpengfei/p/10453957.html
Copyright © 2011-2022 走看看