`

hibernate注解使用

阅读更多
  1. 声明实体Bean   
  2.   
  3. @Entity  
  4. public class Flight implements Serializable {   
  5.   Long id;   
  6.   @Id  
  7.   public Long getId() { return id; }   
  8.   public void setId(Long id) { this.id = id; }   
  9. }   
  10.   
  11. @Entity 注解将一个类声明为实体 Bean, @Id 注解声明了该实体Bean的标识属性。   
  12.   
  13. Hibernate 可以对类的属性或者方法进行注解。属性对应field类别,方法的 getXxx()对应property类别。   
  14.   
  15. 定义表   
  16.   
  17. 通过 @Table 为实体Bean指定对应数据库表,目录和schema的名字。   
  18.   
  19. @Entity  
  20. @Table(name="tbl_sky")   
  21. public class Sky implements Serializable {   
  22.   
  23. ...   
  24.   
  25. @Table 注解包含一个schema和一个catelog 属性,使用@UniqueConstraints 可以定义表的唯一约束。   
  26.   
  27. @Table(name="tbl_sky",   
  28.   uniqueConstraints = {@UniqueConstraint(columnNames={"month""day"})}   
  29. )   
  30.   
  31. 上述代码在  "month" 和 "day" 两个 field 上加上 unique constrainst.   
  32.   
  33. @Version 注解用于支持乐观锁版本控制。   
  34.   
  35. @Entity  
  36. public class Flight implements Serializable {   
  37.    ...   
  38.    @Version  
  39.    @Column(name="OPTLOCK")   
  40.    public Integer getVersion() { ... }   
  41. }   
  42.   
  43. version属性映射到 "OPTLOCK" 列,entity manager 使用这个字段来检测冲突。 一般可以用 数字 或者 timestamp 类型来支持 version.   
  44.   
  45. 实体Bean中所有非static 非 transient 属性都可以被持久化,除非用@Transient注解。   
  46.   
  47. 默认情况下,所有属性都用 @Basic 注解。   
  48.   
  49. public transient int counter; //transient property   
  50.   
  51. private String firstname; //persistent property   
  52. @Transient  
  53. String getLengthInMeter() { ... } //transient property   
  54. String getName() {... } // persistent property   
  55. @Basic  
  56. int getLength() { ... } // persistent property   
  57. @Basic(fetch = FetchType.LAZY)   
  58. String getDetailedComment() { ... } // persistent property   
  59. @Temporal(TemporalType.TIME)   
  60. java.util.Date getDepartureTime() { ... } // persistent property   
  61. @Enumerated(EnumType.STRING)   
  62. Starred getNote() { ... } //enum persisted as String in database   
  63.   
  64. 上述代码中 counter, lengthInMeter 属性将忽略不被持久化,而 firstname, name, length 被定义为可持久化和可获取的。    
  65.   
  66. @TemporalType.(DATE,TIME,TIMESTAMP) 分别Map java.sql.(Date, Time, Timestamp).   
  67.   
  68. @Lob 注解属性将被持久化为 Blog 或 Clob 类型。具体的java.sql.Clob, Character[], char[] 和 java.lang.String 将被持久化为 Clob 类型. java.sql.Blob, Byte[], byte[] 和 serializable type 将被持久化为 Blob 类型。   
  69.   
  70. @Lob  
  71. public String getFullText() {   
  72.    return fullText;  // clob type   
  73. }   
  74.   
  75.   
  76. @Lob  
  77. public byte[] getFullCode() {   
  78.   return fullCode;  // blog type   
  79. }   
  80.   
  81. @Column 注解将属性映射到列。   
  82.   
  83. @Entity  
  84. public class Flight implements Serializable {   
  85.    ...   
  86.    @Column(updatable = false, name = "flight_name", nullable = false, length=50)   
  87.    public String getName() { ... }   
  88.   
  89. 定义 name 属性映射到 flight_name column, not null, can't update, length equal 50  
  90.   
  91. @Column(   
  92.    name="columnName"; (1) 列名   
  93.    boolean unique() default false; (2)    是否在该列上设置唯一约束   
  94.    boolean nullable() default true; (3)   列可空?   
  95.    boolean insertable() default true; (4) 该列是否作为生成 insert语句的一个列   
  96.    boolean updatable() default true; (5)  该列是否作为生成 update语句的一个列   
  97.    String columnDefinition() default ""; (6)  默认值   
  98.    String table() default ""; (7)             定义对应的表(deault 是主表)   
  99.    int length() default 255; (8)              列长度   
  100.    int precision() default 0// decimal precision (9)  decimal精度   
  101.    int scale() default 0// decimal scale        (10)  decimal长度   
  102.   
  103. 嵌入式对象(又称组件)也就是别的对象定义的属性   
  104.   
  105. 组件类必须在类一级定义 @Embeddable 注解。在特定的实体关联属性上使用 @Embeddable 和 @AttributeOverride 注解可以覆盖该属性对应的嵌入式对象的列映射。   
  106.   
  107. @Entity  
  108. public class Person implements Serializable {   
  109.    // Persistent component using defaults   
  110.    Address homeAddress;   
  111.    @Embedded  
  112.    @AttributeOverrides( {   
  113.       @AttributeOverride(name="iso2", column = @Column(name="bornIso2") ),   
  114.       @AttributeOverride(name="name", column = @Column(name="bornCountryName") )   
  115.    } )   
  116.    Country bornIn;   
  117.    ...   
  118. }   
  119.   
  120. @Embeddable  
  121. public class Address implements Serializable {   
  122.    String city;   
  123.    Country nationality; //no overriding here   
  124. }   
  125.   
  126. @Embeddable  
  127. public class Country implements Serializable {   
  128.    private String iso2;   
  129.    @Column(name="countryName"private String name;   
  130.    public String getIso2() { return iso2; }   
  131.    public void setIso2(String iso2) { this.iso2 = iso2; }   
  132.    public String getName() { return name; }   
  133.    public void setName(String name) { this.name = name; }   
  134.    ...   
  135. }   
  136.   
  137. Person 类定义了 Address 和  Country 对象,具体两个类实现见上。   
  138.   
  139. 无注解属性默认值:   
  140.   
  141. • 属性为简单类型,则映射为 @Basic  
  142.   
  143. • 属性对应的类型定义了 @Embeddable 注解,则映射为 @Embedded  
  144.   
  145. • 属性对应的类型实现了Serializable,则属性被映射为@Basic并在一个列中保存该对象的serialized版本。   
  146.   
  147. • 属性的类型为 java.sql.Clob or java.sql.Blob, 则映射到 @Lob 对应的类型。   
  148.   
  149. 映射主键属性   
  150.   
  151. @Id 注解可将实体Bean中某个属性定义为主键,使用@GenerateValue注解可以定义该标识符的生成策略。   
  152.   
  153. • AUTO -  可以是 identity column, sequence 或者 table 类型,取决于不同底层的数据库   
  154. • TABLE - 使用table保存id值   
  155. • IDENTITY - identity column   
  156. • SEQUENCE - seque   
  157.   
  158. nce    
  159.   
  160. @Id @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SEQ_STORE")   
  161. public Integer getId() { ... }   
  162.   
  163. @Id @GeneratedValue(strategy=GenerationType.IDENTITY)   
  164. public Long getId() { ... }   
  165.   
  166. AUTO 生成器,适用与可移值的应用,多个@Id可以共享同一个 identifier生成器,只要把generator属性设成相同的值就可以。通过@SequenceGenerator 和 @TableGenerator 可以配置不同的 identifier 生成器。    
  167.   
  168. <table-generator name="EMP_GEN"  
  169.      table="GENERATOR_TABLE"  
  170.      pk-column-name="key"  
  171.      value-column-name="hi"  
  172.      pk-column-value="EMP"  
  173.      allocation-size="20"/>   
  174. //and the annotation equivalent   
  175. @javax.persistence.TableGenerator(   
  176.      name="EMP_GEN",   
  177.      table="GENERATOR_TABLE",   
  178.      pkColumnName = "key",   
  179.      valueColumnName = "hi"  
  180.      pkColumnValue="EMP",   
  181.      allocationSize=20  
  182. )   
  183. <sequence-generator name="SEQ_GEN"  
  184.      sequence-name="my_sequence"  
  185.      allocation-size="20"/>   
  186. //and the annotation equivalent   
  187. @javax.persistence.SequenceGenerator(   
  188.      name="SEQ_GEN",   
  189.      sequenceName="my_sequence",   
  190.      allocationSize=20  
  191. )   
  192.   
  193. The next example shows the definition of a sequence generator in a class scope:   
  194.   
  195. @Entity  
  196. @javax.persistence.SequenceGenerator(   
  197.     name="SEQ_STORE",   
  198.     sequenceName="my_sequence"  
  199. )   
  200. public class Store implements Serializable {   
  201.    private Long id;   
  202.    @Id @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SEQ_STORE")   
  203.    public Long getId() { return id; }   
  204. }   
  205.   
  206. Store类使用名为my_sequence的sequence,并且SEQ_STORE生成器对于其他类是不可见的。   
  207.   
  208. 通过下面语法,你可以定义组合键。   
  209.   
  210. • 将组件类注解为 @Embeddable, 并将组件的属性注解为 @Id  
  211. • 将组件的属性注解为 @EmbeddedId  
  212. • 将类注解为 @IdClass,并将该实体中所有主键的属性都注解为 @Id  
  213.   
  214. @Entity  
  215. @IdClass(FootballerPk.class)   
  216. public class Footballer {   
  217.   //part of the id key   
  218.   @Id public String getFirstname() {   
  219.     return firstname;   
  220.   }   
  221.   public void setFirstname(String firstname) {   
  222.      this.firstname = firstname;   
  223.   }   
  224.   //part of the id key   
  225.   @Id public String getLastname() {   
  226.     return lastname;   
  227.   }   
  228.   public void setLastname(String lastname) {   
  229.     this.lastname = lastname;   
  230.   }   
  231.   public String getClub() {   
  232.     return club;   
  233.   }   
  234.   public void setClub(String club) {   
  235.    this.club = club;   
  236.   }   
  237.   //appropriate equals() and hashCode() implementation   
  238. }   
  239.   
  240. @Embeddable  
  241. public class FootballerPk implements Serializable {   
  242.   //same name and type as in Footballer   
  243.   public String getFirstname() {   
  244.     return firstname;   
  245.   }   
  246.   public void setFirstname(String firstname) {   
  247.     this.firstname = firstname;   
  248.   }   
  249.   //same name and type as in Footballer   
  250.   public String getLastname() {   
  251.     return lastname;   
  252.   }   
  253.   public void setLastname(String lastname) {   
  254.    this.lastname = lastname;   
  255.   }   
  256.   //appropriate equals() and hashCode() implementation   
  257. }   
  258.   
  259. @Entity  
  260. @AssociationOverride( name="id.channel", joinColumns = @JoinColumn(name="chan_id") )   
  261. public class TvMagazin {   
  262.    @EmbeddedId public TvMagazinPk id;   
  263.    @Temporal(TemporalType.TIME) Date time;   
  264. }   
  265.   
  266.   
  267. @Embeddable  
  268. public class TvMagazinPk implements Serializable {   
  269.    @ManyToOne  
  270.    public Channel channel;   
  271.    public String name;   
  272.    @ManyToOne  
  273.    public Presenter presenter;   
  274. }   
  275.   
  276. 映射继承关系   
  277.   
  278. EJB支持3种类型的继承。   
  279.   
  280. • Table per Class Strategy: the <union-class> element in Hibernate 每个类一张表   
  281. • Single Table per Class Hierarchy Strategy: the <subclass> element in Hibernate 每个类层次结构一张表   
  282. • Joined Subclass Strategy: the <joined-subclass> element in Hibernate 连接的子类策略   
  283.   
  284. @Inheritance 注解来定义所选的之类策略。   
  285.   
  286. 每个类一张表   
  287.   
  288. @Entity  
  289. @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)   
  290. public class Flight implements Serializable {   
  291.   
  292. 有缺点,如多态查询或关联。Hibernate 使用 SQL Union 查询来实现这种策略。 这种策略支持双向的一对多关联,但不支持 IDENTIFY 生成器策略,因为ID必须在多个表间共享。一旦使用就不能使用AUTO和IDENTIFY生成器。   
  293.   
  294. 每个类层次结构一张表   
  295.   
  296. @Entity  
  297. @Inheritance(strategy=InheritanceType.SINGLE_TABLE)   
  298. @DiscriminatorColumn(   
  299.     name="planetype",   
  300.     discriminatorType=DiscriminatorType.STRING   
  301. )   
  302. @DiscriminatorValue("Plane")   
  303. public class Plane { ... }   
  304.   
  305. @Entity  
  306. @DiscriminatorValue("A320")   
  307. public class A320 extends Plane { ... }   
  308.   
  309. 整个层次结构中的所有父类和子类属性都映射到同一个表中,他们的实例通过一个辨别符列(discriminator)来区分。   
  310.   
  311. Plane 是父类。@DiscriminatorColumn 注解定义了辨别符列。对于继承层次结构中的每个类, @DiscriminatorValue 注解指定了用来辨别该类的值。 辨别符列名字默认为 DTYPE,其默认值为实体名。其类型为DiscriminatorType.STRING。   
  312.   
  313. 连接的子类   
  314.   
  315. @Entity  
  316. @Inheritance(strategy=InheritanceType.JOINED)   
  317. public class Boat implements Serializable { ... }   
  318.   
  319.   
  320. @Entity  
  321. public class Ferry extends Boat { ... }   
  322.   
  323. @Entity  
  324. @PrimaryKeyJoinColumn(name="BOAT_ID")   
  325. public class AmericaCupClass extends Boat { ... }   
  326.   
  327. 以上所有实体使用 JOINED 策略 Ferry和Boat class使用同名的主键关联(eg: Boat.id = Ferry.id), AmericaCupClass 和 Boat 关联的条件为 Boat.id = AmericaCupClass.BOAT_ID.   
  328.   
  329. 从父类继承的属性   
  330.   
  331. @MappedSuperclass  
  332. public class BaseEntity {   
  333.   @Basic  
  334.   @Temporal(TemporalType.TIMESTAMP)   
  335.   public Date getLastUpdate() { ... }   
  336.   public String getLastUpdater() { ... }   
  337.   ...   
  338. }   
  339.   
  340.   
  341. @Entity class Order extends BaseEntity {   
  342.   @Id public Integer getId() { ... }   
  343.   ...   
  344. }   
  345.   
  346. 继承父类的一些属性,但不用父类作为映射实体,这时候需要 @MappedSuperclass 注解。 上述实体映射到数据库中的时候对应 Order 实体Bean, 其具有 id, lastUpdate, lastUpdater 三个属性。如果没有@MappedSuperclass 注解,则父类中属性忽略,这是 Order 实体 Bean 只有 id 一个属性。   
  347.   
  348. 映射实体Bean的关联关系   
  349.   
  350. 一对一   
  351.   
  352. 使用 @OneToOne 注解可以建立实体Bean之间的一对一关系。一对一关系有3种情况。   
  353.   
  354. • 关联的实体都共享同样的主键。   
  355.   
  356. @Entity  
  357. public class Body {   
  358.   @Id  
  359.   public Long getId() { return id; }   
  360.   @OneToOne(cascade = CascadeType.ALL)   
  361.   @PrimaryKeyJoinColumn  
  362.   public Heart getHeart() {   
  363.      return heart;   
  364.   }   
  365.   ...   
  366. }   
  367.   
  368. @Entity  
  369. public class Heart {   
  370.   @Id  
  371.   public Long getId() { ...}   
  372. }   
  373.   
  374. 通过@PrimaryKeyJoinColumn 注解定义了一对一的关联关系。   
  375.   
  376.   
  377. 多对一   
  378.   
  379. 使用 @ManyToOne 注解定义多对一关系。   
  380.   
  381. @Entity()   
  382. public class Flight implements Serializable {   
  383.   @ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE} )   
  384.   @JoinColumn(name="COMP_ID")   
  385.   public Company getCompany() {   
  386.     return company;   
  387.   }   
  388.   ...   
  389. }   
  390.   
  391. 其中@JoinColumn 注解是可选的,关键字段默认值和一对一关联的情况相似。列名为:主题的关联属性名 + 下划线 + 被关联端的主键列名。本例中为company_id,因为关联的属性是company, Company的主键为 id.   
  392.   
  393. @ManyToOne 注解有个targetEntity属性,该参数定义了目标实体名。通常不需要定义,大部分情况为默认值。但下面这种情况则需要 targetEntity 定义(使用接口作为返回值,而不是常用的实体)。   
  394.   
  395. @Entity()   
  396. public class Flight implements Serializable {   
  397.    @ManyToOne(cascade=   {CascadeType.PERSIST,CascadeType.MERGE},targetEntity= CompanyImpl.class)   
  398.    @JoinColumn(name="COMP_ID")   
  399.    public Company getCompany() {   
  400.      return company;   
  401.    }   
  402.    ...   
  403. }   
  404.   
  405.   
  406. public interface Company {   
  407.    ...   
  408.   
  409. 多对一也可以通过关联表的方式来映射,通过 @JoinTable 注解可定义关联表。该关联表包含指回实体的外键(通过@JoinTable.joinColumns)以及指向目标实体表的外键(通过@JoinTable.inverseJoinColumns).   
  410.   
  411. @Entity()   
  412. public class Flight implements Serializable {   
  413.   
  414.    @ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE} )   
  415.    @JoinTable(name="Flight_Company",   
  416.        joinColumns = @JoinColumn(name="FLIGHT_ID"),   
  417.        inverseJoinColumns = @JoinColumn(name="COMP_ID")   
  418.    )   
  419.    public Company getCompany() {   
  420.        return company;   
  421.    }   
  422.    ...   
  423. }   
  424.   
  425. 集合类型   
  426.   
  427.   
  428.   
  429.  一对多   
  430.   
  431. @OneToMany 注解可定义一对多关联。一对多关联可以是双向的。   
  432.   
  433. 双向   
  434.   
  435. 规范中多对一端几乎总是双向关联中的主体(owner)端,而一对多的关联注解为 @OneToMany(mappedBy=)   
  436.   
  437. @Entity  
  438. public class Troop {   
  439.   @OneToMany(mappedBy="troop")   
  440.   public Set<Soldier> getSoldiers() {   
  441.   ...   
  442. }   
  443.   
  444.   
  445. @Entity  
  446. public class Soldier {   
  447.   @ManyToOne  
  448.   @JoinColumn(name="troop_fk")   
  449.   public Troop getTroop() {   
  450.   ...   
  451.   }   
  452.   
  453. Troop 通过troop属性和Soldier建立了一对多的双向关联。在 mappedBy 端不必也不能定义任何物理映射。   
  454.   
  455. 单向   
  456.   
  457. @Entity  
  458. public class Customer implements Serializable {   
  459.    @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)   
  460.    @JoinColumn(name="CUST_ID")   
  461.    public Set<Ticket> getTickets() {   
  462.       ...   
  463.    }   
  464.   
  465. @Entity  
  466. public class Ticket implements Serializable {   
  467.    ... //no bidir   
  468. }   
  469.   
  470. 一般通过连接表来实现这种关联,可以通过@JoinColumn注解来描述这种单向关联关系。上例 Customer 通过 CUST_ID 列和 Ticket 建立了单向关联关系。   
  471.   
  472. 通过关联表来处理单向关联   
  473.   
  474. @E
    分享到:
    评论

相关推荐

Global site tag (gtag.js) - Google Analytics