|
|
本节将介绍如何通过OperaMasks Studio快速开发一个基于Hibernate框架和Spring框架的多表CRUD(Create,
Read, Update, Delete)应用
Step By Step
|
|
|
注:下列步骤中,如无特殊说明,均采用默认选项。
-
创建数据库表。此示范需要两个表,分别是费用表FEE及费用明细表FEE_DETAIL。它们之间存在一对多的主外键关系,数据库使用SQL Server
2000,创建表的SQL脚本如下
create table FEE (
id int primary key,
topic varchar(200),
userName varchar(100),
applyDate datetime
);
create table FEE_DETAIL (
id int primary key,
name varchar(100),
amount float,
feeId int references FEE(id)
);
delete from FEE_DETAIL;
delete from FEE;
insert into FEE values(1, '深圳至北京差旅费', 'Kevin','2008-6-1');
insert into FEE values(2, '部门活动经费', 'Kevin', '2008-10-20');
insert into FEE_DETAIL values (1, '深圳至北京机票', 1000, 1);
insert into FEE_DETAIL values (2, '北京至深圳机票', 1500, 1);
insert into FEE_DETAIL values (3, '吃饭', 800, 2);
insert into FEE_DETAIL values (4, '打保龄球', 600, 2) ;
-
创建Apusic工程,工程名为:AdvanceCRUD。
-
创建web模块。将其IoVC默认命名空间设置为 com.demo.beans。
-
添加Hibernate支持。
-
添加Spring支持。
-
在web模块的web/src目录下创建两个包,分别为com.demo.entities、com.demo.services,用于存放实体类、业务实现类。
-
从数据库反向生成实体。
-
选中刚建立的包com.demo.entities,右键->Apusic Tools->打开模型视图。
-
在模型视图的编辑区空白处点击右键->增强功能->数据库至代码同步。
-
在弹出的对话框中选择FEE和FEE_DETAIL表,点击确定。
-
可看到生成的实体类,如下
生成的Fee.java的代码如下
package com.demo.entities;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
/**
* Fee generated by Apusic Studio
*/
@Entity
@Table(name = "FEE", schema = "dbo", catalog = "CRUD")
public class Fee implements java.io.Serializable {
private int id;
private String topic;
private String userName;
private Date applyDate;
private Set<FeeDetail> feeDetails = new HashSet<FeeDetail>(0);
public Fee() {
}
public Fee(int id) {
this.id = id;
}
public Fee(int id, String topic, String userName, Date applyDate,
Set<FeeDetail> feeDetails) {
this.id = id;
this.topic = topic;
this.userName = userName;
this.applyDate = applyDate;
this.feeDetails = feeDetails;
}
@Id
@Column(name = "id", unique = true, nullable = false)
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
@Column(name = "topic", length = 200)
public String getTopic() {
return this.topic;
}
public void setTopic(String topic) {
this.topic = topic;
}
@Column(name = "userName", length = 100)
public String getUserName() {
return this.userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "applyDate", length = 23)
public Date getApplyDate() {
return this.applyDate;
}
public void setApplyDate(Date applyDate) {
this.applyDate = applyDate;
}
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "fee")
public Set<FeeDetail> getFeeDetails() {
return this.feeDetails;
}
public void setFeeDetails(Set<FeeDetail> feeDetails) {
this.feeDetails = feeDetails;
}
}
生成的FeeDetail.java代码如下
package com.demo.entities;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
/**
* FeeDetail generated by Apusic Studio
*/
@Entity
@Table(name = "FEE_DETAIL", schema = "dbo", catalog = "CRUD")
public class FeeDetail implements java.io.Serializable {
private int id;
private Fee fee;
private String name;
private Double amount;
public FeeDetail() {
}
public FeeDetail(int id) {
this.id = id;
}
public FeeDetail(int id, Fee fee, String name, Double amount) {
this.id = id;
this.fee = fee;
this.name = name;
this.amount = amount;
}
@Id
@Column(name = "id", unique = true, nullable = false)
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "feeId")
public Fee getFee() {
return this.fee;
}
public void setFee(Fee fee) {
this.fee = fee;
}
@Column(name = "name", length = 100)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
@Column(name = "amount", precision = 53, scale = 0)
public Double getAmount() {
return this.amount;
}
public void setAmount(Double amount) {
this.amount = amount;
}
}
-
映射实体。
-
双击打开Hibernate配置文件,并切换到“映射”标签页。
-
选中Fee.java文件及FeeDetail.java文件,将其拖拽到编辑器配置映射区域,如下,
此处也可以点击“添加”按钮查找并添加映射文件。
-
点击Save按钮,或者Ctrl+s保存配置文件,并点击“同步”按钮进行同步。
-
生成Spring DAO业务实现。
-
打开模型视图,在编辑区空白处点击右键->增强功能->生成业务实现
或是选中包com.demo.entities,右键->Apusic Tools->生成业务实现
-
选择需要生成的业务实现的类型,此处选择Spring Service实现,依照默认即可,点击下一步
-
选择实体类及输出包,如下
此处指定输出包为先前创建的 com.demo.services包,如下
-
点击“完成”,生成业务实现接口与类,如下
-
创建Faces页面及其托管Bean。
-
创建用于显示主界面的Faces页面,将其命名为fee.xhtml,步骤如下
-
在web节点右键->新建->Faces页面
-
输入文件名为fee,如下
-
选择Faces模板,保持默认即可
-
选择生成托管Bean,同样保持默认
-
将fee.xhtml的内容设置为
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE HTML PUBLIC "" "">
<f:view xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core"
xmlns:w="http://www.apusic.com/jsf/widget" xmlns:layout="http://www.apusic.com/jsf/layout"
xmlns:h="http://java.sun.com/jsf/html" xmlns:ajax="http://www.apusic.com/jsf/ajax"
renderKitId="AJAX">
<w:head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</w:head>
<w:page title="Fee CRUD">
<w:form>
<w:dataGrid paged="true" rows="10"
toolBarPosition="both" height="209" id="grid">
<w:outputColumn id="id"></w:outputColumn>
<w:outputColumn id="topic" header="主题">
</w:outputColumn>
<w:outputColumn id="userName" header="用户名">
</w:outputColumn>
<w:outputColumn id="applyDate" header="申请时间">
</w:outputColumn>
<w:toolBar target="grid">
<w:button id="create" value="添加"/>
<w:button id="modify" value="更改"/>
<w:button id="remove" value="删除"/>
<w:button id="refresh" value="刷新"/>
</w:toolBar>
<w:pagingToolbar target="grid"/>
</w:dataGrid>
</w:form>
<layout:window width="600" height="430" id="dialog" resizable="true">
<ajax:updater url="feeEdit.xhtml"
style="width: 100%; height: 100%"></ajax:updater>
</layout:window>
</w:page>
</f:view>
-
将其托管Bean类--包com.demo.beans下的FeeBean类的内容改为
package com.demo.beans;
import java.io.Serializable;
import java.util.List;
import org.operamasks.faces.annotation.Action;
import org.operamasks.faces.annotation.Bind;
import org.operamasks.faces.annotation.DataModel;
import org.operamasks.faces.annotation.ManagedBean;
import org.operamasks.faces.annotation.ManagedBeanScope;
import org.operamasks.faces.annotation.ManagedProperty;
import org.operamasks.faces.component.grid.impl.UIDataGrid;
import org.operamasks.faces.component.layout.impl.UIWindow;
import com.demo.entities.Fee;
import com.demo.services.IFeeService;
/**
* This managed bean is generated automatically
*/
@ManagedBean(name="feeBean", scope=ManagedBeanScope.SESSION)
public class FeeBean implements Serializable {
@Bind
private UIDataGrid grid;
@ManagedProperty("#{feeService}")
private IFeeService service;
@ManagedProperty("#{feeEditBean}")
private FeeEditBean editBean;
@Bind(id="dialog", attribute="binding")
private UIWindow dialog;
public UIDataGrid getGrid() {
return grid;
}
public void setGrid(UIDataGrid grid) {
this.grid = grid;
}
public UIWindow getDialog() {
return dialog;
}
public void setDialog(UIWindow dialog) {
this.dialog = dialog;
}
@Action(id="create")
public void create(){
editBean.setFeeBean(this);
editBean.shouldCreate();
dialog.show();
}
@Action(id="modify")
public void modify(){
Object[] values = grid.getSelectedValues();
if(values == null || values.length ==0) {
return;
}
Fee instane = (Fee) values[0];
editBean.setFeeBean(this);
editBean.shouldUpdate(instane);
editBean.getDetailGrid().reload();
dialog.show();
}
@Action(id="remove")
public void remove(){
Object[] values = grid.getSelectedValues();
if(values == null || values.length ==0) {
return;
}
Fee instane = (Fee) values[0];
service.remove(instane);
grid.reload();
}
@Action(id="refresh")
public void refresh(){
grid.reload();
}
@Action(id="grid", event="ondblclick")
public void grid_dblclick() {
modify();
}
@DataModel(id="grid")
private List<Fee> getGridValues(){
return service.findAll();
}
}
此时编译FeeBean类会报告出错,暂时无须理睬。
-
类似上述操作,创建Faces页面,命名为feeEdit.xhtml,内容为
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE HTML PUBLIC "" "">
<f:view xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core"
xmlns:w="http://www.apusic.com/jsf/widget" xmlns:layout="http://www.apusic.com/jsf/layout"
xmlns:h="http://java.sun.com/jsf/html" xmlns:ajax="http://www.apusic.com/jsf/ajax"
renderKitId="AJAX">
<w:head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</w:head>
<w:page title="Fee Edit">
<w:form>
<div align="center">
<layout:panelGrid columns="2">
<layout:cell colspan="1" rowspan="1">
<h:outputLabel for="id"></h:outputLabel>
</layout:cell>
<layout:cell colspan="1" rowspan="1">
<w:numberField id="id"></w:numberField>
</layout:cell>
<layout:cell colspan="1" rowspan="1">
<h:outputLabel for="topic" value="主题">
</h:outputLabel>
</layout:cell>
<layout:cell colspan="1" rowspan="1">
<w:textField id="topic"></w:textField>
</layout:cell>
<layout:cell colspan="1" rowspan="1">
<h:outputLabel for="userName" value="用户名">
</h:outputLabel>
</layout:cell>
<layout:cell colspan="1" rowspan="1">
<w:textField id="userName"></w:textField>
</layout:cell>
<layout:cell colspan="1" rowspan="1">
<h:outputLabel for="applyDate" value="申请日期">
</h:outputLabel>
</layout:cell>
<layout:cell colspan="1" rowspan="1">
<w:dateField id="applyDate"/>
</layout:cell>
</layout:panelGrid>
</div>
<w:editDataGrid paged="true" rows="10"
id="detailGrid" height="200" toolBarPosition="both">
<w:outputColumn id="id">
<w:numberField id="idEdit" allowBlank="true" />
</w:outputColumn>
<w:outputColumn id="name" header="名称">
<w:textField id="nameEdit" allowBlank="true" />
</w:outputColumn>
<w:outputColumn id="amount" header="账目">
<w:numberField id="amountEdit" allowBlank="true" />
</w:outputColumn>
<w:toolBar target="detailGrid">
<w:button id="addDetail" value="添加明细"/>
<w:button id="deleteDetail" value="删除明细"/>
</w:toolBar>
<w:pagingToolbar target="detailGrid" />
</w:editDataGrid>
<div style="position:absolute; bottom:0px;right:5px;z-index:0">
<layout:panelGrid columns="2">
<w:button id="save" value="保存"/>
<w:button id="cancel" value="取消"/>
</layout:panelGrid>
</div>
</w:form>
</w:page>
</f:view>
将其托管Bean--FeeEditBean的内容设置为
package com.demo.beans;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.operamasks.faces.annotation.Action;
import org.operamasks.faces.annotation.Bind;
import org.operamasks.faces.annotation.DataModel;
import org.operamasks.faces.annotation.ManagedBean;
import org.operamasks.faces.annotation.ManagedBeanScope;
import org.operamasks.faces.annotation.ManagedProperty;
import org.operamasks.faces.component.grid.impl.UIEditDataGrid;
import com.demo.entities.Fee;
import com.demo.entities.FeeDetail;
import com.demo.services.IFeeDetailService;
import com.demo.services.IFeeService;
/**
* This managed bean is generated automatically
*/
@ManagedBean(name = "feeEditBean", scope = ManagedBeanScope.SESSION)
public class FeeEditBean implements Serializable {
/**
* Inject the 'HEADER' service
*/
@ManagedProperty("#{feeService}")
private IFeeService service;
/**
* Inject the 'DETAIL' service
*/
@ManagedProperty("#{feeDetailService}")
private IFeeDetailService detailService;
/**
* the updated object handler
*/
private Fee updatedInstance = null;
/**
* the 'HEADER' ManagedBean
*/
private FeeBean instance;
/**
* the 'HEADER' property
*/
@Bind(id = "id", attribute = "value")
private int id;
/**
* the 'HEADER' property
*/
@Bind(id = "topic", attribute = "value")
private String topic;
/**
* the 'HEADER' property
*/
@Bind(id = "userName", attribute = "value")
private String userName;
/**
* the 'HEADER' property
*/
@Bind(id = "applyDate", attribute = "value")
private Date applyDate;
/**
* the handler of the detail datagrid
*/
@Bind(id = "detailGrid", attribute = "binding")
private UIEditDataGrid detailGrid;
/**
* the added data of detail datagrid
*/
@Bind(id = "detailGrid", attribute = "addedData")
private FeeDetail[] addedData;
/**
* the modified data of detail datagrid
*/
@Bind(id = "detailGrid", attribute = "modifiedData")
private FeeDetail[] modifiedData;
/**
* the removed data of detail datagrid
*/
@Bind(id = "detailGrid", attribute = "removedData")
private FeeDetail[] removedData;
/**
* the type of the detail datagrid
*/
@Bind(id = "detailGrid", attribute = "bindBean")
private Class detailBindBean = FeeDetail.class;
@Action(id = "save")
public void save() {
Fee obj = null;
if (updatedInstance != null) {
obj = updatedInstance;
} else {
obj = new Fee();
}
obj.setId (id);
obj.setTopic (topic);
obj.setUserName (userName);
obj.setApplyDate (applyDate);
if(updatedInstance != null) {
service.modify(obj);
}
else {
service.create(obj);
}
if (addedData != null) {
for (FeeDetail detail : addedData) {
detail.setFee(obj);
detailService.create(detail);
}
}
if (modifiedData != null) {
for (FeeDetail detail : modifiedData) {
detail.setFee(obj);
detailService.modify(detail);
}
}
if (removedData != null) {
for (FeeDetail detail : removedData) {
detail.setFee(obj);
detailService.remove(detail);
}
}
instance.getDialog().close();
instance.getGrid().reload();
}
@Action(id = "cancel")
public void cancel() {
instance.getDialog().close();
}
public void shouldCreate() {
this.updatedInstance = null;
this.id = 0;
this.topic = null;
this.userName = null;
this.applyDate = null;
this.detailGrid.reload();
}
public void shouldUpdate(Fee instance) {
if (instance != null) {
this.updatedInstance = instance;
this.id = instance.getId();
this.topic = instance.getTopic();
this.userName = instance.getUserName();
this.applyDate = instance.getApplyDate();
this.detailGrid.reload();
}
}
public FeeBean getFeeBean() {
return instance;
}
public void setFeeBean(FeeBean instance) {
this.instance = instance;
}
public UIEditDataGrid getDetailGrid() {
return detailGrid;
}
public void setDetailGrid(UIEditDataGrid detailGrid) {
this.detailGrid = detailGrid;
}
@DataModel(id = "detailGrid")
private List<FeeDetail> getDetailGridValues() {
if (updatedInstance != null) {
return new ArrayList<FeeDetail>(updatedInstance.getFeeDetails());
}
return new ArrayList<FeeDetail>();
}
@Action(id = "addDetail")
public void addDetail() {
detailGrid.appendRow();
}
@Action(id = "deleteDetail")
public void deleteDetail() {
detailGrid.remove();
}
}
-
在Apusic上部署。
在fee.xhtml上点击右键->运行方式->在Apusic服务器上运行
-
查看结果。
|
|
[下一页]
|
|