Hibernate注解详细介绍

来源:互联网 发布:php curl 上传文件 编辑:程序博客网 时间:2024/04/29 14:43

http://blog.csdn.net/lin_yongrui/article/details/6855394



  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 falsename "flight_name"nullable falselength=50 
  87.    public String getName() ...  
  88.   
  89. 定义 name 属性映射到 flight_name column, not nullcan'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 sequence generator in 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. @AssociationOverridename="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-classelement 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.   @ManyToOnecascade {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.    @ManyToOnecascade {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. @Entity  
  475. public class Trainer  
  476.   @OneToMany  
  477.   @JoinTable 
  478.      name="TrainedMonkeys" 
  479.      joinColumns @JoinColumnname="trainer_id"),  
  480.      inverseJoinColumns @JoinColumnname="monkey_id" 
  481.    
  482.   public Set<Monkey> getTrainedMonkeys()  
  483.      ...  
  484.    
  485.   
  486.   
  487. @Entity  
  488. public class Monkey  
  489.   ... //no bidir  
  490.  
  491.   
  492. 通过关联表来处理单向一对多关系是首选,这种关联通过 @JoinTable 注解来进行描述。上例子中 Trainer 通过TrainedMonkeys表和Monkey建立了单向关联关系。其中外键trainer_id关联到Trainer(joinColumns)而外键monkey_id关联到Monkey(inverseJoinColumns).  
  493.   
  494. 默认处理机制  
  495.   
  496. 通过连接表来建立单向一对多关联不需要描述任何物理映射,表名由一下3个部分组成,主表(owner table)表名 下划线 从表(the other side table)表名。指向主表的外键名:主表表名+下划线+主表主键列名 指向从表的外键定义为唯一约束,用来表示一对多的关联关系。  
  497.   
  498. @Entity  
  499. public class Trainer  
  500.   @OneToMany  
  501.   public Set<Tiger> getTrainedTigers()  
  502.   ...  
  503.  
  504.   
  505.   
  506. @Entity  
  507. public class Tiger  
  508.   ... //no bidir  
  509.  
  510.   
  511. 上述例子中 Trainer 和 Tiger 通过 Trainer_Tiger 连接表建立单向关联关系。其中外键 trainer_id 关联到 Trainer表,而外键 trainedTigers_id 关联到 Tiger 表。  
  512.   
  513. 多对多  
  514.   
  515. 通过 @ManyToMany 注解定义多对多关系,同时通过 @JoinTable 注解描述关联表和关联条件。其中一端定义为 owner, 另一段定义为 inverse(对关联表进行更新操作,这段被忽略)。  
  516.   
  517. @Entity  
  518. public class Employer implements Serializable  
  519.   @ManyToMany 
  520.     targetEntity=org.hibernate.test.metadata.manytomany.Employee.class 
  521.     cascade={CascadeType.PERSIST, CascadeType.MERGE}  
  522.    
  523.   @JoinTable 
  524.     name="EMPLOYER_EMPLOYEE" 
  525.     joinColumns=@JoinColumn(name="EMPER_ID"),  
  526.     inverseJoinColumns=@JoinColumn(name="EMPEE_ID" 
  527.    
  528.   public Collection getEmployees()  
  529.     return employees;  
  530.    
  531.   ...  
  532.  
  533.   
  534. @Entity  
  535. public class Employee implements Serializable  
  536.   @ManyToMany 
  537.     cascade {CascadeType.PERSIST, CascadeType.MERGE},  
  538.     mappedBy "employees" 
  539.     targetEntity Employer.class  
  540.    
  541.   public Collection getEmployers()  
  542.     return employers;  
  543.    
  544.  
  545.   
  546. 默认值:  
  547.   
  548. 关联表名:主表表名 下划线 从表表名;关联表到主表的外键:主表表名 下划线 主表中主键列名;关联表到从表的外键名:主表中用于关联的属性名 下划线 从表的主键列名。  
  549.   
  550. 用 cascading 实现传播持久化(Transitive persistence)  
  551.   
  552. cascade 属性接受值为 CascadeType 数组,其类型如下:  
  553.   
  554. • CascadeType.PERSIST: cascades the persist (create) operation to associated entities persist() is called or if the entity is managed 如果一个实体是受管状态,或者当 persist() 函数被调用时,触发级联创建(create)操作。  
  555.   
  556.   
  557. • CascadeType.MERGE: cascades the merge operation to associated entities if merge() is called or if the entity is managed 如果一个实体是受管状态,或者当 merge() 函数被调用时,触发级联合并(merge)操作。  
  558.   
  559.   
  560. • CascadeType.REMOVE: cascades the remove operation to associated entities if delete() is called 当 delete() 函数被调用时,触发级联删除(remove)操作。  
  561.   
  562.   
  563. • CascadeType.REFRESH: cascades the refresh operation to associated entities if refresh() is called  当 refresh() 函数被调用时,出发级联更新(refresh)操作。  
  564.   
  565.   
  566. • CascadeType.ALL: all of the above  以上全部  
  567.   
  568. 映射二级列表  
  569.   
  570. 使用类一级的 @SecondaryTable 和 @SecondaryTables 注解可以实现单个实体到多个表的映射。使用 @Column 或者 @JoinColumn 注解中的 table 参数可以指定某个列所属的特定表。  
  571.   
  572. @Entity  
  573. @Table(name="MainCat" 
  574. @SecondaryTables({  
  575.     @SecondaryTable(name="Cat1"pkJoinColumns={  
  576.            @PrimaryKeyJoinColumn(name="cat_id"referencedColumnName="id")}),  
  577.     @SecondaryTable(name="Cat2"uniqueConstraints={  
  578.            @UniqueConstraint(columnNames={"storyPart2"})})  
  579.  })  
  580. public class Cat implements Serializable  
  581.   private Integer id;  
  582.   private String name;  
  583.   
  584.   private String storyPart1;  
  585.   private String storyPart2;  
  586.   @Id @GeneratedValue  
  587.   public Integer getId()  
  588.     return id;  
  589.    
  590.   public String getName()  
  591.     return name;  
  592.    
  593.   @Column(table="Cat1" 
  594.   public String getStoryPart1()  
  595.     return storyPart1;  
  596.    
  597.   @Column(table="Cat2" 
  598.   public String getStoryPart2()  
  599.     return storyPart2;  
  600.    
  601.   
  602. 上述例子中, name 保存在 MainCat 表中,storyPart1保存在 Cat1 表中,storyPart2 保存在 Cat2 表中。 Cat1 表通过外键 cat_id 和 MainCat 表关联, Cat2 表通过 id 列和 MainCat 表关联。对storyPart2 列还定义了唯一约束。  
  603.   
  604. 映射查询  
  605.   
  606. 使用注解可以映射 EJBQL/HQL 查询,@NamedQuery 和 @NamedQueries 是可以使用在类级别或者JPA的XML文件中的注解。  
  607.   
  608. <entity-mappings>  
  609.  <named-query name="plane.getAll" 
  610.   <query>select from Plane p</query>  
  611.  </named-query>  
  612.  ...  
  613. </entity-mappings>  
  614. ...  
  615. @Entity  
  616. @NamedQuery(name="night.moreRecentThan"query="select from Night where n.date >= :date" 
  617. public class Night  
  618.  ...  
  619.  
  620. public class MyDao  
  621.  doStuff()  
  622.    Query s.getNamedQuery("night.moreRecentThan");  
  623.    q.setDate( "date"aMonthAgo );  
  624.    List results q.list();  
  625.    ...  
  626.   
  627.  ...  
  628.  
  629.   
  630. 可以通过定义 QueryHint 数组的 hints 属性为查询提供一些 hint 信息。下图是一些 Hibernate hints:  
  631.   
  632.   
  633.   
  634. 映射本地化查询  
  635.   
  636. 通过@SqlResultSetMapping 注解来描述 SQL 的 resultset 结构。如果定义多个结果集映射,则用 @SqlResultSetMappings。  
  637.   
  638. @NamedNativeQuery(name="night&area"query="select night.id nid, night.night_duration, "  
  639.      night.night_date, area.id aid, night.area_id, area.name "  
  640.      "from Night night, Area area where night.area_id area.id"resultSetMapping="joinMapping" 
  641.   
  642. @SqlResultSetMappingname="joinMapping"entities={  
  643.   @EntityResult(entityClass=org.hibernate.test.annotations.query.Night.classfields  
  644.    @FieldResult(name="id"column="nid"),  
  645.    @FieldResult(name="duration"column="night_duration"),  
  646.    @FieldResult(name="date"column="night_date"),  
  647.    @FieldResult(name="area"column="area_id"),  
  648.    discriminatorColumn="disc"  
  649.   }),  
  650.     
  651.   @EntityResult(entityClass=org.hibernate.test.annotations.query.Area.classfields  
  652.    @FieldResult(name="id"column="aid"),  
  653.    @FieldResult(name="name"column="name" 
  654.   })  
  655.   
  656.  
  657.   
  658. 上面的例子,名为“night&area”的查询和 "joinMapping"结果集映射对应,该映射返回两个实体,分别为 Night 和 Area, 其中每个属性都和一个列关联,列名通过查询获取。  
  659.   
  660. @Entity  
  661. @SqlResultSetMapping(name="implicit"  
  662.   entities=@EntityResult 
  663.     entityClass=org.hibernate.test.annotations.@NamedNativeQuery 
  664.       name="implicitSample"query="select from SpaceShip"  
  665.       resultSetMapping="implicit" 
  666. public class SpaceShip  
  667.  private String name;  
  668.  private String model;  
  669.  private double speed;  
  670.  @Id  
  671.  public String getName()  
  672.   return name;  
  673.   
  674.  public void setName(String name)  
  675.   this.name name;  
  676.   
  677.  @Column(name="model_txt" 
  678.  public String getModel()  
  679.   return model;  
  680.   
  681.  public void setModel(String model)  
  682.   this.model model;  
  683.   
  684.  public double getSpeed()  
  685.   return speed;  
  686.   
  687.  public void setSpeed(double speed)  
  688.   this.speed speed;  
  689.   
  690.  
  691.   
  692. 上例中 model1 属性绑定到 model_txt 列,如果和相关实体关联设计到组合主键,那么应该使用 @FieldResult 注解来定义每个外键列。@FieldResult的名字组成:定义这种关系的属性名字 "." 主键名或主键列或主键属性。  
  693.   
  694. @Entity  
  695. @SqlResultSetMapping(name="compositekey" 
  696.  entities=@EntityResult(entityClass=org.hibernate.test.annotations.query.SpaceShip.class 
  697.   fields  
  698.    @FieldResult(name="name"column "name"),  
  699.    @FieldResult(name="model"column "model"),  
  700.    @FieldResult(name="speed"column "speed"),  
  701.    @FieldResult(name="captain.firstname"column "firstn"),  
  702.    @FieldResult(name="captain.lastname"column "lastn"),  
  703.    @FieldResult(name="dimensions.length"column "length"),  
  704.    @FieldResult(name="dimensions.width"column "width" 
  705.   }),  
  706.  columns @ColumnResult(name "surface"),  
  707.    
  708. @ColumnResult(name "volume" 
  709.  @NamedNativeQuery(name="compositekey" 
  710.  query="select name, model, speed, lname as lastn, fname as firstn, length, width, length width as resultSetMapping="compositekey")  
  711. })  
  712.   
  713. 如果查询返回的是单个实体,或者打算用系统默认的映射,这种情况下可以不使用 resultSetMapping,而使用resultClass属性,例如:  
  714.   
  715. @NamedNativeQuery(name="implicitSample"query="select from SpaceShip" 
  716.                                             resultClass=SpaceShip.class 
  717. public class SpaceShip  
  718.   
  719. Hibernate 独有的注解扩展  
  720.   
  721. Hibernate 提供了与其自身特性想吻合的注解,org.hibernate.annotations package包含了这些注解。  
  722.   
  723. 实体  
  724.   
  725. org.hibernate.annotations.Entity 定义了  Hibernate 实体需要的信息。  
  726.   
  727. • mutable: whether this entity is mutable or not  此实体是否可变  
  728.   
  729.   
  730. • dynamicInsert: allow dynamic SQL for inserts   用动态SQL新增  
  731.   
  732.   
  733. • dynamicUpdate: allow dynamic SQL for updates   用动态SQL更新  
  734.   
  735.   
  736. • selectBeforeUpdate: Specifies that Hibernate should never perform an SQL UPDATE unless it is certain that an object is actually modified.指明Hibernate从不运行SQL Update,除非能确定对象已经被修改  
  737.   
  738.   
  739. • polymorphism: whether the entity polymorphism is of PolymorphismType.IMPLICIT (defaultor PolymorphismType.EXPLICIT 指出实体多态是 PolymorphismType.IMPLICIT(默认)还是PolymorphismType.EXPLICIT   
  740.   
  741.   
  742. • optimisticLock: optimistic locking strategy (OptimisticLockType.VERSION, OptimisticLockType.NONE, OptimisticLockType.DIRTY or OptimisticLockType.ALL) 乐观锁策略  
  743.   
  744. 标识符  
  745.   
  746. @org.hibernate.annotations.GenericGenerator和@org.hibernate.annotations.GenericGenerators允许你定义hibernate特有的标识符。  
  747.   
  748. @Id @GeneratedValue(generator="system-uuid" 
  749. @GenericGenerator(name="system-uuid"strategy "uuid" 
  750. public String getId()  
  751. @Id @GeneratedValue(generator="hibseq" 
  752. @GenericGenerator(name="hibseq"strategy "seqhilo" 
  753.    parameters  
  754.      @Parameter(name="max_lo"value "5"),  
  755.      @Parameter(name="sequence"value="heybabyhey" 
  756.     
  757.  
  758. public Integer getId()  
  759.   
  760. 新例子  
  761.   
  762. @GenericGenerators 
  763.   
  764.   @GenericGenerator 
  765.    name="hibseq" 
  766.    strategy "seqhilo" 
  767.    parameters  
  768.     @Parameter(name="max_lo"value "5"),  
  769.     @Parameter(name="sequence"value="heybabyhey" 
  770.     
  771.   ),  
  772.   @GenericGenerator(...)  
  773.   
  774.  
  775.   
  776. 自然ID  
  777.   
  778. 用 @NaturalId 注解标识  
  779.   
  780. 公式  
  781.   
  782. 让数据库而不是JVM进行计算。  
  783.   
  784. @Formula("obj_length obj_height obj_width" 
  785. public long getObjectVolume()  
  786.   
  787. 索引  
  788.   
  789. 通过在列属性(property)上使用@Index注解,可以指定特定列的索引,columnNames属性(attribute)将随之被忽略。  
  790.   
  791. @Column(secondaryTable="Cat1" 
  792. @Index(name="story1index" 
  793. public String getStoryPart1()  
  794.   return storyPart1;  
  795.  
  796.   
  797. 辨别符  
  798.   
  799. @Entity  
  800. @DiscriminatorFormula("case when forest_type is null then else forest_type end" 
  801. public class Forest ...  
  802.   
  803. 过滤 查询 ...  
  804.   
  805.   
  806.   
  807.   
  808.   
  809. • 其中一个实体通过外键关联到另一个实体的主键。注:一对一,则外键必须为唯一约束。  
  810.   
  811. @Entity  
  812. public class Customer implements Serializable  
  813.    @OneToOne(cascade CascadeType.ALL)  
  814.    @JoinColumn(name="passport_fk" 
  815.    public Passport getPassport()  
  816.    ...  
  817.  
  818.   
  819.   
  820. @Entity  
  821. public class Passport implements Serializable  
  822.    @OneToOne(mappedBy "passport" 
  823.    public Customer getOwner()  
  824.    ...  
  825.  
  826.   
  827. 通过@JoinColumn注解定义一对一的关联关系。如果没有@JoinColumn注解,则系统自动处理,在主表中将创建连接列,列名为:主题的关联属性名 下划线 被关联端的主键列名。上例为 passport_id, 因为Customer 中关联属性为 passport, Passport 的主键为 id.  
  828.   
  829.   
  830. • 通过关联表来保存两个实体之间的关联关系。注:一对一,则关联表每个外键都必须是唯一约束。  
  831.   
  832. @Entity  
  833. public class Customer implements Serializable  
  834.    @OneToOne(cascade CascadeType.ALL)  
  835.    @JoinTable(name "CustomerPassports" 
  836.         joinColumns @JoinColumn(name="customer_fk"),  
  837.         inverseJoinColumns @JoinColumn(name="passport_fk" 
  838.     
  839.    public Passport getPassport()  
  840.    ...  
  841.  
  842.   
  843.   
  844. @Entity public class Passport implements Serializable  
  845.    @OneToOne(mappedBy "passport" 
  846.    public Customer getOwner()  
  847.    ...  
  848.  
  849.   
  850. Customer 通过 CustomerPassports 关联表和 Passport 关联。该关联表通过 passport_fk 外键指向 Passport 表,该信心定义为 inverseJoinColumns 的属性值。 通过 customer_fk 外键指向 Customer 表,该信息定义为 joinColumns 属性值。

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 oppo媒体声音小怎么办 手机视频音量小怎么办 苹果6内存不够怎么办 wiwox7忘记密码了怎么办 wiwo手机声音小怎么办 海信手机声音小怎么办 ppos手机声音小怎么办 手机铃声太小怎么办 手机声音没有了怎么办 vivo外放没声音怎么办 fgo关服充的钱怎么办 淘宝提前收货了怎么办 淘宝直播间没人怎么办 花呗地区限制怎么办 支付宝花呗账单错误怎么办 台球厅生意惨淡怎么办 退货少了东西怎么办 微店注册id怎么办 卖红酒没有客源怎么办 来姨妈10天没走怎么办 京东违反广告法怎么办 支付宝定位错误怎么办 银行账户未年审怎么办 淘宝集运禁运品 怎么办 物流显示禁运品怎么办 淘宝禁运品怎么办呢 货物退回日本了怎么办 淘宝卖家寄多了衣服怎么办 集运地址选错怎么办 淘宝卖韩国化妆品退货怎么办 去韩国留学手机怎么办 韩国办无线网怎么办 淘宝卖家被骗怎么办 淘宝买软件被骗怎么办 被淘宝店诈骗怎么办? 支付宝被骗2000怎么办 给私人打款后不发货怎么办 毕业证寄丢了怎么办 微商下单返现被骗一千四怎么办 淘宝买东西卡里多扣钱怎么办 付款了卖家不发货怎么办