• 《Java从入门到放弃》入门篇:hibernate中的多表对应关系(二)


    前一篇讲完了一对多的关系,通过与JDBC对比应该能发现,是不是比JDBC简单了很多?j_0019.gif

    我们只需要把对象只间的包含或对应关系理清楚,完全不用我们自己来写SQL语句。所以使用hibernate框架后,我们的关注重点是业务逻辑,所有的SQL语句都不用再操心了。

    上次忘记说明,如果使用增、删、改的操作,我们还需要再引入一个Transaction对象。代码如下所示:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
        public static void main(String[] args) {
            Session session = HibernateSessionFactory.getSession();
            Transaction tx = session.beginTransaction();
            try {
                Author author = new Author("刘皇叔""sb250");
                session.save(author);
                tx.commit();    //提交
                System.out.println("保存成功");
            catch (Exception e) {
                tx.rollback();  //回滚
            }
            HibernateSessionFactory.closeSession();
        }

    知道数据库中事务的客官应该对这个对象不陌生吧。所以执行了session对象的增、删、改后,一定要记得使用transaction对象进行提交。如果某个业务有多次数据的操作,那么一定记得使用事务。

    接下来,我们继续上次未完成的任务。

    二、多一对映射关系

    上次我们已经生成了作者和博客表的关系,从作者的角度来看,作者对应博客是一对多,而从博客的角度来看,博客对应作者是多对一。所以博客实体类中的代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    public class Blog  implements java.io.Serializable {
     
         private Integer id;
         private Author author;    //相当于数据库中的外键引用
         private String title;
         private String content;
         private Date createTime;
         private String type;
         //封装的get和set方法略
    }

    blog的映射文件中代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
        <class name="com.pxy.entity.Blog" table="blog" catalog="blogdb">
            <id name="id" type="java.lang.Integer">
                <column name="id" />
                <generator class="native" />
            </id>
            <many-to-one name="author" class="com.pxy.entity.Author" fetch="select">
                <column name="author_id" />
            </many-to-one>
            <property name="title" type="java.lang.String">
                <column name="title" length="30" not-null="true" />
            </property>
            <property name="content" type="java.lang.String">
                <column name="content" length="500" />
            </property>
            <property name="createTime" type="java.util.Date">
                <column name="create_time" length="10" />
            </property>
            <property name="type" type="java.lang.String">
                <column name="type" length="20" />
            </property>
        </class>

    里面的many-to-one就是多对一的关系。我们同样先不做任何修改,来查询一篇博客看看效果。

    1
    2
    3
    4
    5
    6
    7
    8
    9
        public static void main(String[] args) {
            Session session = HibernateSessionFactory.getSession();
            Blog blog = (Blog)session.get(Blog.class6);
            System.out.println("标题:"+blog.getTitle());
            System.out.println("内容:"+blog.getContent());
            System.out.println("作者:"+blog.getAuthor().getUsername());
     
            HibernateSessionFactory.closeSession();
        }

    结果如下:

    wKioL1maNLngZxLJAABflUpXwVc287.png

    接下来,我们来聊五毛钱的与映射关系有关的几个属性:not-null、fetch、lazy、cascade、inverse。

    1)not-null

        从名字就能看出来,这个表示非空,不用多说吧。

     

    2)fetch

        表示获取数据的方式,对应的值有两个:select和join。默认是select。它们的差别我们可以通过生成的SQL语句来看看。

        select的结果如上图,默认只查询blog的内容,需要使用映射的author时,再次到数据库中查询。

        我们将Blog的映射文件中many-to-one中的fetch的值设置为join,结果如下图:

    wKiom1maNveCn2NfAABafz0RiWk614.png

    区别是不是很明显!!!

    使用join后,默认就使用多表联合的方式查询了所有的数据。

    3)lazy

        接下来,我们先把fetch的值还原为select。然后再把lazy的分别设置为proxy和false看效果对比。

    wKioL1maQI-SnQe8AABrF4YN24M368.png           wKiom1maQJaCDFjLAABxhuzmfy0998.png

    左图为设置lazy的值为false(实时加载,实体类中包含的所有对象都一次性查询出来),

    右图为设置lazy的值为proxy(延时加载,默认只查询blog的数据,当需要使用其中包含的对象时再去数据库查询)。

    4)cascade

        表示执行增、删、改时的级联操作。其值有:none、save-update、delete、delete-orphan、all、all-delete-orphan。

    cascade属性

     

    none

    Session操纵当前对象时,忽略其关联对象。它是cascade属性的默认值

    save-update

    当通过Sessionsave()update()saveOrUpdate()方法来保存或更新当前对象时,级联保存关联的临时对象,并且级联更新所有关联的游离对象

    delete

    当通过Sessiondelete()方法删除当前对象时,会级联删除关联的对象

    all

    包含save-updatedelete的行为

    delete-orphan

    删除和当前对象解除关联关系的所有对象。  即当一个节点在对象图中成为孤儿节点时,删除该节点

    all-delete-orphan

    包含alldelete-orphan的行为

    接下来,我们演示一下默认值和save-update,其它的值,各位客官可以自行试验哈。

    4.1)不设置cascade属性

        编码如下代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
        public static void main(String[] args) {
            Session session = HibernateSessionFactory.getSession();
            Transaction tx = session.beginTransaction();
            //创建作者和博客对象
            Author author = new Author("刘皇叔""sb250");
            Blog blog = new Blog("论持久战");
            //相互关联
            author.getBlogs().add(blog);
            blog.setAuthor(author);
            //保存作者或者保存博客
            session.save(author);
            //session.save(blog);
            //提交数据
            tx.commit();
            HibernateSessionFactory.closeSession();
     
        }

    运行后查看结果,可以发现,只添加了作者或者博客(注意看代码,只添加作者或者只添加博客)。

    wKiom1maR_qyL6LeAABANXOB528239.png

    4.2)把blog的映射文件和author的映射文件中的cascade属性设置为save-update

    wKioL1maSNaS8faGAAApzayUlwA316.png

    wKiom1maSN2DdNJrAAAvtSN9rjM800.png

    Test中的代码不做任何修改,再次运行看效果。

    wKiom1maSTCRQdsyAAAtyqzlWt4591.png

    现在的添加操作就进行了级联,虽然我们只保存作者,或者只保存博客,但Session发现它内部还包含新的对象时就会级联更新。

    5)inverse

        表示是否由关联对象来主控级联关系。一般设置在一对多中的”一方“。看4.2图中的set标签中包含有inverse属性。

        接下来,我们把inverse设置为false。

    wKioL1maSzGS1Eq9AABGY0UhEeQ402.png

    是不是发现多了一个update?

    其实很好理解,因为把inverse设置为false后,表示没有主控方了,A执行了控制B的代码后,B也会再次执行控制A的代码,所以blog对象会发现:“哟,我还关联有author对象,那我必须要更新一下它的ID”。

    今天的内容虽然简单,但大伙一定要把每个属性及每个属性的值都多练习几遍,不然很容易弄混效果。

    想当初第一次讲这个的时候,自己都是晕晕的,快被学生问疯了···j_0025.gif

  • 相关阅读:
    B. Random Teams(Codeforces Round 273)
    Unity3d中的属性(Attributes)整理
    Python 的 Flask 框架安装应用
    动态SQL(章节摘要)
    Linux系统PWM驱动【转】
    嵌入式电路中的BUCK VS LDO【转】
    git用法-打补丁【转】
    展讯7731C_M Android6.0 充电指示灯实现(一)------关机充电实现【转】
    Android 充电信息的获取【转】
    2.Android硬件访问服务编写系统代码【转】
  • 原文地址:https://www.cnblogs.com/yixueyuan/p/7403245.html
Copyright © 2020-2023  润新知