实体类和我们的关系数据库中的表之间的映射关系,可能是我们在使用Hibernate中最重要,最必须掌握的技能啦,这个是非常有必要的,使用的方式有很多种,我自己觉得可能注解的方式写起来更加的简单,但是不好,不利余修改,比较分散。而采用XML的方式的话,更利于我们去修改啦!
有几种方式实现我们的关系的映射
using the Hibernate legacy XML files approach known as hbm.xml
JPA annotations are in the javax.persistence.* package. Hibernate specific extensions are in org.hibernate.annotations.*. 我们下面看个例子。写得很多。对了哈,关于注解的实现原理,我也想写一篇,先把这个文档看完再说。
Hibernate一般我们把注解写在get上面,spring注解写在set上面。这个还是有记住的
package eg;
@Entity 表明这个是个实体类
@Table(name="cats") 对应数据库中的表
@Inheritance(strategy=SINGLE_TABLE) 单继承
@DiscriminatorValue("C") 鉴别器的值为(就是为了区分父类子类的情况),鉴别器在表中的名称为,类型为,这个为了在集成中把所有的都集中在一个表中,进行区分,我看过的,一种的全部放在一起,一种是父亲有的放在父类,子类有的在弄一张表单独存放的这个是Join类型的,还有我们等会慢慢的说@DiscriminatorColumn(name="subclass", discriminatorType=CHAR)
public class Cat {
@Id 这个就是key,主键
@GeneratedValue 生成的策略,有increament,native....
public Integer getId() { return id; }
public void setId(Integer id) { this.id = id; }
private Integer id;
public BigDecimal getWeight() { return weight; }
public void setWeight(BigDecimal weight) { this.weight = weight; }
private BigDecimal weight;
@Temporal(DATE) 因为时间有很多种在数据库中,我们到底转换成什么的类型
@NotNull 不为空
@Column(updatable=false) 这个列,不允许更新
public Date getBirthdate() { return birthdate; }
public void setBirthdate(Date birthdate) { this.birthdate = birthdate; }
private Date birthdate;
@org.hibernate.annotations.Type(type="eg.types.ColorUserType")
@NotNull
@Column(updatable=false)
public ColorType getColor() { return color; }
public void setColor(ColorType color) { this.color = color; }
private ColorType color;
@NotNull @Column(updatable=false)
public String getSex() { return sex; }
public void setSex(String sex) { this.sex = sex; }
private String sex;
@NotNull @Column(updatable=false)
public Integer getLitterId() { return litterId; }
public void setLitterId(Integer litterId) { this.litterId = litterId; }
private Integer litterId;
@ManyToOne 多对一
下面这个就是我们生成表的策略,慢慢的说
@JoinColumn(name="mother_id", updatable=false)
public Cat getMother() { return mother; }
public void setMother(Cat mother) { this.mother = mother; }
private Cat mother;
@OneToMany(mappedBy="mother") 这个属性下面有个链接自己去看看http://blog.sina.com.cn/s/blog_697b968901016s7f.html
@OrderBy("litterId")
public Set<Cat> getKittens() { return kittens; }
public void setKittens(Set<Cat> kittens) { this.kittens = kittens; }
private Set<Cat> kittens = new HashSet<Cat>();
}
@Entity
@DiscriminatorValue("D")
public class DomesticCat extends Cat {
public String getName() { return name; }
public void setName(String name) { this.name = name }
private String name;
}
@Entity
public class Dog { ... }
上面的好多的注解,记不住没关系。慢慢的领悟就好了。你真的在做项目的时候,可能在写的时候,先自己会吧所有可以写的属性罗列一下,放在单独的文档,需要的时候在复制 一下。但是前提是你能够理解这些东西,到底的作用是什么。我们好的方式是,把XML和我们的annotations这两个做个比较
XML的方式
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="eg">
<class name="Cat" table="cats" discriminator-value="C">
<id name="id">
<generator class="native"/>
</id>
<discriminator column="subclass" type="character"/>
<property name="weight"/>
<property name="birthdate" type="date" not-null="true" update="false"/>
<property name="color" type="eg.types.ColorUserType" not-null="true" update="false"/>
<property name="sex" not-null="true" update="false"/>
<property name="litterId" column="litterId" update="false"/>
<many-to-one name="mother" column="mother_id" update="false"/>
<set name="kittens" inverse="true" order-by="litter_id">
<key column="mother_id"/>
<one-to-many class="Cat"/>
</set>
<subclass name="DomesticCat" discriminator-value="D">
<property name="name" type="string"/>
</subclass>
</class>
<class name="Dog">
<!-- mapping for Dog could go here -->
</class>
</hibernate-mapping>
看了两个例子,我们慢慢的来了解这些属性吧。
Entity
An entity is a regular Java object (aka POJO) which will be persisted by Hibernate.
Table
@Table lets you define the table the entity will be persisted into. If undefined, the table name is the unqualified class name of the entity. 数据库中的表名,如果没有定义的话,就是我们的实体类的名字啦
@Immutable
Some entities are not mutable. They cannot be updated by the application. This allows Hibernate to make some minor performance optimizations 有些实体是不可变的,可以让他不可以更新
-@discriminator-value 用于继承的
(optional - defaults to the class name): a value that distinguishes individual subclasses that is used for polymorphic behavior. Acceptable values include null and not null.
@dynamicInsert / dynamicUpdate
指定用于 UPDATE 、INSERT的 SQL 将会在运行时动态生成,
并且只更新那些改变过的字段。
-@optimistic-lock
optional - defaults to version): determines the optimistic locking strategy. 如果你打开了dynamic-update,你可以选择几种乐观锁定的策略:
Tables | Are |
---|---|
version | check the version/timestamp columns |
all | check all columns |
dirty | check the changed columns, allowing some concurrent updates |
none | do not use optimistic locking |
- @Id
Mapped classes must declare the primary key column of the database table.
@Entity
public class Flight implements Serializable {
...
@Column(updatable = false, name = "flight_name", nullable = false, length=50)
public String getName() { ... }
@Column(
name="columnName"; (1)
boolean unique() default false; (2)
boolean nullable() default true; (3)
boolean insertable() default true; (4)
boolean updatable() default true; (5)
String columnDefinition() default ""; (6)
String table() default ""; (7)
int length() default 255; (8)小数点精度
int precision() default 0; // decimal precision (9)
int scale() default 0; // decimal scale
. Property mapping with hbm.xml
<property
name="propertyName" (1)
column="column_name" (2)
type="typename" (3)
update="true|false" (4)
insert="true|false" (4)
formula="arbitrary SQL expression" (5)
access="field|property|ClassName" (6)
lazy="true|false" (7)
unique="true|false" (8)
not-null="true|false" (9)
optimistic-lock="true|false" (10)
generated="never|insert|always" (11)
node="element-name|@attribute-name|element/@attribute|."
index="index_name"
unique_key="unique_key_id"
length="L"
precision="P"
scale="S"
/>
继承的策略
存储的策略有三种:
1。全部存放到一张表中
2。加入子类策略:每个类和子类是一个表 现在和每个表存储特定于给定的属性 子类。 实体的状态被存储在它 相应的类表和所有它的超类。父类的属放在父类,新产出的放在我们的子类中新建表
3。表每个类策略:每个具体类一个表 子类是现在和每个表持续的属性 类和它的超类。 然后存储实体的状态 完全在专用表类。
1。单个表的策略
@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(
name="planetype",
discriminatorType=DiscriminatorType.STRING
)
@DiscriminatorValue("Plane")
The discriminator column contains marker values that tell the persistence layer what subclass to instantiate for a particular row
public class Plane { ... }
@Entity
@DiscriminatorValue("A320")
public class A320 extends Plane { ... }
xml
subclass
name="ClassName" (1)
discriminator-value="discriminator_value" (2)
proxy="ProxyInterface" (3)
lazy="true|false" (4)
dynamic-update="true|false"
dynamic-insert="true|false"
entity-name="EntityName"
node="element-name"
extends="SuperclassName">
<property .... />
.....
</subclass>
<hibernate-mapping>
<subclass name="DomesticCat" extends="Cat" discriminator- value="D">
<property name="name" type="string"/>
</subclass>
</hibernate-mapping
>
每个子类一张表(Table per subclass)
<class name="Payment" table="PAYMENT">
<id name="id" type="long" column="PAYMENT_ID">
<generator class="native"/>
</id>
<property name="amount" column="AMOUNT"/>
...
<joined-subclass name="CreditCardPayment" table="CREDIT_PAYMENT">
<key column="PAYMENT_ID"/>
<property name="creditCardType" column="CCTYPE"/>
...
</joined-subclass>
<joined-subclass name="CashPayment" table="CASH_PAYMENT">
<key column="PAYMENT_ID"/>
...
</joined-subclass>
<joined-subclass name="ChequePayment" table="CHEQUE_PAYMENT">
<key column="PAYMENT_ID"/>
...
</joined-subclass>
</class
>
@JoinTable和@JoinColumn的讲解,写的不错!
http://www.cnblogs.com/mingforyou/p/4615969.html
@Entity @Table(name="CATS")
@Inheritance(strategy=InheritanceType.JOINED)
public class Cat implements Serializable {
@Id @GeneratedValue(generator="cat-uuid")
@GenericGenerator(name="cat-uuid", strategy="uuid")
String getId() { return id; }
...
}
@Entity @Table(name="DOMESTIC_CATS")
@PrimaryKeyJoinColumn(name="CAT")
public class DomesticCat extends Cat {
public String getName() { return name; }
}
每个具体类一张表(Table per concrete class)
<class name="Payment">
<id name="id" type="long" column="PAYMENT_ID">
<generator class="sequence"/>
</id>
<property name="amount" column="AMOUNT"/>
...
<union-subclass name="CreditCardPayment" table="CREDIT_PAYMENT">
<property name="creditCardType" column="CCTYPE"/>
...
</union-subclass>
<union-subclass name="CashPayment" table="CASH_PAYMENT">
...
</union-subclass>
<union-subclass name="ChequePayment" table="CHEQUE_PAYMENT">
...
</union-subclass>
</class
这些都看完了,是不是特别复杂,没看过数据库的,简直就是晕死。还有好多的特性。慢慢看
a foreign key in one table is referencing the primary key column(s) of the target table. 引用一个外键
@Entity
public class Flight implements Serializable {
@ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE} )
@JoinColumn(name="COMP_ID")
public Company getCompany() {
return company;
}
...
}
这个就是个外键的引用啦,如果没有指定我们的JoinColumn的名字的话,会有个默认的名字加入到Flight这个表中比如 company_id