类图和ORM关系(二)

    技术2022-05-11  92

    3         继承映射 3.1    一个继承结构使用一个表(Table per class hierarchy) 这种方法在JPA中是InheritanceType.SINGLE_TABLE。 优点:简单,性能好,是多态操作性能最好的方式。 缺点:子类的字段必须定义成nullable,数据可能不是规范化的,存在数据一致性和易维护问题。 适用:简单继承结构,特别是子类属性比较少的情况。 例子:Billing是父类,CreditCard和BankAccount是两个子类。 @Entity@Inheritance(strategy = InheritanceType.SINGLE_TABLE)@DiscriminatorColumn(name = " DISC " , discriminatorType = DiscriminatorType.STRING)@DiscriminatorValue( " BILLING " ) public   abstract   class  Billing1  {    @Id private int id;    private String owner;} @Entity@DiscriminatorValue( " CREDITCARD " ) public   class  CreditCard1  extends  Billing1  {    private String number;} @Entity@DiscriminatorValue( " BANK " ) public   class  BankAccount1  extends  Billing1  {    private String account;} 数据库表只有一个:create table  " BILLING1 " (     " DISC "  VARCHAR( 31 ) not  null ,    " ID "  INTEGER not  null ,    " OWNER "  VARCHAR( 255 ),    " ACCOUNT "  VARCHAR( 255 ),    " NUMBER "  VARCHAR( 255 ),    constraint  " SYS_PK_1845 "  primary key ( " ID " ));create unique index  " SYS_PK_1845 "  on  " BILLING1 " ( " ID " );   3.2    各子类使用单独的表(Table per subclass) 这种方法在JPA中是InheritanceType.JOINED。 优点:数据是规范化的,支持多态查询和多态关联。 缺点:对复杂的继承结构,该方法性能不好。 适用:需要多态查询和多态关联,特别是子类的属性较多的情况。 例子: @Entity@Inheritance(strategy = InheritanceType.JOINED) public   class  Billing2  {    @Id private int id;    private String owner;} @Entity public   class  CreditCard2  extends  Billing2  {    private String number;    } @Entity public   class  BankAccount2  extends  Billing2  {   private String account;} 数据库表是:create table  " BILLING2 " (     " ID "  INTEGER not  null ,    " OWNER "  VARCHAR( 255 ),    constraint  " SYS_PK_1846 "  primary key ( " ID " ));create unique index  " SYS_PK_1846 "  on  " BILLING2 " ( " ID " );create table  " CREDITCARD2 " (     " ID "  INTEGER not  null ,    " NUMBER "  VARCHAR( 255 ),    constraint  " SYS_PK_1874 "  primary key ( " ID " ));alter table  " CREDITCARD2 "       add constraint  " FK4FC2E7898F29E03D "      foreign key ( " ID " )     references  " BILLING2 " ( " ID " );create unique index  " SYS_PK_1874 "  on  " CREDITCARD2 " ( " ID " );create index  " SYS_IDX_1944 "  on  " CREDITCARD2 " ( " ID " );create table  " BANKACCOUNT2 " (     " ID "  INTEGER not  null ,    " ACCOUNT "  VARCHAR( 255 ),    constraint  " SYS_PK_1842 "  primary key ( " ID " ));alter table  " BANKACCOUNT2 "       add constraint  " FKDB157E218F29E03D "      foreign key ( " ID " )     references  " BILLING2 " ( " ID " );create unique index  " SYS_PK_1842 "  on  " BANKACCOUNT2 " ( " ID " );create index  " SYS_IDX_1904 "  on  " BANKACCOUNT2 " ( " ID " );   3.3    支持多态的各具体实体类使用单独的表(Table per concrete class with implicit polymorphism)。 优点:比较简单。 缺点:对多态关联的支持不好,多态查询也有问题(一个多态查询需要对应多条查询语句)。 适用:复杂继承结构中的顶层结构(一般不需要多态操作),并且基类修改的可能性不大的情况。特别适用于不采用JPA接口(如JDBC)的查询。 例子: @MappedSuperclass public   class  Billing3  {    private String owner;} @Entity public   class  CreditCard3  extends  Billing3  {    @Id private int id;    private String number;} @Entity public   class  BankAccount3  extends  Billing3  {    @Id private int id;    private String account;} 数据库表是:create table  " CREDITCARD3 " (     " ID "  INTEGER not  null ,    " OWNER "  VARCHAR( 255 ),    " NUMBER "  VARCHAR( 255 ),    constraint  " SYS_PK_1875 "  primary key ( " ID " ));create unique index  " SYS_PK_1875 "  on  " CREDITCARD3 " ( " ID " );create table  " BANKACCOUNT3 " (     " ID "  INTEGER not  null ,    " OWNER "  VARCHAR( 255 ),    " ACCOUNT "  VARCHAR( 255 ),    constraint  " SYS_PK_1843 "  primary key ( " ID " ));create unique index  " SYS_PK_1843 "  on  " BANKACCOUNT3 " ( " ID " );   3.4    采用Union的各具体实体类使用单独的表(Table per concrete class with unions) 这种方式在JPA中是InheritanceType.TABLE_PER_CLASS。 优点:支持多态查询和多态关联。 缺点:TABLE_PER_CLASS在JPA中是可选的,也就是说不能保证每个EJB 3.0的容器都支持这种方式。 适用:如果需要考虑可移植性问题,不推荐使用本方法。 例子: @Entity@Inheritance(strategy  =  InheritanceType.TABLE_PER_CLASS) public   class  Billing4  {    @Id private int id;    private String owner;} @Entity public   class  CreditCard4  extends  Billing4  {    private String number;} @Entity public   class  BankAccount4  extends  Billing4  {    private String account;} 数据库表是:create table  " BILLING4 " (     " ID "  INTEGER not  null ,    " OWNER "  VARCHAR( 255 ),    constraint  " SYS_PK_1847 "  primary key ( " ID " ));create unique index  " SYS_PK_1847 "  on  " BILLING4 " ( " ID " );create table  " CREDITCARD4 " (     " ID "  INTEGER not  null ,    " OWNER "  VARCHAR( 255 ),    " NUMBER "  VARCHAR( 255 ),    constraint  " SYS_PK_1876 "  primary key ( " ID " ));create unique index  " SYS_PK_1876 "  on  " CREDITCARD4 " ( " ID " );create table  " BANKACCOUNT4 " (     " ID "  INTEGER not  null ,    " OWNER "  VARCHAR( 255 ),    " ACCOUNT "  VARCHAR( 255 ),    constraint  " SYS_PK_1844 "  primary key ( " ID " ));create unique index  " SYS_PK_1844 "  on  " BANKACCOUNT4 " ( " ID " ); 由于Billing类不是抽象类,所以数据库中有Billing4表;可以将Billing设计为abstract,则不会出现Billing4表。   任何一种映射方法可以从抽象类继承,也可以从实体类继承;但是JPA规范不允许从接口继承(Hibernate支持从接口继承)。另外,还可以混用继承方法,例如采用一个继承结构使用一个表,但是某个表采用各子类使用单独的表方法。最后,在选用不同的继承映射方法前,请考虑是否可以采用设计模式将继承转化为合成,使业务模型更趋简单。 本文的最后一部分将描述实体和实体的关联关系。

    最新回复(0)