1.用netbeans6.5创建grails项目
2.修改DataSource.groovy
dataSource { pooled = true driverClassName = "com.mysql.jdbc.Driver" username = "root" password = "root" } 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 = "update" // one of 'create', 'create-drop','update' url = "jdbc:mysql://localhost/racetrack_dev" } } test { dataSource { dbCreate = "update" url = "jdbc:hsqldb:mem:testDb" } } production { dataSource { dbCreate = "update" url = "jdbc:hsqldb:file:prodDb;shutdown=true" } } }
将mysql-connector-java-5.1.6-bin.jar拷到项目lib目录下
3.创建两个domain
class Race { String name Date startDateTime String city String state Float distance Float cost Integer maxRunners=100000 static hasMany=[registrations:Registration] static constraints={ name(maxLength:50,blank:false) // startDateTime(validator:{return (it>new Date())}) city(maxLength:30,blank:false) state(inList:['GA','NC','SC','VA'],blank:false) distance(min:3.1f,max:100f) cost(min:0f,max:999.99f) } String toString(){ "${this.name}:${this.city},${this.state}" } }
class Registration { Race race String name Date dateOfBirth String gender='F' String postalAddress String emailAddress Date createAt=new Date() static belongsTo=Race static optionals=["postalAddress"] static constraints={ name(maxLength:50,blank:false) dateOfBirth(nullable:false) gender(inList:["M","F"]) postalAddress(maxLength:255) emailAddress(maxLength:50,email:true) race(nullable:false) } }
4.运用脚手架:
新建race和registration控制器,然后添加方法def scaffold=Race/Registration
或者直接在grails项目目录下:
D:\Backup\NetBeansProjects\RaceTrack>grails generate-all Welcome to Grails 1.0.4 - http://grails.org/ Licensed under Apache Standard License 2.0 Grails home is set to: D:\DevelopTool\grails Base Directory: D:\Backup\NetBeansProjects\RaceTrack Note: No plugin scripts found Running script D:\DevelopTool\grails\scripts\GenerateAll.groovy Environment set to development [groovyc] Compiling 1 source file to C:\Documents and Settings\Administrator\. grails\1.0.4\projects\RaceTrack\classes [copy] Copying 1 file to C:\Documents and Settings\Administrator\.grails\1. 0.4\projects\RaceTrack Domain Class name not specified. Please enter: Race [0] spring.GrailsWebApplicationContext Refreshing org.codehaus.groovy.grails.com mons.spring.GrailsWebApplicationContext@913c56: display name [org.codehaus.groov y.grails.commons.spring.GrailsWebApplicationContext@913c56]; startup date [Mon J an 26 10:49:03 CST 2009]; root of context hierarchy [0] spring.GrailsWebApplicationContext Bean factory for application context [org .codehaus.groovy.grails.commons.spring.GrailsWebApplicationContext@913c56]: org. springframework.beans.factory.support.DefaultListableBeanFactory@1aa5882 [groovyc] Compiling 1 source file to C:\Documents and Settings\Administrator\. grails\1.0.4\projects\RaceTrack\classes [copy] Copying 1 file to C:\Documents and Settings\Administrator\.grails\1. 0.4\projects\RaceTrack Generating views for domain class Race ... Generating controller for domain class Race ... Finished generation for domain class Race D:\Backup\NetBeansProjects\RaceTrack>grails generate-all Welcome to Grails 1.0.4 - http://grails.org/ Licensed under Apache Standard License 2.0 Grails home is set to: D:\DevelopTool\grails Base Directory: D:\Backup\NetBeansProjects\RaceTrack Note: No plugin scripts found Running script D:\DevelopTool\grails\scripts\GenerateAll.groovy Environment set to development [groovyc] Compiling 2 source files to C:\Documents and Settings\Administrator\ .grails\1.0.4\projects\RaceTrack\classes [copy] Copying 1 file to C:\Documents and Settings\Administrator\.grails\1. 0.4\projects\RaceTrack Domain Class name not specified. Please enter: Registration [0] spring.GrailsWebApplicationContext Refreshing org.codehaus.groovy.grails.com mons.spring.GrailsWebApplicationContext@39452f: display name [org.codehaus.groov y.grails.commons.spring.GrailsWebApplicationContext@39452f]; startup date [Mon J an 26 10:49:26 CST 2009]; root of context hierarchy [0] spring.GrailsWebApplicationContext Bean factory for application context [org .codehaus.groovy.grails.commons.spring.GrailsWebApplicationContext@39452f]: org. springframework.beans.factory.support.DefaultListableBeanFactory@442c76 [groovyc] Compiling 1 source file to C:\Documents and Settings\Administrator\. grails\1.0.4\projects\RaceTrack\classes [copy] Copying 1 file to C:\Documents and Settings\Administrator\.grails\1. 0.4\projects\RaceTrack Generating views for domain class Registration ... Generating controller for domain class Registration ... Finished generation for domain class Registration D:\Backup\NetBeansProjects\RaceTrack>
5.产生race和registration控制器
class RaceController { 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 [ raceInstanceList: Race.list( params ) ] } def show = { def raceInstance = Race.get( params.id ) if(!raceInstance) { flash.message = "Race not found with id ${params.id}" redirect(action:list) } else { return [ raceInstance : raceInstance ] } } def delete = { def raceInstance = Race.get( params.id ) if(raceInstance) { raceInstance.delete() flash.message = "Race ${params.id} deleted" redirect(action:list) } else { flash.message = "Race not found with id ${params.id}" redirect(action:list) } } def edit = { def raceInstance = Race.get( params.id ) if(!raceInstance) { flash.message = "Race not found with id ${params.id}" redirect(action:list) } else { return [ raceInstance : raceInstance ] } } def update = { def raceInstance = Race.get( params.id ) if(raceInstance) { raceInstance.properties = params if(!raceInstance.hasErrors() && raceInstance.save()) { flash.message = "Race ${params.id} updated" redirect(action:show,id:raceInstance.id) } else { render(view:'edit',model:[raceInstance:raceInstance]) } } else { flash.message = "Race not found with id ${params.id}" redirect(action:edit,id:params.id) } } def create = { def raceInstance = new Race() raceInstance.properties = params return ['raceInstance':raceInstance] } def save = { def raceInstance = new Race(params) if(!raceInstance.hasErrors() && raceInstance.save()) { flash.message = "Race ${raceInstance.id} created" redirect(action:show,id:raceInstance.id) } else { render(view:'create',model:[raceInstance:raceInstance]) } } }
6.产生的race的list/create/show/edit.gsp如下
list: <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta name="layout" content="main" /> <title>Race List</title> </head> <body> <div class="nav"> <span class="menuButton"><a class="home" href="${createLinkTo(dir:'')}">Home</a></span> <span class="menuButton"><g:link class="create" action="create">New Race</g:link></span> </div> <div class="body"> <h1>Race List</h1> <g:if test="${flash.message}"> <div class="message">${flash.message}</div> </g:if> <div class="list"> <table> <thead> <tr> <g:sortableColumn property="id" title="Id" /> <g:sortableColumn property="name" title="Name" /> <g:sortableColumn property="city" title="City" /> <g:sortableColumn property="state" title="State" /> <g:sortableColumn property="distance" title="Distance" /> <g:sortableColumn property="cost" title="Cost" /> </tr> </thead> <tbody> <g:each in="${raceInstanceList}" status="i" var="raceInstance"> <tr class="${(i % 2) == 0 ? 'odd' : 'even'}"> <td><g:link action="show" id="${raceInstance.id}">${fieldValue(bean:raceInstance, field:'id')}</g:link></td> <td>${fieldValue(bean:raceInstance, field:'name')}</td> <td>${fieldValue(bean:raceInstance, field:'city')}</td> <td>${fieldValue(bean:raceInstance, field:'state')}</td> <td>${fieldValue(bean:raceInstance, field:'distance')}</td> <td>${fieldValue(bean:raceInstance, field:'cost')}</td> </tr> </g:each> </tbody> </table> </div> <div class="paginateButtons"> <g:paginate total="${Race.count()}" /> </div> </div> </body> </html>
-----------------------------------------------------------------------------------
create: <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta name="layout" content="main" /> <title>Create Race</title> </head> <body> <div class="nav"> <span class="menuButton"><a class="home" href="${createLinkTo(dir:'')}">Home</a></span> <span class="menuButton"><g:link class="list" action="list">Race List</g:link></span> </div> <div class="body"> <h1>Create Race</h1> <g:if test="${flash.message}"> <div class="message">${flash.message}</div> </g:if> <g:hasErrors bean="${raceInstance}"> <div class="errors"> <g:renderErrors bean="${raceInstance}" as="list" /> </div> </g:hasErrors> <g:form action="save" method="post" > <div class="dialog"> <table> <tbody> <tr class="prop"> <td valign="top" class="name"> <label for="name">Name:</label> </td> <td valign="top" class="value ${hasErrors(bean:raceInstance,field:'name','errors')}"> <input type="text" id="name" name="name" value="${fieldValue(bean:raceInstance,field:'name')}"/> </td> </tr> <tr class="prop"> <td valign="top" class="name"> <label for="city">City:</label> </td> <td valign="top" class="value ${hasErrors(bean:raceInstance,field:'city','errors')}"> <input type="text" id="city" name="city" value="${fieldValue(bean:raceInstance,field:'city')}"/> </td> </tr> <tr class="prop"> <td valign="top" class="name"> <label for="state">State:</label> </td> <td valign="top" class="value ${hasErrors(bean:raceInstance,field:'state','errors')}"> <g:select id="state" name="state" from="${raceInstance.constraints.state.inList}" value="${raceInstance.state}" ></g:select> </td> </tr> <tr class="prop"> <td valign="top" class="name"> <label for="distance">Distance:</label> </td> <td valign="top" class="value ${hasErrors(bean:raceInstance,field:'distance','errors')}"> <input type="text" id="distance" name="distance" value="${fieldValue(bean:raceInstance,field:'distance')}" /> </td> </tr> <tr class="prop"> <td valign="top" class="name"> <label for="cost">Cost:</label> </td> <td valign="top" class="value ${hasErrors(bean:raceInstance,field:'cost','errors')}"> <input type="text" id="cost" name="cost" value="${fieldValue(bean:raceInstance,field:'cost')}" /> </td> </tr> <tr class="prop"> <td valign="top" class="name"> <label for="maxRunners">Max Runners:</label> </td> <td valign="top" class="value ${hasErrors(bean:raceInstance,field:'maxRunners','errors')}"> <input type="text" id="maxRunners" name="maxRunners" value="${fieldValue(bean:raceInstance,field:'maxRunners')}" /> </td> </tr> <tr class="prop"> <td valign="top" class="name"> <label for="startDateTime">Start Date Time:</label> </td> <td valign="top" class="value ${hasErrors(bean:raceInstance,field:'startDateTime','errors')}"> <g:datePicker name="startDateTime" value="${raceInstance?.startDateTime}" ></g:datePicker> </td> </tr> </tbody> </table> </div> <div class="buttons"> <span class="button"><input class="save" type="submit" value="Create" /></span> </div> </g:form> </div> </body> </html> ---------------------------------------------------------------------------
show:
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta name="layout" content="main" /> <title>Show Race</title> </head> <body> <div class="nav"> <span class="menuButton"><a class="home" href="${createLinkTo(dir:'')}">Home</a></span> <span class="menuButton"><g:link class="list" action="list">Race List</g:link></span> <span class="menuButton"><g:link class="create" action="create">New Race</g:link></span> </div> <div class="body"> <h1>Show Race</h1> <g:if test="${flash.message}"> <div class="message">${flash.message}</div> </g:if> <div class="dialog"> <table> <tbody> <tr class="prop"> <td valign="top" class="name">Id:</td> <td valign="top" class="value">${fieldValue(bean:raceInstance, field:'id')}</td> </tr> <tr class="prop"> <td valign="top" class="name">Name:</td> <td valign="top" class="value">${fieldValue(bean:raceInstance, field:'name')}</td> </tr> <tr class="prop"> <td valign="top" class="name">City:</td> <td valign="top" class="value">${fieldValue(bean:raceInstance, field:'city')}</td> </tr> <tr class="prop"> <td valign="top" class="name">State:</td> <td valign="top" class="value">${fieldValue(bean:raceInstance, field:'state')}</td> </tr> <tr class="prop"> <td valign="top" class="name">Distance:</td> <td valign="top" class="value">${fieldValue(bean:raceInstance, field:'distance')}</td> </tr> <tr class="prop"> <td valign="top" class="name">Cost:</td> <td valign="top" class="value">${fieldValue(bean:raceInstance, field:'cost')}</td> </tr> <tr class="prop"> <td valign="top" class="name">Max Runners:</td> <td valign="top" class="value">${fieldValue(bean:raceInstance, field:'maxRunners')}</td> </tr> <tr class="prop"> <td valign="top" class="name">Registrations:</td> <td valign="top" style="text-align:left;" class="value"> <ul> <g:each var="r" in="${raceInstance.registrations}"> <li><g:link controller="registration" action="show" id="${r.id}">${r?.encodeAsHTML()}</g:link></li> </g:each> </ul> </td> </tr> <tr class="prop"> <td valign="top" class="name">Start Date Time:</td> <td valign="top" class="value">${fieldValue(bean:raceInstance, field:'startDateTime')}</td> </tr> </tbody> </table> </div> <div class="buttons"> <g:form> <input type="hidden" name="id" value="${raceInstance?.id}" /> <span class="button"><g:actionSubmit class="edit" value="Edit" /></span> <span class="button"><g:actionSubmit class="delete" onclick="return confirm('Are you sure?');" value="Delete" /></span> </g:form> </div> </div> </body> </html>
-------------------------------------------------------------------------------------------------------
edit:
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <meta name="layout" content="main" /> <title>Edit Race</title> </head> <body> <div class="nav"> <span class="menuButton"><a class="home" href="${createLinkTo(dir:'')}">Home</a></span> <span class="menuButton"><g:link class="list" action="list">Race List</g:link></span> <span class="menuButton"><g:link class="create" action="create">New Race</g:link></span> </div> <div class="body"> <h1>Edit Race</h1> <g:if test="${flash.message}"> <div class="message">${flash.message}</div> </g:if> <g:hasErrors bean="${raceInstance}"> <div class="errors"> <g:renderErrors bean="${raceInstance}" as="list" /> </div> </g:hasErrors> <g:form method="post" > <input type="hidden" name="id" value="${raceInstance?.id}" /> <div class="dialog"> <table> <tbody> <tr class="prop"> <td valign="top" class="name"> <label for="name">Name:</label> </td> <td valign="top" class="value ${hasErrors(bean:raceInstance,field:'name','errors')}"> <input type="text" id="name" name="name" value="${fieldValue(bean:raceInstance,field:'name')}"/> </td> </tr> <tr class="prop"> <td valign="top" class="name"> <label for="city">City:</label> </td> <td valign="top" class="value ${hasErrors(bean:raceInstance,field:'city','errors')}"> <input type="text" id="city" name="city" value="${fieldValue(bean:raceInstance,field:'city')}"/> </td> </tr> <tr class="prop"> <td valign="top" class="name"> <label for="state">State:</label> </td> <td valign="top" class="value ${hasErrors(bean:raceInstance,field:'state','errors')}"> <g:select id="state" name="state" from="${raceInstance.constraints.state.inList}" value="${raceInstance.state}" ></g:select> </td> </tr> <tr class="prop"> <td valign="top" class="name"> <label for="distance">Distance:</label> </td> <td valign="top" class="value ${hasErrors(bean:raceInstance,field:'distance','errors')}"> <input type="text" id="distance" name="distance" value="${fieldValue(bean:raceInstance,field:'distance')}" /> </td> </tr> <tr class="prop"> <td valign="top" class="name"> <label for="cost">Cost:</label> </td> <td valign="top" class="value ${hasErrors(bean:raceInstance,field:'cost','errors')}"> <input type="text" id="cost" name="cost" value="${fieldValue(bean:raceInstance,field:'cost')}" /> </td> </tr> <tr class="prop"> <td valign="top" class="name"> <label for="maxRunners">Max Runners:</label> </td> <td valign="top" class="value ${hasErrors(bean:raceInstance,field:'maxRunners','errors')}"> <input type="text" id="maxRunners" name="maxRunners" value="${fieldValue(bean:raceInstance,field:'maxRunners')}" /> </td> </tr> <tr class="prop"> <td valign="top" class="name"> <label for="registrations">Registrations:</label> </td> <td valign="top" class="value ${hasErrors(bean:raceInstance,field:'registrations','errors')}"> <ul> <g:each var="r" in="${raceInstance?.registrations?}"> <li><g:link controller="registration" action="show" id="${r.id}">${r?.encodeAsHTML()}</g:link></li> </g:each> </ul> <g:link controller="registration" params="['race.id':raceInstance?.id]" action="create">Add Registration</g:link> </td> </tr> <tr class="prop"> <td valign="top" class="name"> <label for="startDateTime">Start Date Time:</label> </td> <td valign="top" class="value ${hasErrors(bean:raceInstance,field:'startDateTime','errors')}"> <g:datePicker name="startDateTime" value="${raceInstance?.startDateTime}" ></g:datePicker> </td> </tr> </tbody> </table> </div> <div class="buttons"> <span class="button"><g:actionSubmit class="save" value="Update" /></span> <span class="button"><g:actionSubmit class="delete" onclick="return confirm('Are you sure?');" value="Delete" /></span> </div> </g:form> </div> </body> </html>