扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
@Entity
public class Person implements Serializable {
// ... ...
protected Resume resume;
protected CreditCard [] cards;
protected Address addr;
// ... ...
@OneToOne
public Resume getResume () {
return resume;
}
// ... ...
@ManyToOne
// @JoinColumn (name="MyCustomId")
public Address getAddr () {
return addr;
}
// ... ...
@OneToMany
public Collection <CreditCard> getCards () {
return cards;
}
}
在关系型数据库中,那些关系自动地被EJB 3.0容器使用外键来重建了。举例来说,Person表有一个外键包含了Resume表中相应的主键。运行时,EJB 3.0容器加强了一对一的关系:它保证了Resume键值对于Person表中的每一行是唯一的。为了启用Resume表到Person表的双向查询,你可以Resume表中定义一个Person属性,并把它也加上@OneToOne注释。
Person表中也有一个外键包含了Address表中相应行的主键。这种情况下,相同的Address主键可以出现在多个Person行中,这是多对一关系。对于一对多的关系,映射稍有一点复杂,因为外键列是定义在多对一表中的。于是,在CreditCard类中,你必须用@ManyToOne来定义一个Person属性。
改变外部键字段名
ORM中使用的外部键字段的名字是由容器自动决定的或者由@JoinColumn注释来显式的指定。
上面讨论的关系只是实体bean之间关系的一种类型,实体类之间另外一种重要关系是继承。
继承
面向对象设计方法的一个关键概念是继承。使用继承,你可以创建一个复杂的对象树而不需要重复的代码。举例来说,Consultant(顾问)是提供有偿服务的一个人,那么在我们的数据模型中,Consultant类就从Person(个人)类中继承,并增加了一个价格属性。不幸的是,当今的关系型数据库并不存在继承的概念。ORM框架主要通过以下两个手段来模仿这种行为:
●框架可以为每一个类生成一个单独的表。子类的表重复了那些从父类的字段。子类和父类都存储为各自对应的表。
●框架可以使用包含了所有子类属性的表。两种类(父类和子类)的实例都存储于同一张表—父类中不存在的字段(也就是,子类的字段)取null值。为了使继承映射更为强壮,表也可以有一个“区别”列,它存储的标记表明该行数据映射到哪一个类。
EJB 3.0实体bean支持上述两种映射策略,默认是单表映射策略。你可以简单地用注释指明子类的继承策略和区别字段的名字。下面是Consultant类的例子,它从Person类中继承:
@Entity
@Inheritance(discriminatorValue="C")
@DiscriminatorColumn(name="person_type")
public class Consultant extends Person {
protected double rate;
public void setRate (double rate) {
this.rate = rate;
}
public double getRate () {
return rate;
}
}
从上面的例子中,容器使用默认策略将Consultant类映射到Person类对应的同一张表中。如果表中的person_type字段的值为C,那么那一行数据就代表了一个顾问类。否则,当前行代表的是一个普通的Person类。
持久化档案
现在你的数据模型有了一组使用了注释EJB 3.0实体bean的类,你可以将它们捆绑在一起布署到服务器环境中。EJB 3.0为实体bean定义了一种特殊的归档格式,叫做持久化档案(文件后缀名为.par)。
一个.par文件是一组实体bean类文件加上一个简单的配置文件META-INF/persistence.xml的jar打包文件。persistence.xml文件定义了持久化上下文,它告知EJB 3.0哪一个后端数据库(数据源)与这一组实体bean相对应。persistence.xml也包含了配置属性的细节。举例来说,JBoss EJB 3.0是在Hibernate 3.0之上实现的,于是你可以通过persistence.xml传递任意的Hibernate配置选项。这有一个范例persistence.xml文件,它包含了JBoss和Hibernate专用的配置属性,包括SQL 方言(dialect)和二级缓存。
<entity-manager>
<name>cal</name>
<jta-data-source>java:/DefaultDS</jta-data-source>
<properties>
<property name="hibernate.dialect"
value="org.hibernate.dialect.MySQLDialect" />
<property name="hibernate.cache.provider_class"
value="org.jboss.ejb3.entity.TreeCacheProviderHook"/>
<property name="hibernate.treecache.mbean.object_name"
value="jboss.cache:service=EJB3EntityTreeCache"/>
</properties>
</entity-manager>
实体管理器
一旦你部署了实体bean, 你必须通过EJB 3.0的实体管理器的API来访问和操作它们。EJB 3.0容器为每个部署的持久化上下文(也就是,.par文件)提供了一个实体管理器对象。从一个EJB 3.0 session bean POJO(参看第一部分)中 ,你可以通过@PersistenceContext注释将实体管理器对象注入,并传入上下文的名字。
@Stateless
public class ManagerBean implements Manager {
@PersistenceContext (unitName="cal")
protected EntityManager em;
// Use "em"
// 使用“em”
// ... ...
}
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者