(12)映射继承关系三之连接的子类(@Inheritance(strategy=InheritanceType.JOINED))

这种方式:父类存放子类和父类的公共字段, 父类和子类中存在一一对应的关系,子类的id参考父类的id


@Entity
@Inheritance(strategy=InheritanceType.JOINED)

public class Person {

    private int id;
    private String name;

    @Id
    @GeneratedValue
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
}

student类继承person类

@Entity

public class student extends Person {


    private int score;

    public int getScore() {
        return score;
    }

    public void setScore(int score) {
        this.score = score;
    }

}

Test
当给具体的子类时,因为person中有student字段,所以一定会进行表连接(先连接,后where)
当利用多态查询时,先进行所有表的连接,所以若select * 按照下面的连接,则会显示6条数据
id name id title id score
其中id name是person的 然后连接老师 得到 id name id title
然后再连接student 得到 6条记录。【而且连接都是用的父类和子类id的连接,必然连接成功,因为父类和子类是一一对应的。因为是左外连接,所以只要有父类,则就能连接上,比如有些id ,教师里面没有则用null补】
从上面连接得到的结果可以看出,重复列不会自动删除。
当id=1时
id name id title id score
1 s1 null null 1 80
毕竟要选出某个人具体信息,而且通过select*得到这么多重复数据。如何区分是哪个子类呢,从上面可以看出person里必有id
当不属于某个类时,其id为null,所以我们只要找谁的id 不为空,则说明是哪个类的。
case
when person0_1_.id is not null then 1 [列值,确定是学生、教师、人。给个编号]
when person0_2_.id is not null then 2
when person0_.id is not null then 0
end as clazz_0_ [列名 ]
case多中选一,则先从子类开始找,最后是父类

@Test
    public void testSave() {
        student s=new student();
        s.setName("s1");
        s.setScore(80);

        teacher t=new teacher();
        t.setName("t1");
        t.setTitle("高级");

        Session session=sf.getCurrentSession();
        session.beginTransaction();
        session.save(s);
        session.save(t);
        session.getTransaction().commit();
        /*
         * CREATE TABLE `student` (
          `score` int(11) NOT NULL,
          `id` int(11) NOT NULL,
           PRIMARY KEY  (`id`),
           KEY `FK8FFE823B415D44C3` (`id`),
           CONSTRAINT `FK8FFE823B415D44C3` FOREIGN KEY (`id`) REFERENCES `person` (`id`)
           ) ENGINE=InnoDB DEFAULT CHARSET=utf8;


         */

    }

    @Test
    public void testGet() {
        testSave();

        Session session=sf.getCurrentSession();
        session.beginTransaction();
        //student s=(student) session.get(student.class, 1);
        /*
         * inner join:就是并不参考左边表或者右边表,select两表均有的数据
         *   select
        student0_.id as id0_0_,学生表查到
        student0_1_.name as name0_0_,//从用户表查到
        student0_.score as score2_0_ 学生表查到
    from
        student student0_ //这句话:将student表重命名为student0_
    inner join
        Person student0_1_ 
            on student0_.id=student0_1_.id 
    where
        student0_.id=?

         */
        Person p=(Person) session.get(Person.class, 2);
        /*
         * 因为不确定是哪个子类,所以通过id连接所有的子类,然后根据id获取某条信息
         select
        person0_.id as id0_0_,
        person0_.name as name0_0_,
        person0_1_.title as title1_0_,
        person0_2_.score as score2_0_,
        case
            when person0_1_.id is not null then 1  [列值,确定是学生、教师、人。给个编号]
            when person0_2_.id is not null then 2 
            when person0_.id is not null then 0 
        end as clazz_0_ [列名 ]
    from
        Person person0_ 
    left outer join等价于left join
        teacher person0_1_ 
            on person0_.id=person0_1_.id 
    left outer join
        student person0_2_ 
            on person0_.id=person0_2_.id 
    where
        person0_.id=1


         */
        session.getTransaction().commit();



    }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值