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
映射文件:类属性和数据库字段一一映射即可

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值