关于JPA实现类的继承
来源:互联网 发布:旋转变换矩阵 编辑:程序博客网 时间:2024/06/05 06:29
JPA实现继承有三种类型.假设有A.B.C三个类,A为基类,B,C均为A的子类.那么三种设计方式分别为:
1.A.B.C共用一张表
2.每个类分层结构一张表A.B.C各一张表,各自包含自己的属性.
3.A.B.C各一张表.
首先,我们针对第一种情况,进行分析.
分别再定义两个子类
仔细观查,你会发现,除了基类上指定了@Table属性外,两个子类均没有指定,而且还有几个特殊的地方
1>父类中的@Inheritance(strategy=InheritanceType.SINGLE_TABLE):继承表标,指定实现方式为一张表,即所有的对象一张表.
2>父类中的@DiscriminatorColumn(name="Discriminator",
discriminatorType = DiscriminatorType.STRING,
length=30) 其实这个字段就是一个区分字段,我们平时自己设计数据库的时候,有时候也会在表中加入一个字段用于判断该记录的类型,那么这个字段就是同样功能,name为自定义的.
3>三个类都有这个注解:@DiscriminatorValue("WindowFile"),很显明,明白了第2>点,这点也很容易理解,就是上面那个字段的值,当这个字段值为"windowFile"时,他就是基类,为"Document"时,就是Document类....这个值是自定义的..
配置好项目,启动.查看数据库,发现我们的表已经被创建好.表名为"window_file" 有7个字段:Discriminator id date name type file_cout size插入一条纪录,会发现,Discriminator的值是系统自动我们插入的..
采用这种式有一个不好的地方:当页面需要进行展示的时候,我们需要对记录的类型的进行判断,因为folder的size为nll Document类型的file_count为null,不进行判断,则会报nullPointException.而我们的Discrimination不能在页面上进行获取.所以通常做法是:多加一个字段,可以让其值保持与Discriminator的一样,或者重新创建一个Dto对象(简单的pojo),拥有这七个属性,专门用与在页面上进行显示,个人比较推荐后面的这种试,原因不多说,既然涉及到hibernate就会跟session有关,如果session关闭,采用后一种方式在页面上进行展示时也不会报NullPointException.
2.每个类分层结构一张表 这种映射方式为每个类创建一个表。在每个类对应的表中只需包含和这个类本身的属性对应的字段,子类对应的表参照父类对应的表,使用每个子类一张表 (table per subclass)策略,需要把@javax.persistence.Inheritance 注释的strategy 属性设置为InheritanceType.JOINED
代码如下:
看下数据库:生成了三张表,并分别有如下字段
animal : id color name
bird : speed birdId(既为主键,又为外键)
dog : legs dogId(既为主键,又为外键)
现在写一个JSP页面,上面有name legs color输入框(即创造一条狗),当我们save成功以后,查看数据库发现animal表有值,dog有值,但bird没有,dog表中的dogId的值等于animal中的id. 这种方式也就是我们常用的外键设计方式.一般情况下推荐使用这种方式.
3.每个具体类一张表(table per concrete class)
这种映射方式为每个类创建一个表。在每个类对应的表中包含和这个类所有属性(包括从超类继承的属性)对应的字段,使用每个具体类一张表(table per concrete class)策略,需要把@javax.persistence.Inheritance 注释的strategy 属性设置为InheritanceType.TABLE_PER_CLASS
此种方式,代码我就不贴了.. 把Animal中的inheritance改过来.去掉Dog和Bird类中的PrimaryKeyJoinColumn标注.还有一点非常重要,Animal类的主键生成策略不能自动生成了需要使用@Column(columnDefinition="integer")..进入数据库,删除animal dog brid三张表.重新编译运行项目.再进入数据库,依然是三张表,不过这三张表和以往的已经不同了..各自都包括了自己应有的属性.什么意思列?父类包含了自己的属性,而子类包括了从父类继续来的属性..
这种方式,不推荐使用,理解有三:
1>如果父类的属性特别多,那么在数据量大的时候,会产生很多见冗涂.
2> 查询所有Animal时,因为他是最继承树中的根,查询结果会得到所有继承于Animal类的记录
delete from delete from Vehicle a 执行该操作会删除自身对应记录,还会删除所有继承Vehicle的记录,因为他是最继承树中的根,就相当于清除整个表的数据a
1.A.B.C共用一张表
2.每个类分层结构一张表A.B.C各一张表,各自包含自己的属性.
3.A.B.C各一张表.
首先,我们针对第一种情况,进行分析.
[共用一张表]
首先我们定义基类(本例以文件为例,子类分别为文件夹和文件)
@Entity @Inheritance(strategy=InheritanceType.SINGLE_TABLE) @Table(name="window_file") @DiscriminatorColumn(name="Discriminator", discriminatorType = DiscriminatorType.STRING, length=30) @DiscriminatorValue("WindowFile") public class WindowFile { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Integer id; @Basic @Column(name="name") private String name; @Basic @Column(name="type") private String type; @Basic @Column(name="date") private String date; //getter setter......
分别再定义两个子类
@Entity @DiscriminatorValue("Folder") public class Folder extends WindowFile { @Basic @Column(name="file_count") private Integer fileCount; public Integer getFileCount() { return fileCount; } public void setFileCount(Integer fileCount) { this.fileCount = fileCount; } }
@Entity @DiscriminatorValue("Document") public class Document extends WindowFile { @Basic @Column(name="size") private String size; public String getSize() { return size; } public void setSize(String size) { this.size = size; }
仔细观查,你会发现,除了基类上指定了@Table属性外,两个子类均没有指定,而且还有几个特殊的地方
1>父类中的@Inheritance(strategy=InheritanceType.SINGLE_TABLE):继承表标,指定实现方式为一张表,即所有的对象一张表.
2>父类中的@DiscriminatorColumn(name="Discriminator",
discriminatorType = DiscriminatorType.STRING,
length=30) 其实这个字段就是一个区分字段,我们平时自己设计数据库的时候,有时候也会在表中加入一个字段用于判断该记录的类型,那么这个字段就是同样功能,name为自定义的.
3>三个类都有这个注解:@DiscriminatorValue("WindowFile"),很显明,明白了第2>点,这点也很容易理解,就是上面那个字段的值,当这个字段值为"windowFile"时,他就是基类,为"Document"时,就是Document类....这个值是自定义的..
配置好项目,启动.查看数据库,发现我们的表已经被创建好.表名为"window_file" 有7个字段:Discriminator id date name type file_cout size插入一条纪录,会发现,Discriminator的值是系统自动我们插入的..
采用这种式有一个不好的地方:当页面需要进行展示的时候,我们需要对记录的类型的进行判断,因为folder的size为nll Document类型的file_count为null,不进行判断,则会报nullPointException.而我们的Discrimination不能在页面上进行获取.所以通常做法是:多加一个字段,可以让其值保持与Discriminator的一样,或者重新创建一个Dto对象(简单的pojo),拥有这七个属性,专门用与在页面上进行显示,个人比较推荐后面的这种试,原因不多说,既然涉及到hibernate就会跟session有关,如果session关闭,采用后一种方式在页面上进行展示时也不会报NullPointException.
2.每个类分层结构一张表 这种映射方式为每个类创建一个表。在每个类对应的表中只需包含和这个类本身的属性对应的字段,子类对应的表参照父类对应的表,使用每个子类一张表 (table per subclass)策略,需要把@javax.persistence.Inheritance 注释的strategy 属性设置为InheritanceType.JOINED
代码如下:
//三个类我一起贴出来..偷下懒 @Entity @Table(name="animal") @Inheritance(strategy = InheritanceType.JOINED ) public class Animal { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Integer id; @Column(name="name") private String name; @Column(name="color") private String color; //getter...setter } @Entity @Table(name="bird") @PrimaryKeyJoinColumn(name="BirdId") public class Bird extends Animal { @Column(name="speed") private String speed; public String getSpeed() { return speed; } public void setSpeed(String speed) { this.speed = speed; } } @Entity @Table(name="Dog") @PrimaryKeyJoinColumn(name="DogId") public class Dog extends Animal { @Column(name="legs") private Integer legs; public Integer getLegs() { return legs; } public void setLegs(Integer legs) { this.legs = legs; } }
看下数据库:生成了三张表,并分别有如下字段
animal : id color name
bird : speed birdId(既为主键,又为外键)
dog : legs dogId(既为主键,又为外键)
现在写一个JSP页面,上面有name legs color输入框(即创造一条狗),当我们save成功以后,查看数据库发现animal表有值,dog有值,但bird没有,dog表中的dogId的值等于animal中的id. 这种方式也就是我们常用的外键设计方式.一般情况下推荐使用这种方式.
3.每个具体类一张表(table per concrete class)
这种映射方式为每个类创建一个表。在每个类对应的表中包含和这个类所有属性(包括从超类继承的属性)对应的字段,使用每个具体类一张表(table per concrete class)策略,需要把@javax.persistence.Inheritance 注释的strategy 属性设置为InheritanceType.TABLE_PER_CLASS
此种方式,代码我就不贴了.. 把Animal中的inheritance改过来.去掉Dog和Bird类中的PrimaryKeyJoinColumn标注.还有一点非常重要,Animal类的主键生成策略不能自动生成了需要使用@Column(columnDefinition="integer")..进入数据库,删除animal dog brid三张表.重新编译运行项目.再进入数据库,依然是三张表,不过这三张表和以往的已经不同了..各自都包括了自己应有的属性.什么意思列?父类包含了自己的属性,而子类包括了从父类继续来的属性..
这种方式,不推荐使用,理解有三:
1>如果父类的属性特别多,那么在数据量大的时候,会产生很多见冗涂.
2> 查询所有Animal时,因为他是最继承树中的根,查询结果会得到所有继承于Animal类的记录
delete from delete from Vehicle a 执行该操作会删除自身对应记录,还会删除所有继承Vehicle的记录,因为他是最继承树中的根,就相当于清除整个表的数据a
- 关于JPA实现类的继承
- 【Java 】--jpa中继承的实现
- JPA的继承映射
- JPA实体继承的映射
- JPA实体继承的映射
- Hibernate的JPA 继承方式
- JPA实体继承的映射
- 简单实现JPA实体继承映射
- 关于JPA的简介
- c# 关于继承类中构造函数的实现
- jpa继承
- JPA:继承
- 关于Hibernate实现继承树的问题
- 关于存钱的继承接口实现
- 关于实现c#多继承的总结
- JPA实现的CRUD
- JPA实体继承关系的映射策略
- JPA实体继承实体的映射策略
- ActivityManager与Proxy模式的运用
- iOS杂谈5—统计 xcode里面代码量
- Mac下MonoDevelop中文乱码解决方法
- 年产30万《毫米蓝宝石晶棒》项目可行性研究报告
- 解密Redis持久化
- 关于JPA实现类的继承
- 黑马程序员-学习日记13(IO流 1 )
- ListView 下拉更新
- lucene4.1.0 demo (jsp)配置
- 九度OJ 1463 贪心算法、优先队列、运算符重载之《招聘会》
- RTSP 流媒体播放地址
- MBR, EBR, Partition Table(分区表)
- EXCEL中发现不可读的内容。是否恢复此工作薄的内容?如果信任此工作薄的来源,请单击”是“
- 常用shell脚本