读书人

hibernate诠注使用

发布时间: 2012-09-17 12:06:51 作者: rapoo

hibernate注解使用

    声明实体Bean ????@Entity??public?class?Flight?implements?Serializable?{ ????Long?id; ????@Id????public?Long?getId()?{?return?id;?} ????public?void?setId(Long?id)?{?this.id?=?id;?} ??} ????@Entity?注解将一个类声明为实体?Bean,?@Id?注解声明了该实体Bean的标识属性。 ????Hibernate?可以对类的属性或者方法进行注解。属性对应field类别,方法的?getXxx()对应property类别。 ????定义表 ????通过?@Table?为实体Bean指定对应数据库表,目录和schema的名字。 ????@Entity??@Table(name="tbl_sky") ??public?class?Sky?implements?Serializable?{ ????... ????@Table?注解包含一个schema和一个catelog?属性,使用@UniqueConstraints?可以定义表的唯一约束。 ????@Table(name="tbl_sky", ????uniqueConstraints?=?{@UniqueConstraint(columnNames={"month",?"day"})} ??) ????上述代码在??"month"?和?"day"?两个?field?上加上?unique?constrainst. ????@Version?注解用于支持乐观锁版本控制。 ????@Entity??public?class?Flight?implements?Serializable?{ ?????... ?????@Version?????@Column(name="OPTLOCK") ?????public?Integer?getVersion()?{?...?} ??} ????version属性映射到?"OPTLOCK"?列,entity?manager?使用这个字段来检测冲突。?一般可以用?数字?或者?timestamp?类型来支持?version. ????实体Bean中所有非static?非?transient?属性都可以被持久化,除非用@Transient注解。 ????默认情况下,所有属性都用?@Basic?注解。 ????public?transient?int?counter;?//transient?property ????private?String?firstname;?//persistent?property ??@Transient??String?getLengthInMeter()?{?...?}?//transient?property ??String?getName()?{...?}?//?persistent?property ??@Basic??int?getLength()?{?...?}?//?persistent?property ??@Basic(fetch?=?FetchType.LAZY) ??String?getDetailedComment()?{?...?}?//?persistent?property ??@Temporal(TemporalType.TIME) ??java.util.Date?getDepartureTime()?{?...?}?//?persistent?property ??@Enumerated(EnumType.STRING) ??Starred?getNote()?{?...?}?//enum?persisted?as?String?in?database ????上述代码中?counter,?lengthInMeter?属性将忽略不被持久化,而?firstname,?name,?length?被定义为可持久化和可获取的。? ????@TemporalType.(DATE,TIME,TIMESTAMP)?分别Map?java.sql.(Date,?Time,?Timestamp). ????@Lob?注解属性将被持久化为?Blog?或?Clob?类型。具体的java.sql.Clob,?Character[],?char[]?和?java.lang.String?将被持久化为?Clob?类型.?java.sql.Blob,?Byte[],?byte[]?和?serializable?type?将被持久化为?Blob?类型。 ????@Lob??public?String?getFullText()?{ ?????return?fullText;??//?clob?type ??} ??????@Lob??public?byte[]?getFullCode()?{ ????return?fullCode;??//?blog?type ??} ????@Column?注解将属性映射到列。 ????@Entity??public?class?Flight?implements?Serializable?{ ?????... ?????@Column(updatable?=?false,?name?=?"flight_name",?nullable?=?false,?length=50) ?????public?String?getName()?{?...?} ????定义?name?属性映射到?flight_name?column,?not?null,?can't?update,?length?equal?50????@Column( ?????name="columnName";?(1)?列名 ?????boolean?unique()?default?false;?(2)????是否在该列上设置唯一约束 ?????boolean?nullable()?default?true;?(3)???列可空? ?????boolean?insertable()?default?true;?(4)?该列是否作为生成?insert语句的一个列 ?????boolean?updatable()?default?true;?(5)??该列是否作为生成?update语句的一个列 ?????String?columnDefinition()?default?"";?(6)??默认值 ?????String?table()?default?"";?(7)?????????????定义对应的表(deault?是主表) ?????int?length()?default?255;?(8)??????????????列长度 ?????int?precision()?default?0;?//?decimal?precision?(9)??decimal精度 ?????int?scale()?default?0;?//?decimal?scale????????(10)??decimal长度 ????嵌入式对象(又称组件)也就是别的对象定义的属性 ????组件类必须在类一级定义?@Embeddable?注解。在特定的实体关联属性上使用?@Embeddable?和?@AttributeOverride?注解可以覆盖该属性对应的嵌入式对象的列映射。 ????@Entity??public?class?Person?implements?Serializable?{ ?????//?Persistent?component?using?defaults ?????Address?homeAddress; ?????@Embedded?????@AttributeOverrides(?{ ????????@AttributeOverride(name="iso2",?column?=?@Column(name="bornIso2")?), ????????@AttributeOverride(name="name",?column?=?@Column(name="bornCountryName")?) ?????}?) ?????Country?bornIn; ?????... ??} ????@Embeddable??public?class?Address?implements?Serializable?{ ?????String?city; ?????Country?nationality;?//no?overriding?here ??} ????@Embeddable??public?class?Country?implements?Serializable?{ ?????private?String?iso2; ?????@Column(name="countryName")?private?String?name; ?????public?String?getIso2()?{?return?iso2;?} ?????public?void?setIso2(String?iso2)?{?this.iso2?=?iso2;?} ?????public?String?getName()?{?return?name;?} ?????public?void?setName(String?name)?{?this.name?=?name;?} ?????... ??} ????Person?类定义了?Address?和??Country?对象,具体两个类实现见上。 ????无注解属性默认值: ??????属性为简单类型,则映射为?@Basic??????属性对应的类型定义了?@Embeddable?注解,则映射为?@Embedded??????属性对应的类型实现了Serializable,则属性被映射为@Basic并在一个列中保存该对象的serialized版本。 ??????属性的类型为?java.sql.Clob?or?java.sql.Blob,?则映射到?@Lob?对应的类型。 ????映射主键属性 ????@Id?注解可将实体Bean中某个属性定义为主键,使用@GenerateValue注解可以定义该标识符的生成策略。 ??????AUTO?-??可以是?identity?column,?sequence?或者?table?类型,取决于不同底层的数据库 ????TABLE?-?使用table保存id值 ????IDENTITY?-?identity?column ????SEQUENCE?-?seque ????nce? ????@Id?@GeneratedValue(strategy=GenerationType.SEQUENCE,?generator="SEQ_STORE") ??public?Integer?getId()?{?...?} ????@Id?@GeneratedValue(strategy=GenerationType.IDENTITY) ??public?Long?getId()?{?...?} ????AUTO?生成器,适用与可移值的应用,多个@Id可以共享同一个?identifier生成器,只要把generator属性设成相同的值就可以。通过@SequenceGenerator?和?@TableGenerator?可以配置不同的?identifier?生成器。? ????<table-generator?name="EMP_GEN"???????table="GENERATOR_TABLE"???????pk-column-name="key"???????value-column-name="hi"???????pk-column-value="EMP"???????allocation-size="20"/> ??//and?the?annotation?equivalent ??@javax.persistence.TableGenerator( ???????name="EMP_GEN", ???????table="GENERATOR_TABLE", ???????pkColumnName?=?"key", ???????valueColumnName?=?"hi"???????pkColumnValue="EMP", ???????allocationSize=20??) ??<sequence-generator?name="SEQ_GEN"???????sequence-name="my_sequence"???????allocation-size="20"/> ??//and?the?annotation?equivalent ??@javax.persistence.SequenceGenerator( ???????name="SEQ_GEN", ???????sequenceName="my_sequence", ???????allocationSize=20??) ????The?next?example?shows?the?definition?of?a?sequence?generator?in?a?class?scope: ????@Entity??@javax.persistence.SequenceGenerator( ??????name="SEQ_STORE", ??????sequenceName="my_sequence"??) ??public?class?Store?implements?Serializable?{ ?????private?Long?id; ?????@Id?@GeneratedValue(strategy=GenerationType.SEQUENCE,?generator="SEQ_STORE") ?????public?Long?getId()?{?return?id;?} ??} ????Store类使用名为my_sequence的sequence,并且SEQ_STORE生成器对于其他类是不可见的。 ????通过下面语法,你可以定义组合键。 ??????将组件类注解为?@Embeddable,?并将组件的属性注解为?@Id????将组件的属性注解为?@EmbeddedId????将类注解为?@IdClass,并将该实体中所有主键的属性都注解为?@Id????@Entity??@IdClass(FootballerPk.class) ??public?class?Footballer?{ ????//part?of?the?id?key ????@Id?public?String?getFirstname()?{ ??????return?firstname; ????} ????public?void?setFirstname(String?firstname)?{ ???????this.firstname?=?firstname; ????} ????//part?of?the?id?key ????@Id?public?String?getLastname()?{ ??????return?lastname; ????} ????public?void?setLastname(String?lastname)?{ ??????this.lastname?=?lastname; ????} ????public?String?getClub()?{ ??????return?club; ????} ????public?void?setClub(String?club)?{ ?????this.club?=?club; ????} ????//appropriate?equals()?and?hashCode()?implementation ??} ????@Embeddable??public?class?FootballerPk?implements?Serializable?{ ????//same?name?and?type?as?in?Footballer ????public?String?getFirstname()?{ ??????return?firstname; ????} ????public?void?setFirstname(String?firstname)?{ ??????this.firstname?=?firstname; ????} ????//same?name?and?type?as?in?Footballer ????public?String?getLastname()?{ ??????return?lastname; ????} ????public?void?setLastname(String?lastname)?{ ?????this.lastname?=?lastname; ????} ????//appropriate?equals()?and?hashCode()?implementation ??} ????@Entity??@AssociationOverride(?name="id.channel",?joinColumns?=?@JoinColumn(name="chan_id")?) ??public?class?TvMagazin?{ ?????@EmbeddedId?public?TvMagazinPk?id; ?????@Temporal(TemporalType.TIME)?Date?time; ??} ??????@Embeddable??public?class?TvMagazinPk?implements?Serializable?{ ?????@ManyToOne?????public?Channel?channel; ?????public?String?name; ?????@ManyToOne?????public?Presenter?presenter; ??} ????映射继承关系 ????EJB支持3种类型的继承。 ??????Table?per?Class?Strategy:?the?<union-class>?element?in?Hibernate?每个类一张表 ????Single?Table?per?Class?Hierarchy?Strategy:?the?<subclass>?element?in?Hibernate?每个类层次结构一张表 ????Joined?Subclass?Strategy:?the?<joined-subclass>?element?in?Hibernate?连接的子类策略 ????@Inheritance?注解来定义所选的之类策略。 ????每个类一张表 ????@Entity??@Inheritance(strategy?=?InheritanceType.TABLE_PER_CLASS) ??public?class?Flight?implements?Serializable?{ ????有缺点,如多态查询或关联。Hibernate?使用?SQL?Union?查询来实现这种策略。?这种策略支持双向的一对多关联,但不支持?IDENTIFY?生成器策略,因为ID必须在多个表间共享。一旦使用就不能使用AUTO和IDENTIFY生成器。 ????每个类层次结构一张表 ????@Entity??@Inheritance(strategy=InheritanceType.SINGLE_TABLE) ??@DiscriminatorColumn( ??????name="planetype", ??????discriminatorType=DiscriminatorType.STRING ??) ??@DiscriminatorValue("Plane") ??public?class?Plane?{?...?} ????@Entity??@DiscriminatorValue("A320") ??public?class?A320?extends?Plane?{?...?} ????整个层次结构中的所有父类和子类属性都映射到同一个表中,他们的实例通过一个辨别符列(discriminator)来区分。 ????Plane?是父类。@DiscriminatorColumn?注解定义了辨别符列。对于继承层次结构中的每个类,?@DiscriminatorValue?注解指定了用来辨别该类的值。?辨别符列名字默认为?DTYPE,其默认值为实体名。其类型为DiscriminatorType.STRING。 ????连接的子类 ????@Entity??@Inheritance(strategy=InheritanceType.JOINED) ??public?class?Boat?implements?Serializable?{?...?} ??????@Entity??public?class?Ferry?extends?Boat?{?...?} ????@Entity??@PrimaryKeyJoinColumn(name="BOAT_ID") ??public?class?AmericaCupClass?extends?Boat?{?...?} ????以上所有实体使用?JOINED?策略?Ferry和Boat?class使用同名的主键关联(eg:?Boat.id?=?Ferry.id),?AmericaCupClass?和?Boat?关联的条件为?Boat.id?=?AmericaCupClass.BOAT_ID. ????从父类继承的属性 ????@MappedSuperclass??public?class?BaseEntity?{ ????@Basic????@Temporal(TemporalType.TIMESTAMP) ????public?Date?getLastUpdate()?{?...?} ????public?String?getLastUpdater()?{?...?} ????... ??} ??????@Entity?class?Order?extends?BaseEntity?{ ????@Id?public?Integer?getId()?{?...?} ????... ??} ????继承父类的一些属性,但不用父类作为映射实体,这时候需要?@MappedSuperclass?注解。?上述实体映射到数据库中的时候对应?Order?实体Bean,?其具有?id,?lastUpdate,?lastUpdater?三个属性。如果没有@MappedSuperclass?注解,则父类中属性忽略,这是?Order?实体?Bean?只有?id?一个属性。 ????映射实体Bean的关联关系 ????一对一 ????使用?@OneToOne?注解可以建立实体Bean之间的一对一关系。一对一关系有3种情况。 ??????关联的实体都共享同样的主键。 ????@Entity??public?class?Body?{ ????@Id????public?Long?getId()?{?return?id;?} ????@OneToOne(cascade?=?CascadeType.ALL) ????@PrimaryKeyJoinColumn????public?Heart?getHeart()?{ ???????return?heart; ????} ????... ??} ????@Entity??public?class?Heart?{ ????@Id????public?Long?getId()?{?...} ??} ????通过@PrimaryKeyJoinColumn?注解定义了一对一的关联关系。 ??????多对一 ????使用?@ManyToOne?注解定义多对一关系。 ????@Entity() ??public?class?Flight?implements?Serializable?{ ????@ManyToOne(?cascade?=?{CascadeType.PERSIST,?CascadeType.MERGE}?) ????@JoinColumn(name="COMP_ID") ????public?Company?getCompany()?{ ??????return?company; ????} ????... ??} ????其中@JoinColumn?注解是可选的,关键字段默认值和一对一关联的情况相似。列名为:主题的关联属性名?+?下划线?+?被关联端的主键列名。本例中为company_id,因为关联的属性是company,?Company的主键为?id. ????@ManyToOne?注解有个targetEntity属性,该参数定义了目标实体名。通常不需要定义,大部分情况为默认值。但下面这种情况则需要?targetEntity?定义(使用接口作为返回值,而不是常用的实体)。 ????@Entity() ??public?class?Flight?implements?Serializable?{ ?????@ManyToOne(cascade=???{CascadeType.PERSIST,CascadeType.MERGE},targetEntity=?CompanyImpl.class) ?????@JoinColumn(name="COMP_ID") ?????public?Company?getCompany()?{ ???????return?company; ?????} ?????... ??} ??????public?interface?Company?{ ?????... ????多对一也可以通过关联表的方式来映射,通过?@JoinTable?注解可定义关联表。该关联表包含指回实体的外键(通过@JoinTable.joinColumns)以及指向目标实体表的外键(通过@JoinTable.inverseJoinColumns). ????@Entity() ??public?class?Flight?implements?Serializable?{ ???????@ManyToOne(?cascade?=?{CascadeType.PERSIST,?CascadeType.MERGE}?) ?????@JoinTable(name="Flight_Company", ?????????joinColumns?=?@JoinColumn(name="FLIGHT_ID"), ?????????inverseJoinColumns?=?@JoinColumn(name="COMP_ID") ?????) ?????public?Company?getCompany()?{ ?????????return?company; ?????} ?????... ??} ????集合类型 ?????????一对多 ????@OneToMany?注解可定义一对多关联。一对多关联可以是双向的。 ????双向 ????规范中多对一端几乎总是双向关联中的主体(owner)端,而一对多的关联注解为?@OneToMany(mappedBy=) ????@Entity??public?class?Troop?{ ????@OneToMany(mappedBy="troop") ????public?Set<Soldier>?getSoldiers()?{ ????... ??} ??????@Entity??public?class?Soldier?{ ????@ManyToOne????@JoinColumn(name="troop_fk") ????public?Troop?getTroop()?{ ????... ????} ????Troop?通过troop属性和Soldier建立了一对多的双向关联。在?mappedBy?端不必也不能定义任何物理映射。 ????单向 ????@Entity??public?class?Customer?implements?Serializable?{ ?????@OneToMany(cascade=CascadeType.ALL,?fetch=FetchType.EAGER) ?????@JoinColumn(name="CUST_ID") ?????public?Set<Ticket>?getTickets()?{ ????????... ?????} ????@Entity??public?class?Ticket?implements?Serializable?{ ?????...?//no?bidir ??} ????一般通过连接表来实现这种关联,可以通过@JoinColumn注解来描述这种单向关联关系。上例?Customer?通过?CUST_ID?列和?Ticket?建立了单向关联关系。 ????通过关联表来处理单向关联 ????@E

读书人网 >软件架构设计

热点推荐