组件属性

组件属性到底是什么意思:持久化类的实体的属性并不是基本的数据类型,也不是字符串,日期等标量类型的变量,而是一个复合类型的对象。在持久化的过程中仅仅​被当作值类型,而非引用另一个持久化实体

组件属性的类型可以是自己自定义的任何类

看使用就晓得了:Name是个组件属性,我们不能简单的根据@Column简单的使用涩

@Entity
@Table(name="person_inf")
public class Person
{
@Id @Column(name="person_id")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
private int age;
// 组件属性name,什么都没有做
private Name name;

// id的setter和getter方法
public void setId(Integer id)
{
this.id = id;
}
public Integer getId()
{
return this.id;
}

// age的setter和getter方法
public void setAge(int age)
{
this.age = age;
}
public int getAge()
{
return this.age;
}

// name的setter和getter方法
public void setName(Name name)
{
this.name = name;
}
public Name getName()
{
return this.name;
}
}

下面是定义我们的组件

这个@Embeddable修饰的类,表明这个是个组件,组件类中使用@Cloumn表明在实体中对应的列

@Parent 告知Hibernate owner不是个普通的属性,而是包含Name属性的person实体

@Embeddable 嵌入的意思
public class Name
{
// 定义first成员变量
@Column(name="person_firstname")
private String first;
// 定义last成员变量
@Column(name="person_lastname")
private String last;
// 引用拥有该Name的Person对象
@Parent // ①
private Person owner;

// 无参数的构造器
public Name()
{
}
// 初始化全部成员变量的构造器
public Name(String first , String last)
{
this.first = first;
this.last = last;
}

// first的setter和getter方法
public void setFirst(String first)
{
this.first = first;
}
public String getFirst()
{
return this.first;
}

// last的setter和getter方法
public void setLast(String last)
{
this.last = last;
}
public String getLast()
{
return this.last;
}

// owner的setter和getter方法
public void setOwner(Person owner)
{
this.owner = owner;
}
public Person getOwner()
{
return this.owner;
}

}

除此之外,Hibernate还提供了另外的一种映射策略,无需再组件上使用使用@Embeddable注解,而是直接在持久化类中使用@Embedd修饰组件,如果需要为组件的子属性指定列名,可以使用@AttributeOverrides(name=”哪个属性“,Column=@Colunm(name=”XXXX“))

不需要记得,大概晓得这回事就行了。文档自己找

代码

public class Name
{
// 定义first成员变量
private String first;
// 定义last成员变量
private String last;
// 引用拥有该Name的Person对象
@Parent
private Person owner;
}
Name上面么得啦,parent还是有的,这个和Transient差不多,不要这个属性,但是有多了层意思

@Embedded
@AttributeOverrides({
@AttributeOverride(name="first", column = @Column(name="person_firstname")),
@AttributeOverride(name="last", column = @Column(name="person_lastname"))
})
private Name name;

组件作为复合主键

这种情况下,还是有些特殊的操作的

组件满足,无参够造函数 ,实现序列话接口,从写​equals()和hasCode方法,也就是根据此区分组件对象​类似hash

当使用复合主键是,Hibernate无法为你主动的生成主键值,程序必须为持久化对象分配主键实例。

当持久化的主键为联合主键是,程序需要使用@Embeddedld来修饰该主键,和之前讲的类似,主要是现在是主键啦

为了标识唯一的属性,从写下面的来个方式哦,这些是必须的

public class Name
implements java.io.Serializable
{
// 定义first成员变量
private String first;
// 定义last成员变量
private String last;

// 无参数的构造器
public Name()
{
}
// 初始化全部成员变量的构造器
public Name(String first , String last)
{
this.first = first;
this.last = last;
}

// first的setter和getter方法
public void setFirst(String first)
{
this.first = first;
}
public String getFirst()
{
return this.first;
}

// last的setter和getter方法
public void setLast(String last)
{
this.last = last;
}
public String getLast()
{
return this.last;
}

// 重写equals()方法,根据first、last进行判断
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
if (obj != null && obj.getClass() == Name.class)
{
Name target = (Name)obj;
return target.getFirst().equals(getFirst())
&& target.getLast().equals(getLast());
}
return false;
}
// 重写hashCode()方法,根据first、last计算hashCode值
public int hashCode()
{
return getFirst().hashCode() * 31
+ getLast().hashCode();
}
}

看我们的实体类

@Entity
@Table(name="person_inf")
public class Person
{
// 以Name组件作为标识属性
@EmbeddedId
@AttributeOverrides({
// 指定
@AttributeOverride(name="first",
column = @Column(name="person_firstname")),
@AttributeOverride(name="last",
column = @Column(name="person_lastname"))
})
private Name name;
private int age;

// name的setter和getter方法
public void setName(Name name)
{
this.name = name;
}
public Name getName()
{
return this.name;
}

// age的setter和getter方法
public void setAge(int age)
{
this.age = age;
}
public int getAge()
{
return this.age;
}
}

多列作为联合主键

和我们上面的组件作为联合,其实效果意义都是一样的,就是分开写而已嘛,是不是。​我们主要是 区分hash不一样,怎么去标识一个为主键呢​?

和上面的要求一样的都需要无参构造 序列化 Hash区分

将持久化类直接使用多个@Id就行了,修饰这些属性。

@Entity
@Table(name="person_inf")
public class Person
implements java.io.Serializable
{
// 定义first属性,作为标识属性的成员
@Id
private String first;
// 定义last属性,作为标识属性的成员
@Id
private String last;
private int age;

// first的setter和getter方法
public void setFirst(String first)
{
this.first = first;
}
public String getFirst()
{
return this.first;
}

// last的setter和getter方法
public void setLast(String last)
{
this.last = last;
}
public String getLast()
{
return this.last;
}

// age的setter和getter方法
public void setAge(int age)
{
this.age = age;
}
public int getAge()
{
return this.age;
}

// 重写equals()方法,根据first、last进行判断
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
if (obj != null && obj.getClass() == Person.class)
{
Person target = (Person)obj;
return target.getFirst().equals(getFirst())
&& target.getLast().equals(getLast());
}
return false;
}

// 重写hashCode()方法,根据first、last计算hashCode值
public int hashCode()
{
return getFirst().hashCode() * 31
+ getLast().hashCode();
}
}