随笔 - 312, 文章 - 14, 评论 - 1393, 引用 - 0

导航

<2009年6月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

公告

关注我的新浪微博

我的著作









常用链接

留言簿(126)

我参与的团队

随笔分类(818)

随笔档案(310)

文章分类(1)

文章档案(8)

相册

ADSL、3G查询

CSDN

eclipse

ibm

Java EE

Linux

Web

云服务

代理网站

关注的网站

协议

喜欢的Blog

国内广告平台

图书出版

在线培训

开发工具

微博客户端

手机铃声

操作系统

  • ReactOS
  • 一个与windowXP/2003兼容的操作系统

数学

文件格式

源码资源

移动(Mobile)

编程语言

英语学习

最新随笔

搜索

  •  

积分与排名

  • 积分 - 1968853
  • 排名 - 6

最新评论

阅读排行榜

评论排行榜

eclipse + JBoss 5 + EJB3开发指南(10):通过继承实体Bean,将单个表映射成多个表(单表策略,SINGLE_TABLE)

本文为原创,如需转载,请注明作者和出处,谢谢!

上一篇:eclipse + JBoss 5 + EJB3开发指南(9):实现Entity Bean的多对多(many-to-many)映射

    如果以前使用过EJB1.xEJB2.x的实体Bean,会发现无法通过继承实体Bean将单个表分成多表。而在EJB3中,我们很容易实现这个功能。先看看图1所示的表结构和记录。

图1   t_accounts表的结构和记录

t_accounts表中,有一个account_type字段。这个字段是一个长度为1String类型字段。只能取两个值:CS。如果该字段值为C,表示活期帐户(CheckingAccount),如果该字段值为S,表示储蓄存款帐户(SavingsAccount)。t_accounts表的前三个字段(account_idbalanceaccount_type)是活期帐户和储蓄存款帐户都需要的,而interestrate只对储蓄存款帐户有意义,overdraftlimit只对活期帐户有意义。因此,我们可以将t_accounts表分成两个表,当account_type的值为C时和S时各为一个表。

如果使用EJB3的实体Bean,可以先编写一个Account类来封装t_accounts的前三个字段,代码如下:

package entity;

import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
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.Table;

@Entity
@Table(name
="t_accounts")
@Inheritance(strategy
=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name
="account_type")
public class Account
{
    
protected String id;
    
protected float balance;
    
protected String type;
    @Id
    @GeneratedValue(strategy
=GenerationType.IDENTITY)
    @Column(name
="account_id")
    
public String getId()
    {
        
return id;
    }
    
public void setId(String id)
    {
        
this.id = id;
    }
    
public float getBalance()
    {
        
return balance;
    }
    
public void setBalance(float balance)
    {
        
this.balance = balance;
    }
    @Column(name
="account_type",insertable=false, updatable=false)
    
public String getType()
    {
        
return type;
    }
    
public void setType(String type)
    {
        
this.type = type;
    }
}

    对于Account类的代码,要注意如下两个注释:

1. @Inheritance

2. @DiscriminatorColumn

    @Inheritance注释用于设置实体Bean的继承类型,默认值是InheritanceType.SINGLE_TABLE,也就是单表策略类型。如果使用该继承类型,每一个从该实体Bean继承的表都会被映射成一个子表。而这个子表需要根据一个鉴别字段的值来映射,在本例中该字段是account_type,这个字段由@DiscriminatorColumn注释来指定。还要注意一点的是,由于account_type字段现在被设置成了鉴别字段,因此,该字段值不能由开发人员通过代码动态指定,而必须在Account类的子类中通过注释来指定(在后面会详细介绍),因此,需要使用@Column注释将该字段对应的实体Bean属性设为不可插件和编辑的(insertable=false, updatable=false)。否则在运行程序时会抛出下面的异常:

org.hibernate.MappingException: Repeated column in mapping for entity: entity.SavingsAccount column: account_type (should be mapped with insert="false" update="false")

活期帐户的实体Bean的代码如下:


package entity;

import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;

@Entity
@DiscriminatorValue(
"C")
public class CheckingAccount extends Account
{
    
private double overdraftLimit;

    
public double getOverdraftLimit()
    {
        
return overdraftLimit;
    }

    
public void setOverdraftLimit(double overdraftLimit)
    {
        
this.overdraftLimit = overdraftLimit;
    }

}

CheckingAccount类中通过@DiscriminatorValue注释将account_type字段的值设为了C。如果使用CheckingAccount类来映射t_accounts表时,EJB容器会自动将t_accounts表的account_type字段值设为C(并不需要开发人员干预)。

储蓄存款帐户对应的实体Bean的代码如下:

package entity;

import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;

@Entity
@DiscriminatorValue(
"S")
public class SavingsAccount extends Account
{
    
private double interestRate;

    
public double getInterestRate()
    {
        
return interestRate;
    }

    
public void setInterestRate(double interestRate)
    {
        
this.interestRate = interestRate;
    }
}

可以下面的代码进行测试:

CheckingAccount ca = new CheckingAccount();
ca.setBalance(
342);
ca.setOverdraftLimit(
120);
em.persist(ca); 
// 自动将account_type字段的值设为C
SavingsAccount sa 
= new SavingsAccount();
sa.setBalance(
200);
sa.setInterestRate(
321);
em.persist(sa); 
//  自动将account_type字段的值设为S


下一篇:eclipse + JBoss 5 + EJB3开发指南(10):实体Bean连接策略(JOINED Strategy)





Android开发完全讲义(第2版)(本书版权已输出到台湾)

http://product.dangdang.com/product.aspx?product_id=22741502



Android高薪之路:Android程序员面试宝典 http://book.360buy.com/10970314.html


新浪微博:http://t.sina.com.cn/androidguy   昵称:李宁_Lining

posted on 2009-06-03 16:22 银河使者 阅读(1808) 评论(0)  编辑  收藏 所属分类: java 原创ejb3JBoss


只有注册用户登录后才能发表评论。


网站导航: