Combining Groovy, Grails, MySQL, and the Java Persistence API
来源:互联网 发布:windows.old可以移动吗 编辑:程序博客网 时间:2024/06/06 04:31
Combining Groovy, Grails, MySQL, and the Java Persistence API
by Carol McDonald
With the addition of support for scriptinglanguages in the Java platform, there has been a lot of interestin combining into web applications scripting languages such as Groovy, Java technologies such as the Java PersistenceAPI (JPA), and databases such as MySQL. Last year I wrote a Tech Tip titledCombining JavaServer FacesTechnology, Spring, and the Java Persistence API that showed how you can use JavaServer FacesTechnology, Spring, and the JPA to create an application that displays an online catalog of pets.In this tip, I'll show you how to create an online catalog application using the Groovy language, the Grails framework,the MySQL database, and the Java Persistence API.
A package that contains the code for the sample application accompanies the tip. The code examplesin the tip are taken from the source code of the sample (which is included in the package). In this tip, you'll useNetBeans IDE 6.5 Milestone 1to build the application and deploy it on the GlassFishapplication server. The NetBeans IDE is a modular, standards-based, integrated development environment (IDE) writtenin the Java programming language. The latest NetBeans IDE offering, NetBeans IDE 6.5 Milestone 1 (or M1 for short),offers many new features including support for Groovy and Grails.GlassFish is a free, open source application server that implements the newest features in the Java EE 5 platform.
A Summary of the Languages, Technologies, and Frameworks in the Sample Application
If you're not familiar with Groovy, Grails, MySQL, or the Java Persistence API, here are brief descriptions:
- Groovy is an agile and dynamic language for theJava Virtual Machine1. It compiles to Java bytecode and combines popular features fromlanguages such as Smalltalk, Python, and Ruby.
- Grails is an open-source web application framework that leveragesthe Groovy language and complements Java Web development. It aims to bring the "coding by convention" paradigmto Groovy. Grails is a Model-View-Controller based framework that simplifies the development of web applications byreducing the need for configuration files and by generating a lot of the things needed in a database-backed web application.
- MySQL is the world's most popular open-source database. It offersconsistently fast performance, high reliability and ease of use.
- The Java Persistence API provides a (plain oldJava object) POJO-based persistence model for Java EE and Java SE applications. It handles the details of how relationaldata is mapped to Java objects, and it standardizes Object/Relational (O/R) mapping.
The Sample Application
The sample application displays an online catalog of pets sold in a pet store. Figure 1 shows theCatalog Listing page, which allows a user to page through a list of items in a store.
Figure 1. Catalog Listing Page
Examining the Application
Earlier I mentioned that Grails is a Model-View-Controller based framework that simplifies the development of web applications.The online catalog application uses Grails and so it follows the MVC pattern, that is, the application isolates its data,the "Model", from the user interface, the "View", and from the code that manages the communicationbetween the model and the view, the "Controller". Let's first look at the Model for the application.
The Model
The Model not only represents the data for the application, but it also represent persistent data, that is, datathat persists beyond the life of the application. In other words, the Model represents an application's persistentbusiness domain objects. The application uses JPA to manage that persistence. In JPA, an entity instance -- an instance ofan entity object -- represents a row of data in a database table.
If you examine the source code for the application, you'll find the following two classes in the model
directory:Item
and Address
. Item
is an entity class -- a typical JPA entity object -- thatmaps to an item
table in a database. The table stores information about items in the catalog. Here is partof the source code for the Item
class:
package model;
import java.io.Serializable;
...
@Entity
@Table(name = "item")
public class Item implements Serializable {
private static final long serialVersionUID = 1L;
@Id
private Long id;
private String name;
private String description;
private String imageurl;
private String imagethumburl;
private BigDecimal price;
@ManyToOne(optional = false)
@JoinColumn(name = "address_id")
private Address address;
// getters and setters
...
}
Address
is an entity class that maps to an address
table in the database. The table storesaddresses associated with items in the catalog. Here is part of the source code for the Address
class:
package model;
import java.io.Serializable;
...
@Entity
public class Address implements Serializable {
private static final long serialVersionUID = 1L;
@Id
private Long id;
private String street1;
private String street2;
private String city;
private String state;
private String zip;
private BigDecimal latitude;
private BigDecimal longitude;
private BigInteger version;
@OneToMany(fetch = FetchType.EAGER,
cascade = { CascadeType.ALL },
mappedBy = "address")
private Collection<Item>items = new ArrayList();
// getters and setters
...
}
The Item
class has a many-to-one relationship with the Address
class, meaning thatthere can be multiple items in the catalog associated with the same address, but multiple addresses cannot be associatedwith the same item. This relationship is specified by the @ManyToOne
annotation in the Item
classand the @OneToMany(mappedBy = "address")
annotation in the Address
entity class.
Using JPA Entities With Grails and MySQL
To use the JPA entities for the application with Grails and MySQL, you first need to create a Grails applicationand then modify some files in the Grails application directory structure.
We'll use NetBeans IDE 6.5 M1 to create a Grails application. If you haven't already done so,download NetBeans IDE 6.5 Milestone 1and download Grails.
Start NetBeans IDE 6.5 Milestone 1. Select New Project from the File menu. Then select Groovy in the Categorieswindow and Grails in the Projects window as shown in Figure2.
Figure 2. Creating a Grails Project in NetBeans IDE 6.5 M1
Click the Next button and name the project, for instance, MyGrailsApp
. Accept the default project locationor browse to select a different location. Leave the Set as Main Project checkbox checked and click the Finish button.
In response, NetBeans creates the Grails project and a standard directory structure for a Grails application.Figure 3 shows the Grails directory structure for the online catalog application.
Figure 3. Grails Directory Structure for the Online Catalog Application
After you have your directory structure in place, do the following:
- Put your entity files in the app_name/src/java directory, where app_name is the name of your Grailsapplication. The
Item
andAddress
entity files for the online catalog application are in thecatalog/src/java/model
directory. - Get the MySQL jdbc driver,mysql-connector-java-5.1.6-bin.jar and put it in the
app_name/lib
directory.You can find themysql-connector-java-5.1.6-bin.jar
file for the online catalog application in thecatalog/lib
directory. - Modify the
DataSource.groovy
file in theapp_name/grails-app/conf
directory to use MySQLas the database and specify theGrailsAnnotationConfiguration
configuration class to use the annotationsin the JPA entities. The code marked in bold in the following code example shows the additions and modification that I madeto theDataSource.groovy
file for the online catalog application.import org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsAnnotationConfiguration
dataSource {
configClass = GrailsAnnotationConfiguration.class
pooled = false
driverClassName = "com.mysql.jdbc.Driver"
username = "root"
password = ""
dialect = "org.hibernate.dialect.MySQL5InnoDBDialect"
}
hibernate {
cache.use_second_level_cache=true
cache.use_query_cache=true
cache.provider_class='com.opensymphony.oscache.hibernate.OSCacheProvider'
}
// environment specific settings
environments {
development {
dataSource {
dbCreate = "create-drop" // one of 'create', 'create-drop','update'
url = "jdbc:mysql://localhost/petcatalog"
}
}
test {
dataSource {
dbCreate = "update"
url = "jdbc:mysql://localhost/petcatalog"
}
}
production {
dataSource {
dbCreate = "update"
url = "jdbc:mysql://localhost/petcatalog"
}
}
} - For Grails to recognize the JPA entities as domain classes, you need to addthe
hibernate.cfg.xml
file to theapp_name/grails-app/conf/hibernate
directory.Here is thehibernate.cfg.xml
file for the online catalog application. You can find it in thecatalog/grails-app/conf/hibernate
directory.<?xml version=""1.0" encoding="UTF-8"?>
<!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 package="model" />
<mapping class="model.Item" />
<mapping class="model.Address" />
</session-factory>
</hibernate-configuration>
The Controller
NetBeans IDE 6.5 M1 enables you to create domain classes and controllers, but I haven't found the menu option to generatecontrollers, so for now, let's use the command line as follows to generate a controller:
- Open a command prompt and navigate to the project directory for your Grails application. If you've forgotten where thisis, you can find it in the project's Properties dialog.
- Generate a controller for a domain class by entering the following command:
grails generate-controller domain-class
where domain-class is the domain class name. For example, to generate a controller for theItem
domain class in the online catalog application, I entered the following command:grails generate-controller model.Item
In response, the command generates a file named
domain-classController.groovy
in thegrails-app/controllers
directory. For theItem
class, the generated controller is ingrails-app/controllers/ItemController.groovy
.
Figure 4 shows the controller, ItemController.groovy
, in the NetBeans IDE 6.1 M1 Groovyeditor window.
Figure 4. A Controller Listed in the Grails Directory Structure for the Online Catalog Application
Controllers handle incoming HTTP requests, interact with the model to get data and process requests, invoke the correctview, and direct domain data to the view for display. In Grails, HTTP requests are handled by controller classes that containone or more action methods that are executed on request. The action methods either rendera Groovy Server Page(GSP) or redirect to another action. Grails routes requests to the controller action that corresponds to the URL mapping forthe request. In Grails, the default mapping from URL to action method follows the conventionhttp://host/app_name/controller/action/id where host is the host name,app_name is the name of the Grailsapplication, controller is the controller class, action is the action method, and idis the id of a passed parameter. For example, the URLhttp://host/catalog/item/list calls the list
action method in the item controller class. Here is code snippet inItemController.groovy
that shows the list
method:
import model.Item
class ItemController {
def index = { redirect(action:list,params:params) }
// the delete, save and update actions only accept POST requests
def allowedMethods = [delete:'POST', save:'POST', update:'POST']
def list = {
if(!params.max) params.max = 10
[ itemList: Item.list( params ) ]
}
Grails scaffolding provides a series of standardized controlleraction methods for listing, showing, creating, updating, and deleting objects of a class. These standardized actions comewith both controller logic and default view Groovy Server Pages. The list
action in ItemController
renders a view with a paginated list of item objects.
If a URL has a controller but no action, as is the case for http://localhost:8080/catalog/item/, Grails defaults to theindex
action. In the ItemController
code, the index
action method redirects to thelist
action method. The list
action method calls the Item.list()
method, whichreturns an ArrayList
of item
objects retrieved from the item
table in thedatabase. If there are more objects in the table than the number specified in params.max
(in this case, 10),Grails automatically creates next and previous pagination links. The Grails framework automatically makes theitemList
variable available to the view.
After executing code, actions usually render a GSP in the views
directory corresponding to the name of thecontroller and action. For example the list
action renders the GSP, list.gsp
, in thegrails-app/views/item
directory.
The View
The view layer uses data from domain objects provided by the controller to generate a web page. In Grails, the view isrendered using Groovy Server Pages. To generate the view, open a command prompt, navigate to the project directory foryour Grails application, and enter the following command:
grails generate-views domain-class
where domain-class is the domain class. For example, to generate a view for the Item
domain class in the online catalog application, I entered the following command:
grails generate-views model.Item
In response, the command generates GSPs for the domain class. For example, it generates create.gsp
,edit.gsp
, list.gsp
, for the model.Item
entity.
Here is part of the list.gsp
file for the online catalog application. Note that I modified the HTMLtable format that is generated by default to display the pet images.
<table>
<thead>
<tr>
<g:sortableColumn property="name" title="Name" />
<g:sortableColumn property="imagethumburl" title="Photo" />
<g:sortableColumn property="price" title="Price" />
</tr>
</thead>
<tbody>
<g:each in="${itemList}" status="i" var="item">
<tr class="${(i % 2) == 0 ? 'odd' : 'even'}">
<td>
<g:link action="show" id="${item.id}">
${item.name?.encodeAsHTML()}</g:link>
</td>
<td>
<img src="${createLinkTo(dir:'images',file:item.imagethumburl)}"/>
</td>
<td>${item.price?.encodeAsHTML()}</td>
</tr>
</g:each>
</tbody>
</table>
</div>
<div class="paginateButtons">
<g:paginate total="${Item.count()}" />
</div>
The view uses instance variables set by the controller to access the data it needs to render the GSP. Groovy Server Pagesuse a GroovyTagLib that is similar to the JSP tag library. Notice the tags that start with <g:
in the list.gsp
code. These are GroovyTags. Here is a brief summary of the GroovyTags and some otherelements in the list.gsp
code:
<g:sortableColumn>
- Renders a sortable column to support sorting in tables.
<g:each in="${itemList}" status="i" var="item">
- Loops through each object in the
itemList
variable, which is an orderedArrayList
ofItem
model objects, and assigns eachItem
model object to theitem
variable. <g:link action="show" id="${item.id}">${item.name?.encodeAsHTML()}</g:link>
- Creates an HTML anchor tag
href
based on the specified action, id, and controller parameters specified.In this example, it generates a link to theitem/show/id
action. This action will display thecorresponding item details. Here, the line generates the following HTML for the variableitem
:<a href="/catalog/item/show/2">Friendly Cat</a>
<img src="${createLinkTo(dir:'images',file:item.imagethumburl)}"/>
- Generates an HTML link for the item's attribute.
${item.price?.encodeAsHTML()}
- Displays the value of the item 's price attribute as escaped HTML text.
<g:paginate total="${Item.count()}" />
- Creates next/previous buttons and a breadcrumb trail to allow pagination of results using the domain method.
The Show Action Method
Recall that in Grails, the default mapping from URL to action method follows the conventionhttp://host/app_name/controller/action/id where host is the host name,app_name is the name of the Grailsapplication, controller is the controller class, action is the action method, and idis the id of the passed parameter. This means that in the online catalog application, a URL of http://host/item/show/1will route to the show action in the ItemController
, passing 1 to the method as the id of the parameter.The show
action of the ItemController
class is shown below. The ItemController
show
action renders a view showing the details of the item
object corresponding to theid
parameter.
def show = {
def item = Item.get( params.id )
if(!item) {
flash.message = "Item not found with id ${params.id}"
redirect(action:list)
}
else { return [ item : item ] }
}
The show
action method calls the Item.get()
method. That method, in turn, queriesthe items
table, and returns an item
instance variable that corresponds to theitem
whose attribute id (that is, its primary key) is equal to the id
parameter.This is the equivalent to the following SQL statement:
select * from items where id='1'
The Grails framework automatically makes the item
variable available to the Show
view.
The Show Item GSP
After executing the appropriate code, the show
action renders the show.gsp
filein the applications's views/item
directory. Here is the part of the show.gsp
filefor the online catalog application, presenting the item show view:
<table>
<tbody>
<tr class="prop"">
<td valign="top" class="name">Name:</td>
<td valign="top" class="value">${item.name}</td>
</tr>
<tr class="prop">
<td valign="top" class="name">Description:</td>
<td valign="top" class="value">${item.description}</td>
</tr>
<tr class="prop">
<td valign="top" class="name">Imageurl:</td>
<td valign="top" class="value">
<img src="${createLinkTo(dir:'images',file:item.imageurl)}" />
</td>
</tr>
<tr class="prop">
<td valign="top" class="name">Price:</td>
<td valign="top" class="value"> ${item.price}</td>
</tr>
<tr class="prop">
<td valign="top" class="name">Seller's Address:</td>
<td valign="top" class="value">${item?.address?.street1},
${item?.address?.city}, ${item?.address?.state}</td>
</tr>
</tbody>
</table>
Here are some important parts of the item show view:
${item.description}
- Displays the value of the item 's description attribute.
<img src="${createLinkTo(dir:'images',file:item.imageurl)}" /> ${item.description}
- Generates an HTML image tag for the item's
imageurl
attribute. ${item?.address?.city}
- Displays the value of the item's address city attribute.
Running the Sample Code
These instructions assume that you haveNetBeans IDE 6.1,GlassFish v2ur2, andMySQL installed.You can download all threein a single bundle. Another option is to download a bundle that includesSun Java System Application Server 9.1 Update 1 with MySQL Community Server.
- Install the GlassFish v2 plugin for Grails as follows:
- Start the GlassFish Update Center by issuing the following command:
GF_install/updatecenter/bin/updatetool
- Check the GlassFish Support for Grails Framework checkbox in the GlassFish Update Center and click Install.
- Start the GlassFish Update Center by issuing the following command:
- If you haven't already done so, download and install NetBeans IDE 6.5 M1.
- Download the sample code and extract its contents. You should now see the newly extracted directoryas
<sample_install_dir>/catalog
, where<sample_install_dir>
is the directorywhere you unzipped the sample package. For example, if you extracted the contents toC:/
on a Windows machine,then your newly created directory should be atC:/catalog
. - Start NetBeans IDE 6.5 Milestone 1.
- Start the MySQL database as follows:
- Click the Services tab in the NetBeans IDE.
- Expand the databases node. You should see the MySQL server database in the list of databases.
- Right-mouse click on the MySQL server database and select Start.
- Create the petcatalog database as follows:
- Right-mouse click on the MySQL server database and select Create Database.
- Enter the database name petcatalog. This will open a New Database Connection window. Click O.K. to accept the displayed settings.
- Create the tables in the MySQL pet-catalog database as follows:
- Expand the Drivers node. You should a driver for the petcatalog database in the list of drivers.
- Right-mouse click on the petcatalog driver and select Connect.
- Right-mouse click on the petcatalog driver and select Execute Command. This will open up a SQL command window.
- Copy the contents of the
catalog.sql
file in thecatalog
directory and paste the contents into the SQL command window. - Click the Run SQL icon (Ctrl+Shift+E) above the SQL command window.
- Create a WAR file as follows:
- Ensure that the username and password settings in the
catalog/grails-app/conf/DataSource.groovy
file are the same as the corresponding property settings in NetBeansIDE 6.5 M1 for the MySQL server database. - Right- click the catalog node in the Projects window.
- Select Grails, then Create war file. This will create a
catalog-0.1.war
file in your the catalog project directory. You might need to change the level of Grails expected by the application -- this is theapp.grails.version
setting in thecatalog/application.properties
file -- to align it with the level of Grails you have installed.
- Ensure that the username and password settings in the
- Copy the
catalog-0.1.war
file to theGF_install/domains/domain1/autodeploy
directory, where GF_install is the directory where you installed GlassFish. - Start GlassFish if you haven't already.
- Enter the URL
http://localhost:8080/catalog-0.1/
in your browser. You should see the home page of thesample application.
Further Reading
- Sample Store Catalog using Groovy and Grails and the Java Persistence API on Glassfish with MySQL
- Developing Grails with NetBeans
- GlassFish and Scripting
- TOTD #31: CRUDApplication using Grails - Hosted on GlassFish and MySQL
- Grails
- Groovy
- mysql Commands
About the Author
Carol McDonald is a Java Technology Evangelist at Sun Microsystems. As a software developer since 1986, Carol's experiencehas been in the technology areas of distributed network applications and protocols, including Java EE technology, XML,Internet/Intranet applications, LDAP, Distributed Network Management (CMIP,SNMP) and Email (X.400,X.500). Besides Java,Carol is also fluent in French and German.
1 As used on this web site, the terms "Java virtual machine"or "JVM" mean a virtual machine for the Java platform.
- Combining Groovy, Grails, MySQL, and the Java Persistence API
- grails,java,groovy定时执行
- the differences between groovy and java
- JPA-Java Persistence API
- Java Persistence API
- Java Persistence Api
- JPA-Java Persistence API
- 【文档摘要】J2EE Persistence - Introduction to the Java Persistence API【Entities】
- 【文档摘要】J2EE Persistence - Introduction to the Java Persistence API【Entities Inheritance】
- 【文档摘要】J2EE Persistence - Introduction to the Java Persistence API【Managing Entities】
- 【文档摘要】J2EE Persistence - Introduction to the Java Persistence API【Querying Entities】
- Groovy&Grails
- Groovy&Grails
- Java持久性API(The Java Persistence API)-一个简单的实体持久性编程模型
- Java持久性API(The Java Persistence API)-一个简单的实体持久性编程模型
- JPA 全称Java Persistence API
- JPA注解 Java Persistence API
- JPA (Java Persistence API)概述
- 小图生成
- 解决linux下oracle中文乱码的问题
- □ Struts2学习笔记(1)Struts2开发环境配置 □
- Android G1的nand分区情况
- Hibernate学习笔记-----------缓存的知识
- Combining Groovy, Grails, MySQL, and the Java Persistence API
- lightTPD配置
- 用VB.NET 2005编写定时关机程序
- 可爱的背景图
- 游戏编程学习笔记(2)
- JS 取当前日期、时间的代码
- Intelligencia.UrlRewriter 转到iis7的URL Rewrite Module需要注意的问题
- Tomcat与server.xml配置文件
- 调试WCF