Ruby on Rails 雖吸睛,但企業級開發團隊多持懷疑:「腳本語言框架缺乏分布式事務、消息等企業級服務,不予考慮」。Grails 應運而生:基於 Groovy(JVM 動態語言),無縫集成 Java 生態服務,同時擁有腳本語言的極致便利。本文展示 Grails 如何以 EJB 3 實體 Bean 為後端,構建兼具企業級能力與 RAD 效率的 Web 應用。
// EmployeeBean.java
@Entity
public class EmployeeBean {
@Id @GeneratedValue Long id;
String networkId, firstName, lastName, startDate;
@OneToMany(mappedBy="employeeBean") Set computers;
// getter/setter...
}
// ComputerBean.java
@Entity
public class ComputerBean {
@Id @GeneratedValue Long id;
String name, type;
@ManyToOne EmployeeBean employeeBean;
// getter/setter...
}
import com.example.ejb3.EmployeeBean
// 引入 EJB 實體,無縫互操作
def showComputersByEmployee = {
render(view:'list', model:[
computerBeanList: ComputerBean.findAllByEmployeeBean(
EmployeeBean.get(params.id)
)
])
}
findAllByEmployeeBean 由 GORM 動態生成,無需手寫。
def update = {
def computerBean = ComputerBean.get(params.id)
if (computerBean) {
// 解除舊關聯
if (computerBean.employeeBean) {
computerBean.employeeBean.computers.remove(computerBean)
}
// 綁定參數(動態屬性賦值)
computerBean.properties = params
// 建立新關聯
def employeeBean = EmployeeBean.get(params.employeeId)
employeeBean.computers.add(computerBean)
computerBean.employeeBean = employeeBean
if (computerBean.save()) {
redirect(action:'show', id:computerBean.id)
} else {
render(view:'edit', model:[computerBean:computerBean])
}
} else {
flash.message = "ComputerBean not found with id ${params.id}"
redirect(action:'edit', id:params.id)
}
}
static constraints = {
networkId(length:6..8, blank:false, unique:true)
firstName(maxLength:20, blank:false)
lastName(maxLength:20, blank:false)
startDate(nullable:false)
}
自動生成前端驗證、後端驗證、錯誤消息綁定。
def showSearchResults = {
render(view:'list', model:[
employeeBeanList: EmployeeBean.findAllByLastNameLike("%${params.lastName}%")
])
}
def showSearchResults = {
def criteria = EmployeeBean.createCriteria()
def results = criteria {
or {
ilike("networkId", "%${params.networkId}%")
and {
eq("firstName", params.firstName)
eq("lastName", params.lastName)
}
}
}
render(view:'list', model:[employeeBeanList: results.adaptee])
}
| 維度 | 傳統 Java Web (Struts/Spring MVC + Hibernate) | Grails + EJB 3 |
|---|---|---|
| 樣板代碼 | 大量 Controller/Service/DAO/XML | 極少(約定優於配置、動態方法) |
| 領域模型 | 雙重維護或同步工具 | 單一來源:EJB 3 實體 |
| 企業級服務 | Spring 事務、安全、JMS... | 原生 Java EE 服務(EJB 容器提供) |
| 動態能力 | 靜態類型,重啟熱部署慢 | Groovy 動態 MOP,修改即時生效 |
| 團隊分工 | Java 開發全棧 | 領域專家維護 EJB 實體,Web 團隊專注 Grails |
Grails + EJB 3 實現了「企業級骨架 + 敏捷肌肉」的完美融合:EJB 3 提供分布式事務、安全、消息、集群等鋼筋鐵骨;Grails/GORM/Groovy MOP 賦予極致開發效率、動態查詢、聲明式驗證、約定優於配置的靈活肌肉。零侵入整合現有資產,雙向互調打破語言壁壘,這正是現代多語言架構(Polyglot Persistence/Polyglot Programming)的教科書級範例。