商讯信箱
用户名: @
密  码:   注册|忘记密码
登录
个人用户经销商
您的位置:首页 > 技术频道 > 正文

IT168分析评论】 
    3.使用注解元数据 
        基本注解 
    首先,我们对Topic领域对象进行注解,使其成为一个合格的实体类: 
    代码清单 1 Topic实体类的注解
package com.baobaotao.domain; import javax.persistence.Column; import javax.persistence.DiscriminatorColumn; import javax.persistence.DiscriminatorType; import javax.persistence.DiscriminatorValue; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Inheritance; import javax.persistence.InheritanceType; import javax.persistence.Temporal; import javax.persistence.TemporalType; @Entity(name = "T_TOPIC") ① public class Topic implements Serializable { @Id ②-1 @GeneratedValue(strategy = GenerationType.TABLE) ②-2 @Column(name = "TOPIC_ID") ②-3 private int topicId; @Column(name = "TOPIC_TITLE", length = 100) ③ private String topicTitle; @Column(name = "TOPIC_TIME") @Temporal(TemporalType.DATE) ④ private Date topicTime; @Column(name = "TOPIC_VIEWS") private int topicViews; //省略get/setter方法 }
 @Entity:将领域对象标注为一个实体,表示需要保存到数据库中,默认情况下类名即为表名,通过name属性显式指定表名,如①处的name = "T_TOPIC",表示Topic保存到T_TOPIC表中;
 @Id :对应的属性是表的主键,如②-1所示;
 @GeneratedValue:主键的产生策略,通过strategy属性指定。默认情况下,JPA自动选择一个最适合底层数据库的主键生成策略,如SqlServer对应identity,MySql对应auto increment。在javax.persistence.GenerationType中定义了以下几种可供选择的策略:
 1) IDENTITY:表自增键字段,Oracle不支持这种方式;
 2) AUTO: JPA自动选择合适的策略,是默认选项;
 3) SEQUENCE:通过序列产生主键,通过@SequenceGenerator注解指定序列名,MySql不支持这种方式;
 4) TABLE:通过表产生主键,框架借由表模拟序列产生主键,使用该策略可以使应用更易于数据库移植。不同的JPA实现商生成的表名是不同的,如OpenJPA生成openjpa_sequence_table表Hibernate生成一个hibernate_sequences表,而TopLink则生成sequence表。这些表都具有一个序列名和对应值两个字段,如SEQ_NAME和SEQ_COUNT。
 @Column(name = "TOPIC_ID"):属性对应的表字段。我们并不需要指定表字段的类型,因为JPA会根据反射从实体属性中获取类型;如果是字符串类型,我们可以指定字段长度,以便可以自动生成DDL语句,如③处所示;
 @Temporal(TemporalType.DATE):如果属性是时间类型,因为数据表对时间类型有更严格的划分,所以必须指定具体时间类型,如④所示。在javax.persistence.TemporalType枚举中定义了3种时间类型:
 1) DATE :等于java.sql.Date
 2) TIME :等于java.sql.Time
 3) TIMESTAMP :等于java.sql.Timestamp

继承关系
 Topic和PollTopic是父子类,JPA 采用多种方法来支持实体继承。在父类中必须声明继承实体的映射策略,如代码清单 2所示:
 代码清单 2:继承实体的映射策略
@Entity(name = "T_TOPIC") @Inheritance(strategy = InheritanceType.SINGLE_TABLE) ① @DiscriminatorColumn(name = "TOPIC_TYPE", discriminatorType =
DiscriminatorType.INTEGER, length
= 1) ② @DiscriminatorValue(value="1")③ public class Topic implements Serializable { }
  对于继承的实体,在javax.persistence.InheritanceType定义了3种映射策略,:
 SINGLE_TABLE:父子类都保存到同一个表中,通过字段值进行区分。这是我们Topic实体所采用的策略,Topic和PollTopic都保存到同一张表中,通过TOPIC_TYPE字段进行区分,Topic在T_TOPIC表中对应TOPIC_TYPE=1的记录,而PollTopic对应TOPIC_TYPE=2的记录(稍后在PollTopic实体中指定);区别的字段通过@DiscriminatorColumn说明,如②所示,区分字段对应该实体的值通过@DiscriminatorValue指定,如③所示;
 JOINED:父子类相同的部分保存在同一个表中,不同的部分分开存放,通过表连接获取完整数据;
 TABLE_PER_CLASS:每一个类对应自己的表,一般不推荐采用这种方式。

关联关系
 我们再继续对PollTopic进行注解,进一步了解实体继承的JPA映射定义:
 代码清单 3 PollTopic映射描述
package com.baobaotao.domain; @Entity @DiscriminatorValue(value="2") ① public class PollTopic extends Topic {②继承于Topic实体 private boolean multiple; ③ @Column(name = "MAX_CHOICES") private int maxChoices; @OneToMany(mappedBy="pollTopic",cascade=CascadeType.ALL) ④ private Set<PollOption> options = new HashSet<PollOption>(); //省略get/setter方法 }
 在①处,通过@DiscriminatorValue将区分字段TOPIC_TYPE的值为2。由于PollTopic实体继承于Topic实体,其它的元数据信息直接从Topic获得。
 JPA规范规定任何属性都默认映射到表中,所以虽然我们没有给③处的multiple属性提供注解信息,但JPA将按照默认的规则对该字段进行映射:字段名和属性名相同,类型相同。如果我们不希望将某个属性持久化到数据表中,则可以通过@Transient注解显式指定:
  @Transient
  private boolean tempProp1;
 在④处,我们通过@OneToMany指定了一个一对多的关联关系,一个PollTopic包括多个PollOption对象(我们将在稍后的PollOption中通过ManyToOne描述PollOption和PollTopic的关系,以建立PollTopic和PollOption的双向关联关系)。
 @OneToMany中通过mappedBy属性指定“Many”方类引用“One”方类的属性名,这里mappedBy="pollTopic"表示PollOption实体拥有一个指定PollTopic的pollTopic属性。
 下面,我们来看一下Many方PollOption实体类的映射描述:
 代码清单 4 PollOption映射描述
package com.baobaotao.domain; @Entity(name="T_POLL_OPTION") public class PollOption implements Serializable { @Id @GeneratedValue(strategy = GenerationType.TABLE) @Column(name = "OPTION_ID") private int optionId; @Column(name = "OPTION_ITEM") private String optionItem; @ManyToOne ① @JoinColumn(name="TOPIC_ID", nullable=false) ② private PollTopic pollTopic; }
 在①处通过@ManyToOne描述了PollOption和PollTopic的多对一关联关系,并通过@JoinColumn指定关联PollTopic实体所对应表的“外键”,如②所示。
 当然也可以通过@OneToOne和@ManyToMany指定一对一和多以多的关系,方法差不多,不再赘述。
1 2 3 4 5
©版权所有。未经许可,不得转载。
[责任编辑:郭宗一]
·LoadRunner创建测试脚本
·用LoadRunner编写socket应用的测试脚本
·使用LoadRunner 编写JAVA 测试脚本
·LoadRunner脚本编程
·【高端访谈】寻找下一代CTO向冠军冲刺
·【技术专题】SQL Server 2008数据挖掘指南
·【高端访谈】畅谈“寻找下一代CTO”
·【热点专题】08年.NET最受欢迎的图书