Groovy轻松入门——Grails实战之遗留数据库处理篇(更新于2007.09.23)
由于在过去一段时间内,已有多位朋友向我询问如何用Grails处理遗留数据库,为了回答这个问题。我给出一个实例,并适当讲解,不足之处,敬请谅解。
在Grails0.6+中,配置稍有不同,详见 朝花夕拾——Groovy & Grails
我使用的数据库为MySQL5,其中存在一个名为legacy_dev的schema,legacy_dev中有一张表叫user:
1,创建Grails应用程序,我将它命名为legacy:grails create-app legacy
2,创建一个域类User:grails create-domain-class User
3,修改grails-app\domain\User.groovy的内容,如下所示:
class
User {
String userId
String password
static constraints = {
userId(blank: false , maxSize: 16 )
password(blank: false , maxSize: 45 )
}
}
String userId
String password
static constraints = {
userId(blank: false , maxSize: 16 )
password(blank: false , maxSize: 45 )
}
}
4,生成与域类User相关的所有Grails应用程序工件(artifact):grails generate-all User
5,将grails-app\conf\DevelopmentDataSource.groovy的内容改为:
class
DevelopmentDataSource {
boolean pooling = true
// 将这行注释掉
// String dbCreate = 'update' // one of 'create', 'create-drop','update'
// url和driver要正确
String url = " jdbc:mysql://localhost:3306/legacy_dev "
String driverClassName = " com.mysql.jdbc.Driver "
String username = " root "
String password = "" // 这里为您的密码 :)
}
boolean pooling = true
// 将这行注释掉
// String dbCreate = 'update' // one of 'create', 'create-drop','update'
// url和driver要正确
String url = " jdbc:mysql://localhost:3306/legacy_dev "
String driverClassName = " com.mysql.jdbc.Driver "
String username = " root "
String password = "" // 这里为您的密码 :)
}
6,自行配置Hibernate:
hibernate.cfg.xml
<?
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 >
< property name ="connection.driver_class" > com.mysql.jdbc.Driver </ property >
< property name ="connection.url" > jdbc:mysql://localhost:3306/legacy_dev </ property >
< property name ="connection.username" > root </ property >
< property name ="connection.password" ></ property >
< property name ="connection.pool_size" > 1 </ property >
< property name ="dialect" > org.hibernate.dialect.MySQLDialect </ property >
< property name ="current_session_context_class" > thread </ property >
< property name ="cache.provider_class" > org.hibernate.cache.NoCacheProvider </ property >
< property name ="show_sql" > true </ property >
< property name ="hbm2ddl.auto" > validate </ property >
< mapping resource ="User.hbm.xml" />
</ session-factory >
</ hibernate-configuration >
<! DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd" >
< hibernate-configuration >
< session-factory >
< property name ="connection.driver_class" > com.mysql.jdbc.Driver </ property >
< property name ="connection.url" > jdbc:mysql://localhost:3306/legacy_dev </ property >
< property name ="connection.username" > root </ property >
< property name ="connection.password" ></ property >
< property name ="connection.pool_size" > 1 </ property >
< property name ="dialect" > org.hibernate.dialect.MySQLDialect </ property >
< property name ="current_session_context_class" > thread </ property >
< property name ="cache.provider_class" > org.hibernate.cache.NoCacheProvider </ property >
< property name ="show_sql" > true </ property >
< property name ="hbm2ddl.auto" > validate </ property >
< mapping resource ="User.hbm.xml" />
</ session-factory >
</ hibernate-configuration >
User.hbm.xml
<?
xml version="1.0"
?>
<! DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
< hibernate-mapping >
< class name ="User" table ="user" >
< id name ="userId" column ="user_id" type ="java.lang.String" length ="16" >
< generator class ="assigned" />
</ id >
< property name ="password" column ="password" type ="java.lang.String" length ="45" />
</ class >
</ hibernate-mapping >
<! DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
< hibernate-mapping >
< class name ="User" table ="user" >
< id name ="userId" column ="user_id" type ="java.lang.String" length ="16" >
< generator class ="assigned" />
</ id >
< property name ="password" column ="password" type ="java.lang.String" length ="45" />
</ class >
</ hibernate-mapping >
最后,别忘了修改grails-app\controllers\UserController.groovy以及各GSP的代码
(试验代码时,请不要在Edit User页面中更新用户的userId,否则出发生异常,因为‘主键’不可更改。
在自己的应用程序中,可以disable掉Edit User页面中的User Id文本域)
UserController.groovy
class UserController {
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
[ userList: User.list( params ) ]
}
def show = {
// [ user : User.get( params.id ) ]
[ user : User.findByUserId(params.id) ]
}
def delete = {
// def user = User.get( params.id )
def user = User.findByUserId(params.id)
if (user) {
user.delete()
flash.message = " User ${params.id} deleted. "
redirect(action:list)
}
else {
flash.message = " User not found with id ${params.id} "
redirect(action:list)
}
}
def edit = {
// def user = User.get( params.id )
def user = User.findByUserId(params.id)
if ( ! user) {
flash.message = " User not found with id ${params.id} "
redirect(action:list)
}
else {
return [ user : user ]
}
}
def update = {
// def user = User.get( params.id )
def user = User.findByUserId(params.id)
if (user) {
user.properties = params
if (user.save()) {
// redirect(action:show,id:user.id)
redirect(action:show,id:user.userId)
}
else {
render(view: ' edit ' ,model:[user:user])
}
}
else {
flash.message = " User not found with id ${params.id} "
redirect(action:edit,id:params.id)
}
}
def create = {
def user = new User()
user.properties = params
return [ ' user ' :user]
}
def save = {
def user = new User()
user.properties = params
if (user.save()) {
// redirect(action:show,id:user.id)
redirect(action:show,id:user.userId)
}
else {
render(view: ' create ' ,model:[user:user])
}
}
}
grails-app\views\user\list.gsp
< html >
< head >
< meta http-equiv ="Content-Type" content ="text/html; charset=UTF-8" />
< meta name ="layout" content ="main" />
< title > User List </ title >
</ head >
< body >
< div class ="nav" >
< span class ="menuButton" >< a href ="${createLinkTo(dir:'')}" > Home </ a ></ span >
< span class ="menuButton" >< g:link action ="create" > New User </ g:link ></ span >
</ div >
< div class ="body" >
< h1 > User List </ h1 >
< g:if test ="${flash.message}" >
< div class ="message" >
${flash.message}
</ div >
</ g:if >
< table >
< thead >
< tr >
<!--
<g:sortableColumn property="id" title="Id" />
-->
< g:sortableColumn property ="userId" title ="User Id" />
< g:sortableColumn property ="password" title ="Password" />
< th ></ th >
</ tr >
</ thead >
< tbody >
< g:each in ="${userList}" >
< tr >
<!--
<td>${it.id?.encodeAsHTML()}</td>
-->
< td > ${it.userId?.encodeAsHTML()} </ td >
< td > ${it.password?.encodeAsHTML()} </ td >
< td class ="actionButtons" >
<!--
<span class="actionButton"><g:link action="show" id="${it.id}">Show</g:link></span>
-->
< span class ="actionButton" >< g:link action ="show" id ="${it.userId}" > Show </ g:link ></ span >
</ td >
</ tr >
</ g:each >
</ tbody >
</ table >
< div class ="paginateButtons" >
< g:paginate total ="${User.count()}" />
</ div >
</ div >
</ body >
</ html >
grails-app\views\user\show.gsp
< html >
< head >
< meta http-equiv ="Content-Type" content ="text/html; charset=UTF-8" />
< meta name ="layout" content ="main" />
< title > Show User </ title >
</ head >
< body >
< div class ="nav" >
< span class ="menuButton" >< a href ="${createLinkTo(dir:'')}" > Home </ a ></ span >
< span class ="menuButton" >< g:link action ="list" > User List </ g:link ></ span >
< span class ="menuButton" >< g:link action ="create" > New User </ g:link ></ span >
</ div >
< div class ="body" >
< h1 > Show User </ 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">${user.id}</td>
</tr>
-->
< tr class ="prop" >
< td valign ="top" class ="name" > User Id: </ td >
< td valign ="top" class ="value" > ${user.userId} </ td >
</ tr >
< tr class ="prop" >
< td valign ="top" class ="name" > Password: </ td >
< td valign ="top" class ="value" > ${user.password} </ td >
</ tr >
</ tbody >
</ table >
</ div >
< div class ="buttons" >
< g:form controller ="user" >
<!--
<input type="hidden" name="id" value="${user?.id}" />
-->
< input type ="hidden" name ="id" value ="${user?.userId}" />
< span class ="button" >< g:actionSubmit value ="Edit" /></ span >
< span class ="button" >< g:actionSubmit value ="Delete" /></ span >
</ g:form >
</ div >
</ div >
</ body >
</ html >
grails-app\views\user\create.gsp
< html >
< head >
< meta http-equiv ="Content-Type" content ="text/html; charset=UTF-8" />
< meta name ="layout" content ="main" />
< title > Create User </ title >
</ head >
< body >
< div class ="nav" >
< span class ="menuButton" >< a href ="${createLinkTo(dir:'')}" > Home </ a ></ span >
< span class ="menuButton" >< g:link action ="list" > User List </ g:link ></ span >
</ div >
< div class ="body" >
< h1 > Create User </ h1 >
< g:if test ="${flash.message}" >
< div class ="message" > ${flash.message} </ div >
</ g:if >
< g:hasErrors bean ="${user}" >
< div class ="errors" >
< g:renderErrors bean ="${user}" 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 ='userId' > User Id: </ label ></ td >< td valign ='top' class ='value ${hasErrors(bean:user,field:'userId','errors')}' >< input type ="text" name ='userId' value ="${user?.userId?.encodeAsHTML()}" /></ td ></ tr >
< tr class ='prop' >< td valign ='top' class ='name' >< label for ='password' > Password: </ label ></ td >< td valign ='top' class ='value ${hasErrors(bean:user,field:'password','errors')}' >< input type ="text" name ='password' value ="${user?.password?.encodeAsHTML()}" /></ td ></ tr >
</ tbody >
</ table >
</ div >
< div class ="buttons" >
< span class ="formButton" >
< input type ="submit" value ="Create" ></ input >
</ span >
</ div >
</ g:form >
</ div >
</ body >
</ html >
grails-app\views\user\edit.gsp
< html >
< head >
< meta http-equiv ="Content-Type" content ="text/html; charset=UTF-8" />
< meta name ="layout" content ="main" />
< title > Edit User </ title >
</ head >
< body >
< div class ="nav" >
< span class ="menuButton" >< a href ="${createLinkTo(dir:'')}" > Home </ a ></ span >
< span class ="menuButton" >< g:link action ="list" > User List </ g:link ></ span >
< span class ="menuButton" >< g:link action ="create" > New User </ g:link ></ span >
</ div >
< div class ="body" >
< h1 > Edit User </ h1 >
< g:if test ="${flash.message}" >
< div class ="message" > ${flash.message} </ div >
</ g:if >
< g:hasErrors bean ="${user}" >
< div class ="errors" >
< g:renderErrors bean ="${user}" as ="list" />
</ div >
</ g:hasErrors >
<!--
<div class="prop">
<span class="name">Id:</span>
<span class="value">${user?.id}</span>
</div>
-->
< g:form controller ="user" method ="post" >
<!--
<input type="hidden" name="id" value="${user?.id}" />
-->
< input type ="hidden" name ="id" value ="${user?.userId}" />
< div class ="dialog" >
< table >
< tbody >
< tr class ='prop' >< td valign ='top' class ='name' >< label for ='userId' > User Id: </ label ></ td >< td valign ='top' class ='value ${hasErrors(bean:user,field:'userId','errors')}' >< input type ="text" name ='userId' value ="${user?.userId?.encodeAsHTML()}" /></ td ></ tr >
< tr class ='prop' >< td valign ='top' class ='name' >< label for ='password' > Password: </ label ></ td >< td valign ='top' class ='value ${hasErrors(bean:user,field:'password','errors')}' >< input type ="text" name ='password' value ="${user?.password?.encodeAsHTML()}" /></ td ></ tr >
</ tbody >
</ table >
</ div >
< div class ="buttons" >
< span class ="button" >< g:actionSubmit value ="Update" /></ span >
< span class ="button" >< g:actionSubmit value ="Delete" /></ span >
</ div >
</ g:form >
</ div >
</ body >
</ html >
好了,整个处理过程已经呈现给大家了,希望对大家有用 :)
附: 朝花夕拾——Groovy & Grails