Grails的数据库相关开发
     1.开发domain和service
 在出来的输入框里输入domain的名字,可以包括包名。
这里我输入test.domain.House,点finish 
创建了两个groovy文件,一个当然是test.domain.House.groovy,另一个是test.domain.HouseTests.groovy.
先说test.domain.House.groovy。这个就是传说中的POGO。Grails会在运行时给他注入很多方法。 
现在给他增加两个属性: 
Groovy代码  收藏代码
package test.domain    
class House {        
    String name  
    String address    
    static constraints = {    
    }  
}    
新建一个service(方法参见上一篇),名称可以直接输入House的类全名。
编辑生成的service单元测试: 
Groovy代码  收藏代码
package test.domain        
import grails.test.mixin.*  
import org.junit.*    
/**  
 * See the API for {@link grails.test.mixin.services.ServiceUnitTestMixin} for usage instructions  
 */  
@TestFor(HouseService)  
@Mock(House)  
class HouseServiceTests {    
    void testFindByAddress() {  
        new House(name:"Beautiful House",address:"No.1").save();  
        def house = service.findByAddress("No.1")  
        assert house != null  
        println house.id  
    }  
}   
 注意这一行:
println house.id 
之前并没有给House定义ID,GORM会默认给他加上一个ID。
另外说一下@Mock(House)。因为domain要在grails运行时才会给domain注入方法,如果在单元测试的时候可以使用Mock这个annotation,给House这个domain注入运行时的模拟方法。 
实现一下service: 
Groovy代码  收藏代码
package test.domain    
class HouseService {    
    def findByAddress(String address) {  
        return House.findByAddress(address)  
    }  
}   
 findByAddress就是一个动态生成的方法,可以让我们按地址查找。 
运行一下HouseServiceTests这个单元测试: 
当然也可以先debug,跑完以后会弹出打开 TESTS-TestSuites.xml  这个文件。点下面的sheet切换:
就可以看到test里打的println了: 
<system-out><![CDATA[--Output from testFindByAddress--
1
]]></system-out>  
这个XML的格式不解释。 
service需要加事务吧: 
Groovy代码  收藏代码
package test.domain    
import org.springframework.transaction.annotation.Transactional;    
class HouseService {    
    @Transactional(readOnly=true)  
    def findByAddress(String address) {  
        return House.findByAddress(address)  
    }  
}  
 依然可以使用spring的@Transactional。当然也有别的方法。暂时不写了。
2.domain的验证
test.domain.HouseTests.groovy 不明白为什么要生成这个测试单元。方法都是Grails注入的,MS没什么好测的。
现在拿来做测试验证吧。
给test.domain.House.groovy加多几个属性: 
Groovy代码  收藏代码
package test.domain    
class House {        
    String name  
    String type  
    String desc  
    String address  
    Date buildedDate  
    Float price;    
    static constraints = {  
        type inList:["common","bungalow","villa"],nullable:true  
        desc maxSize:1000,nullable:true