美文网首页
11.hibernate继承映射

11.hibernate继承映射

作者: arkulo | 来源:发表于2017-07-23 21:42 被阅读87次

    导读:

    • 什么是继承映射?
    • 继承映射的分类
      • 所有类形成一张表
      • 每个类形成一张表
      • 只有子类生成表,父类不生成表
    Paste_Image.png

    什么是继承映射

    实体类之间互相有继承关系,或者说多个实体类有公共部分,可以抽象出一个父类。这是对象之间的关系,可是数据表存储不一定是一个类对应一张表,因此我们需要分类讨论一下。

    继承映射的分类

    上面已经说过了,一共分成三种情况,其实对象之间的关系没有变,这三种情况都是表达了数据表的对应关系。
    在讲具体每种情况前,先把各实体类代码贴出来:

    Animal.java

        package entity;
        
        public class Animal {
            private int id;
            private String name;
            private boolean sex;
            public int getId() {
                return id;
            }
            public void setId(int id) {
                this.id = id;
            }
            public String getName() {
                return name;
            }
            public void setName(String name) {
                this.name = name;
            }
            public boolean isSex() {
                return sex;
            }
            public void setSex(boolean sex) {
                this.sex = sex;
            }
        }
    

    Pig.java

        package entity;
        
        public class Pig extends Animal{
            private int weight;
        
            public int getWeight() {
                return weight;
            }
        
            public void setWeight(int weight) {
                this.weight = weight;
            }
            
            
        }
    

    Dog.java

        package entity;
        
        public class Dog extends Animal{
            private int run;
        
            public int getRun() {
                return run;
            }
        
            public void setRun(int run) {
                this.run = run;
            }
            
        }
    

    1.所有类形成一张表

    Animal.hbm.xml

        <?xml version="1.0"?>
        <!DOCTYPE hibernate-mapping PUBLIC 
            "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
            "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
        <hibernate-mapping>
            <class name="entity.Animal" table="_animal">
                <id name="id">
                    <generator class="native"/>
                </id>
                <!-- 下面就开始定义就是将pig和dog继承进来,都生成一张表 -->
                <!-- 下面的这个类型string是hibernate的,不是java自己的String类型 --> 
                <!-- discriminator这个标签必须写在所有属性的第一个,要不然会报错! -->
                <discriminator column="type" type="string" />
                <property name="name" />        
                <property name="sex" />
                <subclass name="entity.Pig" discriminator-value="P">
                    <property name="weight"></property>
                </subclass>
                <subclass name="entity.Dog" discriminator-value="D">
                    <property name="run"></property>
                </subclass> 
            </class>    
        </hibernate-mapping>
    

    单元测试:

        package entity;
        
        import org.hibernate.classic.Session;
        
        import junit.framework.TestCase;
        import util.hibernateUtil;
        
        /**
         * 测试目的:
         * 这是继承映射的第一种策略,多个类共同对应一张表。
         * 1. 用不同的子类去查询数据
         * 2. 用父类多态的角度去查询
         * 3. 根据不同的类查询出来结果,因为涉及到延迟加载,看是否能判断真实类类型
         * 
         * 结果:
         * 只要是查询的时候不延时,那就能判断实际的对象类型
         * @author arkulo
         *
         */
        
        public class TestDemo extends TestCase {
        //  初始化数据
            public void test1()
            {
                Session session = null;
                try {
                    session = hibernateUtil.getSession();
                    session.beginTransaction();
                    
                    Dog dd = new Dog();
                    dd.setName("叮当");
                    dd.setSex(false);
                    dd.setRun(100);
                    session.save(dd);
                    
                    Pig zz = new Pig();
                    zz.setName("八戒");
                    zz.setSex(false);
                    zz.setWeight(60);
                    session.save(zz);
                    
                    session.getTransaction().commit();
                } catch (Exception e) {
                    e.printStackTrace();
                    session.getTransaction().rollback();
                }finally{
                    hibernateUtil.closeSession(session);
                }
            }
            
        //  用父类多态角度去查询
            public void test2()
            {
                test1();
                System.out.println("----------------------------");
                Session session = null;
                try {
                    session = hibernateUtil.getSession();
                    session.beginTransaction();
                    
        //          load是延迟加载,所以用的是代理,因此不能判断对象的类型是Dog
        //          如果必须判断真实对象类型,那就该用get函数,或者把class的lazy属性设置成为false
        //          Animal an = (Animal)session.load(Animal.class, 1);
        //          if(an instanceof Dog)
        //          {
        //              System.out.println("我是小狗,我叫:"+an.getName());
        //          }else
        //          {
        //              System.out.println("我是小猪,我叫"+an.getName());
        //          }
                    
                    Dog dd = (Dog)session.get(Dog.class, 1);
                    System.out.println(dd.getName());   
                    
                    
                    session.getTransaction().commit();
                } catch (Exception e) {
                    e.printStackTrace();
                    session.getTransaction().rollback();
                }finally{
                    hibernateUtil.closeSession(session);
                }
            }
            
        }
    

    2.每个类形成一张表

    Animal.hbm.xml

        <?xml version="1.0"?>
        <!DOCTYPE hibernate-mapping PUBLIC 
            "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
            "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
        <hibernate-mapping package="entity">
            <class name="entity.Animal" table="_animal">
                <id name="id">
                    <generator class="native"/>
                </id>
                <property name="name" />        
                <property name="sex" />
                <!-- 下面就是各个实体类单独程表的映射配置 -->
                <!-- pid是关联animal表的主键,did同理 -->
                <joined-subclass name="Pig" table="_pig">
                    <key column="pid"></key>
                    <property name="weight"></property>
                </joined-subclass>  
                <joined-subclass name="Dog" table="_dog">
                    <key column="did"></key>
                    <property name="run"></property>
                </joined-subclass>
            </class>    
        </hibernate-mapping>
    

    单元测试:

        package entity;
        
        import org.hibernate.classic.Session;
        
        import junit.framework.TestCase;
        import util.hibernateUtil;
        
        /**
         * 这个项目是多个关联实体类,每个实体类映射成为一张表,但是只用一个hbm映射文件
         * 插入数据的时候,相当于主附表
         * 
         * @author arkulo
         *
         */
        
        public class TestDemo extends TestCase {
        //  初始化数据
            public void test1()
            {
                Session session = null;
                try {
                    session = hibernateUtil.getSession();
                    session.beginTransaction();
        //          产生两天sql语句,一条插入Animal表,一条插入Dog表,did字段关联animal表的主键
                    Dog dd = new Dog();
                    dd.setName("叮当");
                    dd.setSex(false);
                    dd.setRun(100);
                    session.save(dd);
        //          和上面同理,产生两条SQL语句
                    Pig zz = new Pig();
                    zz.setName("八戒");
                    zz.setSex(false);
                    zz.setWeight(60);
                    session.save(zz);
                    
                    session.getTransaction().commit();
                } catch (Exception e) {
                    e.printStackTrace();
                    session.getTransaction().rollback();
                }finally{
                    hibernateUtil.closeSession(session);
                }
            }
            
        //  用父类多态角度去查询
            public void test2()
            {
                test1();
                System.out.println("----------------------------");
                Session session = null;
                try {
                    session = hibernateUtil.getSession();
                    session.beginTransaction();
                    
        //          load是延迟加载,所以用的是代理,因此不能判断对象的类型是Dog
        //          如果必须判断真实对象类型,那就该用get函数,或者把class的lazy属性设置成为false
        //          sql语句是left out join,一条SQL语句联合查询两张表
        //          Animal an = (Animal)session.load(Animal.class, 1);
        //          if(an instanceof Dog)
        //          {
        //              System.out.println("我是小狗,我叫:"+an.getName());
        //          }else
        //          {
        //              System.out.println("我是小猪,我叫"+an.getName());
        //          }
                    
        //          采用inner join的方式,发出一条sql语句,关联查询animal和dog表
        //          Dog dd = (Dog)session.get(Dog.class, 1);
        //          System.out.println(dd.getName());   
                    
                    
                    session.getTransaction().commit();
                } catch (Exception e) {
                    e.printStackTrace();
                    session.getTransaction().rollback();
                }finally{
                    hibernateUtil.closeSession(session);
                }
            }
            
        }
    

    3.只有子类生成表,父类不生成表

    Animal.hbm.xml

        <?xml version="1.0"?>
        <!DOCTYPE hibernate-mapping PUBLIC 
            "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
            "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
        <hibernate-mapping package="entity">
            <!-- abstract设置为true,animal实体类就不会建表,但不会影响到存储和加载 -->
            <class name="entity.Animal" abstract="true">
                <id name="id">
                    <!-- 这里不会生成表了,所以id就不能采用数据库生成策略 -->
                    <generator class="assigned"/>
                </id>
                <property name="name" />        
                <property name="sex" />
                <!-- 下面开始配置子类生成独立的表 -->
                <union-subclass name="Pig" table="_pig">
                    <property name="weight"></property>
                </union-subclass>
                <union-subclass name="Dog" table="_dog">
                    <property name="run"></property>
                </union-subclass>
            </class>    
        </hibernate-mapping>
    

    单元测试:

        package entity;
        
        import org.hibernate.classic.Session;
        
        import junit.framework.TestCase;
        import util.hibernateUtil;
        
        /**
         * 三个类,每个具体类映射成一张表,父类不映射成表
         * 
         * @author arkulo
         *
         */
        
        public class TestDemo extends TestCase {
        //  初始化数据
            public void test1()
            {
                Session session = null;
                try {
                    session = hibernateUtil.getSession();
                    session.beginTransaction();
        //          这里要注意,id是由animal提供的,但是animal现在不会在去生成表了,因此
        //          这里的主键,我们只能自己指定,不能依靠数据库生成,当然也可以使用uuid,那就需要设置id为String类型
                    Dog dd = new Dog();
                    dd.setId(1);
                    dd.setName("叮当");
                    dd.setSex(false);
                    dd.setRun(100);
                    session.save(dd);
        //          和上面同理
                    Pig zz = new Pig();
                    zz.setId(2);
                    zz.setName("八戒");
                    zz.setSex(false);
                    zz.setWeight(60);
                    session.save(zz);
                    
                    session.getTransaction().commit();
                } catch (Exception e) {
                    e.printStackTrace();
                    session.getTransaction().rollback();
                }finally{
                    hibernateUtil.closeSession(session);
                }
            }
            
        //  用父类多态角度去查询
            public void test2()
            {
        //      这里如果用上面的函数来初始化数据,记得重新指定id,因为是手动设定的
                test1();
                System.out.println("----------------------------");
                Session session = null;
                try {
                    session = hibernateUtil.getSession();
                    session.beginTransaction();
                    
        //          load是延迟加载,所以用的是代理,因此不能判断对象的类型是Dog
        //          如果必须判断真实对象类型,那就该用get函数,或者把class的lazy属性设置成为false
        //          sql语句是left out join,一条SQL语句联合查询两张表
                    Animal an = (Animal)session.get(Animal.class, 1);
                    if(an instanceof Dog)
                    {
                        System.out.println("我是小狗,我叫:"+an.getName());
                    }else
                    {
                        System.out.println("我是小猪,我叫"+an.getName());
                    }
                    
        //          采用inner join的方式,发出一条sql语句,关联查询animal和dog表
        //          Dog dd = (Dog)session.get(Dog.class, 1);
        //          System.out.println(dd.getName());   
                    
                    
                    session.getTransaction().commit();
                } catch (Exception e) {
                    e.printStackTrace();
                    session.getTransaction().rollback();
                }finally{
                    hibernateUtil.closeSession(session);
                }
            }
            
        }

    相关文章

      网友评论

          本文标题:11.hibernate继承映射

          本文链接:https://www.haomeiwen.com/subject/wjnetxtx.html