Java for Web学习笔记(一二六)映射(2):自定义类作为Entity属性

说明

在之前的学习中,表格的一列对应Entity的一个属性。数据库表格的列都是比较简单的类型,由此也限制了属性也只能是简单的类型。本文将学习利用@Embeddable 实现多个类映射到复杂类型。

多个列映射到类

数据表格结构:

CREATE TABLE `Person` (
  `PersonId` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `FirstName` varchar(60) COLLATE utf8_unicode_ci NOT NULL,
  `LastName` varchar(60) COLLATE utf8_unicode_ci NOT NULL,
  `PhoneNumber_CountryCode` varchar(5) COLLATE utf8_unicode_ci NOT NULL,
  `PhoneNumber_Number` varchar(15) COLLATE utf8_unicode_ci NOT NULL,
  PRIMARY KEY (`PersonId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

其中列PhoneNumber_CountryCode和PhoneNumber_Number都是和电话相关的信息,我们将其整合到一个类PhoneNumber。

@Embeddable 嵌入类

PhoneNumber是Entity Person中的一个属性,不是简单的类型,是一个自定的类。

/*【1】@Embeddable标记表明这是Entity的嵌入类,其属性将映射表格的列。
 * 由此,这个类也必须在Entity扫描的范围内。
 * 当注意,有些列是不能作为嵌入列,即标记@Id的主键和@EmbeddedId */
@Embeddable
public class PhoneNumber {
    private String countryCode;
    private String number;

    //【2】对各类的描述和Entity的一样
    @Basic
    @Column(name="PhoneNumber_CountryCode")
    public String getCountryCode() { ... }
    public void setCountryCode(String countryCode) { ... }

    @Basic
    @Column(name="PhoneNumber_Number")
    public String getNumber() { ... }
    public void setNumber(String number) { ... }
}

Entity中引入嵌入类作为属性

@Entity
public class Person {
    private long id;
    private String firstName;
    private String lastName;	
    private PhoneNumber phoneNumber;

    ...
    //【1】很简单,标记@Embeded,表示这个属性的映射需要进一步去分解
    @Embedded
    public PhoneNumber getPhoneNumber() { ... }
    public void setPhoneNumber(PhoneNumber phoneNumber) { ... }
}

多重嵌套

表格增加地址信息

CREATE TABLE `Person` (
  `PersonId` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `FirstName` varchar(60) COLLATE utf8_unicode_ci NOT NULL,
  `LastName` varchar(60) COLLATE utf8_unicode_ci NOT NULL,
  `PhoneNumber_CountryCode` varchar(5) COLLATE utf8_unicode_ci NOT NULL,
  `PhoneNumber_Number` varchar(15) COLLATE utf8_unicode_ci NOT NULL,
  `Address_Street` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
  `Address_City` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
  `Address_State` varchar(100) COLLATE utf8_unicode_ci DEFAULT NULL,
  `Address_Country` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
  `Address_PostalCode_Code` varchar(10) COLLATE utf8_unicode_ci NOT NULL,
  `Address_PostalCode_Suffix` varchar(5) COLLATE utf8_unicode_ci DEFAULT NULL,
  PRIMARY KEY (`PersonId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

我们增加一定难度,Address这个类不仅作为Person的属性,也作为其他Entity属性,但不同表格的列的名字可能会不一样。有或者PostalCode作为其他Entity的属性,由于表格不一样,对应的列的名字也可能不一样。由此,我们可以在Entity中指定,这个层层嵌套对应下去的列名是什么(或者修订为什么)

嵌套的实现

在嵌套类中可以通过@Embedded来说明映射进一步分解。

@Embeddable
public class PostalCode {
	private String code;
	private String suffix;
	
	@Basic
	@Column(name="PostalCode_Code")  //假设映射为其他表的列名,非Person表格的列名
	public String getCode() { ... }
	public void setCode(String code) { ... }
	
	@Basic
	@Column(name="PostalCode_Suffix") //假设映射为其他表的列名,非Person表格的列名
	public String getSuffix() { ...}
	public void setSuffix(String suffix) { ...}
}
@Embeddable
public class Address {
    private String street;
    private String city;
    private String state;
    private String country;
    private PostalCode postalCode; 
    ... ...
    // 通过@Embedded来说明映射进一步分解,根据PostalCode类所指明的方式进行映射。
    // 通过@Embedded可以进行层次嵌套
    @Embedded
    public PostalCode getPostalCode() { ... }
    public void setPostalCode(PostalCode postalCode) { ... }
}

在Entity中重新修订映射的列名

@Entity
public class Person {
    private long id;
    private String firstName;
    private String lastName;	
    private PhoneNumber phoneNumber;
    private Address address;
    ... ...  
    /* 通过@AttributeOverrides来对映射的列名们进行修订,如果只对一个列名进行修订,可以用@AttributeOverride
    (1)原则上我们也可以在Address对属性和列的映射进行修订,但建议不要这样做。
         最终和表格真正映射的是Entity,如果修订,应在Entity上。
    (2)name是属性,postalCode.code指的标记所在属性(address)的属性postalCode的属性code。
         注意address无需说明,因为这就是在其上的标记。  */
    @Embedded
    @AttributeOverrides(value = { 
            @AttributeOverride(name = "postalCode.code", column = @Column(name = "Address_PostalCode_Code")),
            @AttributeOverride(name = "postalCode.suffix", column = @Column(name = "Address_PostalCode_Suffix"))
            })
    public Address getAddress() { ... }
    public void setAddress(Address address) { ... }
}

相关链接:我的Professional Java for Web Applications相关文章

猜你喜欢

转载自blog.csdn.net/flowingflying/article/details/81102120
今日推荐