Java EE 5.0 实战教程 第二部分:JPA Entity编程(域建模)

Java EE 5.0 实战教程 第二部分:JPA Entity编程(域建模)

 

2008-06-18 10:40:02
查看( 8 ) / 评论( 0 )

域建模是每个面向对象应用程序的核心,就像人的骨骼,如果骨骼都没有,什么界面呀,数据呀都无处可靠。在JPA之前,Java EE程序需要一套域建模,还需要一套类似的Entity Bean来处理Persistence,因为Entity Bean是和EJB容器相关的,不能运用在容器之外,这样就产生了重复,而重复是程序维护的恶梦,每一个改变都需要做多处的修改,一个不小心少改了一个地方就会产生莫名其妙的错误。JPA的出现使这个问题得到解决,JPA里的Entity可以和Persistence Context剥离从而可以象普通的Java类一样使用,详见讲稿Java Persistence API

 

  1. 根据以下的类图建立域建模,这的模型做了简化,目的是演示Java EE 5.0的开发,若需要更多的功能,读者可根据自己的需要进一步丰富数据模型

  1. Stock.java. 注意Stock.java是一个POJO,也就是最普通的Java类,通过加入@Entity注解使其变成了JPAEntity。详见Java Persistence API教程。

package entities;

 

import javax.persistence.Entity;

import javax.persistence.Id;

 

@Entity

public class Stock implements java.io.Serializable {

   

    @Id private String stockCode;

    private String stockName;

   

    /** Creates a new instance of Stock */

    public Stock() {

    }

 

    public String getStockCode() {

        return stockCode;

    }

 

    public void setStockCode(String stockCode) {

        this.stockCode = stockCode;

    }

 

    public String getStockName() {

        return stockName;

    }

 

    public void setStockName(String stockName) {

        this.stockName = stockName;

    }

   

}

 

 

  1. Trade.java. 注意Trade类应用了@ManyToOne注解来确定和别的Entity的关系。详见详见Java Persistence API教程。

package entities;

 

import java.util.Date;

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.GenerationType;

import javax.persistence.Id;

import javax.persistence.ManyToOne;

import javax.persistence.Temporal;

import javax.persistence.TemporalType;

 

@Entity()

public class Trade implements java.io.Serializable {

 

    @Id

    @GeneratedValue(strategy=GenerationType.AUTO)

    private Long id;

    @ManyToOne

    private Stock stock;

    private long shareNum;

    private double price;

    @ManyToOne

    private TradeType type;

   

    /** Creates a new instance of Trade */

    public Trade() {

    }

 

    public Long getId() {

        return id;

    }

 

    public void setId(Long id) {

        this.id = id;

    }

 

    public Stock getStock() {

        return stock;

    }

 

    public void setStock(Stock stock) {

        this.stock = stock;

    }

 

    public long getShareNum() {

        return shareNum;

    }

 

    public void setShareNum(long shareNum) {

        this.shareNum = shareNum;

    }

 

    public double getPrice() {

        return price;

    }

 

    public void setPrice(double price) {

        this.price = price;

    }

   

    public TradeType getType() {

        return type;

    }

 

    public void setType(TradeType type) {

        this.type = type;

    }

   

}

 

 

  1. Holding.java.

package entities;

 

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.GenerationType;

import javax.persistence.Id;

import javax.persistence.OneToOne;

 

@Entity()

public class Holding implements java.io.Serializable {

 

    @Id

    @GeneratedValue(strategy=GenerationType.AUTO)

    private Long id;

   

    @OneToOne

    private  Stock stock;

    private long shareNum;

    private double averageCost;

   

    /** Creates a new instance of Holding */

    public Holding() {

    }

 

    public Long getId() {

        return id;

    }

 

    public void setId(Long id) {

        this.id = id;

    }

 

    public Stock getStock() {

        return stock;

    }

 

    public void setStock(Stock stock) {

        this.stock = stock;

    }

 

    public long getShareNum() {

        return shareNum;

    }

 

    public void setShareNum(long shareNum) {

        this.shareNum = shareNum;

    }

 

    public double getAverageCost() {

        return averageCost;

    }

 

    public void setAverageCost(double averageCost) {

        this.averageCost = averageCost;

    }

   

}

 

 

  1. TradeType.java.

package entities;

 

import javax.persistence.Entity;

import javax.persistence.Id;

 

@Entity()

public class TradeType implements java.io.Serializable {

   

    @Id

    private int typeCode;

   

    private String description;

   

    public TradeType() {

    }

    public TradeType(int code) {

        this.typeCode = code;

    }   

    public TradeType(int code, String description){

        this.setTypeCode(code);

        this.setDescription(description);

    }

   

    public static TradeType BUY = new TradeType(1, "Buy");

    public static TradeType SELL = new TradeType(2, "Sell");

   

    public int getTypeCode() {

        return typeCode;

    }

   

    public void setTypeCode(int typeCode) {

        this.typeCode = typeCode;

    }

   

    public String getDescription() {

        return description;

    }

   

    public void setDescription(String description) {

        this.description = description;

    }

 

