精通Grails: Grails与遗留数据库
对 Java 类使用 Enterprise JavaBeans(EJB)3 注释
正如我在上面所提到的,Java 1.5 引入了注释。注释允许您通过添加 @ 前缀的方式直接向 Java 类添加元数据。Groovy 1.0 在其发行初期(2006 年 12 月)并不支持 Java 1.5 的诸如注释这样的语言特性。一年以后发行的 Groovy 1.5 则发生了翻天覆地的变化。这就意味着您也可以将 EJB3 注释的 Java 文件引入到一个现有的 Grails 应用程序中了。
再次启动 EJB3 注释的 Java 文件。将清单 14 展示的 AirportAnnotation.java 置于 src/java/org.davisworld.trip 中,紧挨着 AirportHbm.java 文件:
清单 14. AirportAnnotation.java
import javax.persistence.*;
@Entity
@Table(name="usgs_airports")
public class AirportAnnotation {
private long id;
private String name;
private String iata;
private String state;
private String lat;
private String lng;
@Id
@Column(name="airport_id", nullable=false)
public long getId() {
return id;
}
@Column(name="airport_name", nullable=false)
public String getName() {
return name;
}
@Column(name="locid", nullable=false)
public String getIata() {
return iata;
}
@Column(name="state", nullable=false)
public String getState() {
return state;
}
@Column(name="latitude", nullable=false)
public String getLat() {
return lat;
}
@Column(name="longitude", nullable=false)
public String getLng() {
return lng;
}
// The setter methods don't have an annotation on them.
// They are not shown here, but they should be in the file
// if you want to be able to change the values.
}
注意,一定要导入文件顶部的 javax.persistence 包。@Entity 与 @Table 注释了类声明,将它映射到了适当的数据库表中。其他的注释位于每一个字段的 getter 方法之上。所有的字段都应该有 @Column 注释,它将字段名映射到列名。主键也应该有一个 @ID 注释。
清单 15 中的 AirportAnnotationConstraints.groovy 文件与前面清单 10 中的例子没什么不同:
清单 15. AirportAnnotationConstraints.groovy
static constraints = {
name()
iata(maxSize:3)
state(maxSize:2)
lat()
lng()
}
AirportAnnotationController.groovy(清单 16 中所展示的)是按照通常的方式搭建的:
清单 16. AirportAnnotationController.groovy
class AirportAnnotationController {
def scaffold = AirportAnnotation
}
hibernate.cfg.xml 文件再次开始其作用。这回,语法有点不同。您直接将它指向类,而不是指向一个 HBM 文件,如清单 17 所示:
清单 17. hibernate.cfg.xml
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<mapping resource="AirportHbm.hbm.xml"/>
<mapping class="org.davisworld.trip.AirportAnnotation"/>
</session-factory>
</hibernate-configuration>
要让注释开始生效,还需要做最后一件事。Grails 并不是本来就被设置成可以查找 EJB3 注释的。而是需要导入 grails-app/conf/DataSource.groovy 中的一个特定的类,如清单 18 所示:
清单 18. DataSource.groovy
dataSource {
configClass = GrailsAnnotationConfiguration.class
pooled = false
driverClassName = "com.mysql.jdbc.Driver"
username = "grails"
password = "server"
}
一旦导入了 org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsAnnotationConfiguration 并允许 Spring 将其作为 configClass 而注入 dataSource 块之后,Grails 就会支持 EJB3 注释了,同时它还可以支持 HBM 文件和本地映射块。
如果忘了这最后一步的话(我几乎每一次在 Grails 中使用 EJB3 注释时都会忘记这一步 ),会得到如下的错误信息:
清单 19. 未注入 DataSource.groovy 中的 configClass 时抛出的异常
An AnnotationConfiguration instance is required to use
<mapping class="org.davisworld.trip.AirportAnnotation"/>