    public boolean equals(Object obj) {

        if(!(obj instanceof TradeType)){

            return false;

        }

        TradeType theType = (TradeType) obj;

        if(theType.getTypeCode() == getTypeCode()){

            return true;

        } else {

            return false;

        }

    }

 

}

 

 

  1. 读者可用拷贝的方式将这四个java类拷到NetBeans里。也可自己输入,NetBeans提供了丰富的编辑功能,象代码自动完成,实体模板及字段封装可帮助你快速地输入源代码。

 

  1. 建立持久性单元。持久性单元是JPA运行环境和物理数据库的连接,一旦指定了持久性单元,JPA运行环境就会自动地在指定的数据库里存储和提取数据。详见Java Persistence API教程。在创建持久性单元时,NetBeans还提供了一个工具,可方便地根据Entities来生成数据库表格,见c

 

  1.  
    1. 右键“StockApp-ejb”,选“新建”-“文件/文件夹…”

 

  1.  
    1. 在对话框里选“持久性”, “持久性单元”,点击“下一步”。

 

  1.  
    1. 在“数据源”一项填入 jdbc/stockDS(注意大小写,和前面必须一致), 并选择“创建”,然后点击“完成”。NetBeans提供了三种表生成策略:

      1. 创建:在部署项目时生成和Entity对印的数据表格

      2. 删除并创建:部署项目时生成表格,并在取消项目部署时删除表格 ,这个选项在开发初期,数据结构改动较多时特别有用。

      3. 无:不进行表格生成的操作。

 

  1. 建立一个会话Bean。这个会话Bean暂时不用,但必须存在,否则下一步部署项目时会出错。

 

  1. 部署项目。右键“StockApp”,选择“部署项目”

 

  1. NetBeans自动部署项目完成后,切换到“运行环境”,展开“数据库”,连接上“…./stockDB”(用户名/密码: stock/stock, 还记得第一部分准备的数据库吗?),打开“表”目录,可看到四个表:Stock, Trade, HoldingTradeType,这是NetBeans根据之前定义的Entities自动生成的。

 

  1. 接下来需要在TRADETYPE表里加入两个常量,可通过NetBeans的数据库工具来完成

    1. 右键“TRADETYPE”,选择“执行命令…”.

 

  1.  
    1. 在打开的“SQL 命令1”窗口里敲入以下命令,并按执行。

insert into tradetype values(1, 'Buy');

 

insert into tradetype values(2, 'Sell');

 

  1.  
    1. 在输出框里,可看见以下输出

0.062 秒内成功执行,但 1 行受到影响。

1 行,第 1

 

0 秒内成功执行,但 1 行受到影响。

3 行,第 1

 

0.062 秒后执行完毕,出现 0 个错误。

 

 

 

  1. 至此,Entity编程完毕,下面我们就可以用这些Entity来编写业务逻辑和页面了。

 

附录

有人会问了,你在这部分里介绍的是先编好JPA Entity然后再根据Entity生成数据库表格,如果我的项目不是新项目,只能使用已有的数据库表格,怎么办呢?别急,NetBeans提供了一个工具,可以根据数据库表格逆向生成JPA Entities。具体做法如下:

  1. 新建一个项目,常规或企业项目均可。

  2. 右键此项目,选择”新建”-“文件/文件夹…”

 

  1. 在对话框里选择“持久性” ,“通过数据库生成实体类”,然后“下一步”

 

  1. 选择你要操作的数据库连接,NetBeans会根据数据库连接提取出可用表,你可全选可用表或者是部分你感兴趣的表,然后“下一步”

 

  1. NetBeans会根据表的名称自动给出实体类名,你可以根据需要做修改。然后指定类生成的位置和包。NetBeans还给一个机会让你创建持久性单元。最后点“完成”,NetBeans就会自动生成实体类。

 

  1. 生成的Trade.java的例子。看起来比我们自己编的还好,连NamedQuery都给做好了,注解的运用也规范多了。

…….

 

@Entity

@Table(name = "TRADE")

@NamedQueries( {

        @NamedQuery(name = "Trade.findById", query = "SELECT t FROM Trade t WHERE t.id = :id"),

        @NamedQuery(name = "Trade.findByPrice", query = "SELECT t FROM Trade t WHERE t.price = :price"),

        @NamedQuery(name = "Trade.findByTradingdate", query = "SELECT t FROM Trade t WHERE t.tradingdate = :tradingdate"),

        @NamedQuery(name = "Trade.findBySharenum", query = "SELECT t FROM Trade t WHERE t.sharenum = :sharenum")

    })

public class Trade implements Serializable {

 

    @Id

    @Column(name = "ID", nullable = false)

    private BigInteger id;

 

    @Column(name = "PRICE")

    private Double price;

 

    @Column(name = "TRADINGDATE")

    @Temporal(TemporalType.DATE)

    private Date tradingdate;

 

    @Column(name = "SHARENUM")

    private BigInteger sharenum;

 

    @JoinColumn(name = "STOCK_STOCKCODE", referencedColumnName = "STOCKCODE")

    @ManyToOne

    private Stock stockStockcode;

 

    @JoinColumn(name = "TYPE_TYPECODE", referencedColumnName = "TYPECODE")

    @ManyToOne

    private Tradetype typeTypecode;

   

…….

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值