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
buildedDate max:new Date(),nullable:true
price max:98765432109876543210f,scale:2,nullable:true
}
}
重点看下边的constraints。这里定义属性的约束 ,选了几个典型的。
inList,适用于枚举。
desc这种属于大文本,字符串默认在数据库里会变成 varchar(255) ,定义了最大值就会成为TEXT
bulidedDate这种属于历史时间,不应当晚于当前时间。参照这种定义方法。
price属于浮点,定义最大最小值的时候需要注意要是浮点数(注意最后的f),默认的scale是3
测试代码如下:
Groovy代码 收藏代码
package test.domain
import grails.test.mixin.*
import grails.test.mixin.domain.DomainClassUnitTestMixin;
import org.junit.*
/**
* See the API for {@link grails.test.mixin.domain.DomainClassUnitTestMixin} for usage instructions
*/
@TestFor(House)
class HouseTests {
void testSomething() {
mockForConstraintsTests(House)
def house = new House(name:"House1",type:"unknown");
assert !house.validate()
println house.errors["type"]
}
}
mockForConstraintsTests(House)是内置的给domain加上验证框架的内置方法的一个mock。house.validate()用于验证所有定义的约束,可以用在web和service里,house.errors["属性名"]可以查违反的约束。
运行测试可以看到结果。
3.domain间的关系
关于一对一,多对对,一对多,多对一的这些个关系,官方的reference写得挺清楚,不翻译了。
不过得注意一下这个belongsTo
如让房子有个主人:
Groovy代码 收藏代码
package test.domain
class House {
String name
String type
String desc
String address
Date buildedDate
Float price;
static belongsTo = [owner:Person]
static constraints = {
type inList:["common","bungalow","villa"],nullable:true
desc maxSize:1000,nullable:true
buildedDate max:new Date(),nullable:true
price max:98765432109876543210f,scale:2,nullable:true
}
}
package test.domain
Groovy代码 收藏代码
class Person {
String name
static hasMany = [houses:House]
static constraints = {
}
}
这时房子从属于人,当人删除的时候会对房子造成级联删除。有一定危险,使用的时候要注意。
由于不知道怎么在单元测试里检验下面要说的东西所以……
以下内容属于道听未经验证
4.多数据源
假设第二个数据源叫datasoruce_second,配置如下
Groovy代码 收藏代码
environments {
development {
dataSource {
dbCreate = "create-drop"
url = "jdbc:h2:mem:devDb"
}
dataSource_second {
dialect = org.hibernate.dialect.MySQLInnoDBDialect
driverClassName = 'com.mysql.jdbc.Driver'
username = 'root'
password = 'root'
url = 'jdbc:mysql://localhost/root'
dbCreate = 'update'
}
}
test {
dataSource {
dbCreate = "update"
url = "jdbc:h2:mem:testDb"
}
}
production {
dataSource {
dbCreate = "update"
url = "jdbc:h2:prodDb"
}
dataSource_second {
dialect = org.hibernate.dialect.Oracle10gDialect
driverClassName = 'oracle.jdbc.driver.OracleDriver'
username = 'root'
password = 'root'
url = 'jdbc:oracle:thin:@localhost:1521:root'
dbCreate = 'update'
}
}
}
如果人这个表用的这个数据源:
Groovy代码 收藏代码
package test.domain
class Person {
String name
static hasMany = [houses:House]
static constraints = {
datasources(["second"])
}
}
另外还可以引入别的datasource的包,把数据源当成spring的bean注入到程序里使用。
5.直接执行SQL
一种方法当然是写java代码,然后groovy当bean来调用,这种感觉用groovy用得比较假。。。
直接写SQL的形如:
Groovy代码 收藏代码
package test.sql
import groovy.sql.Sql
class SQLTestService {
def dataSource
def sqlRun() {
def db = new Sql(dataSource)
db.eachRow('select * from house'){
println it
}
}
}
以上两节留待以后验证
Grails的数据库相关开发的更多相关文章
- MySQL数据库相关开发入门
使用apt-get来进行MYSQL数据库的安装,安装好以后就可以使用数据库了. 命令行键入mysql即可进入(因为数据库初始化的没有密码的):当然为了安全,你最好还是创建一个用户和密码. 当你创建过用 ...
- Atitit 基于meta的orm,提升加速数据库相关应用的开发
Atitit 基于meta的orm,提升加速数据库相关应用的开发 1.1. Overview概论1 1.2. Function & Feature功能特性1 1.2.1. meta api2 ...
- 安卓项目-利用Sqlite数据库,开发新闻发布系统
本教程致力于程序员可以快速的学习安卓移动端手机开发. 适合于已经习得一种编程语言的同仁. 更多志同道合,想要学习更多编程技术的大神们. 小弟不才,麻烦关注一下我的今日头条号-做全栈攻城狮. 本文章是基 ...
- PB数据库相关
---------------------------------------------------------------- 数据库画板: 一张表定义了主键或者唯一索引,则能够在Results视窗 ...
- Oracle数据库之开发PL/SQL子程序和包
Oracle数据库之开发PL/SQL子程序和包 PL/SQL块分为匿名块与命名块,命名块又包含子程序.包和触发器. 过程和函数统称为PL/SQL子程序,我们可以将商业逻辑.企业规则写成过程或函数保 ...
- sourceforge.net安装网站程序数据库相关
sourceforge.net安装网站程序数据库相关 我们应该知道sourceforge.net是可以安装网站(当做一个虚拟空间使用的) 但是在安装cms程序的时候那时的数据库地址再填写“localh ...
- python面试题包含基础和Linux操作以及数据库相关
今天面试了一家公司,感觉表现的不是很好,记录一下面试的试题. python基础部分 python 是一门什么样的语言面向对象的语言有那些,python的面向对象和Java面向对象的区别 Python是 ...
- Oracle 数据库应用开发 30 忌
原创 LaoYuanPython CSDN 今天 作者 | LaoYuanPython 责编 | 欧阳姝黎出品 | CSDN原力计划 引言 笔者及所在团队从 2000 年开始的 CRM 等 ...
- Android数据库相关整理
今天对Android中数据库相关的操作和代码做了一个整理,便于自己之后的查阅.主要内容有: 1.原生数据库写法 2.终端进sqlite的操作 3.第三方库 4.事务处理 5.权限和路径 一.原生数据库 ...
- php与数据库代码开发规范
php与数据库代码开发规范 1/25/2016 6:00:31 PM php对各类变量命名规范 目录名 文件命名 局部变量命名 使用英文动词名词,用下划线作为单词的分割,所有字母均使用小写 目录 up ...
随机推荐
- Linux中国开源社区停止运营
layout: post title: "Linux 中国开源社区停止运营" tags: - "Linux" 昨天看到老王发的公众号文章,Linux中国开源社区 ...
- 轻量级按键动作识别模块(C语言)
1.前言 继嵌入式(单片机)裸机 C 语言开发 + 按键扫描(模块分层/非阻塞式)文章后,原来的按键识别基本能满足大部分需求,但是对于双击和多击等多样化的功能需求并不能满足,因此对整个按键动作识别模块 ...
- 从零开始的react入门教程(九),react context上下文详解,可能有点啰嗦,但很想让你懂
壹 ❀ 引 我在从零开始的react入门教程(八),redux起源与基础用法一文中,介绍了redux的前辈Flux,以及redux关于单项数据更新的基本用法.我们在前文提到,相对Flux支持多个sto ...
- NC13885 Music Problem
题目链接 题目 题目描述 Listening to the music is relax, but for obsessive(强迫症), it may be unbearable. HH is an ...
- Maven多模块项目版本统一管理
如图所示,项目中定义了这样几个模块: pdd-workflow-build :定义项目版本,及全局配置 pdd-workflow-dependencies :外部依赖管理,统一管理所有用到的外部依赖的 ...
- Springboot thymeleaf实战总结
介绍 以下总结了使用Thymeleaf做项目过程中碰到的有价值的知识点.拿出来分享! 1.配置context-path 在公共模板中添加: <script type="text/jav ...
- oracle exp/imp命令使用parfile实现参数文件调用
优先使用数据泵(expdp/impdp)方式,更高效,问题少. 关于exp/imp工具的使用请参考我的另一篇文章: https://blog.csdn.net/IndexMan/article/det ...
- Modbus协议入门
1.Modbus协议是不是开源的,免费的? 标准.开放,用户可以免费.放心地使用Modbus协议,不需要交纳许可证费,也不会侵犯知识产权. 2.怎么传输,有线还是无线? 既可以有线传输如双绞线.光纤, ...
- Java常用编程类库
Java语言已经有许多非常成熟的开源基础类库,封装了日常开发中的各种常用操作,如:对象判空,字符串编码,本地缓存等等. 可以直接在项目中引入对应类库使用即可,或者参与完善相应类库的方法. 现将常用的基 ...
- Jenkins流水线使用@Grab 导入Maven库
有个需求需要在pipeline中调用Java的SDK去执行业务 使用 @Grab 注解可以在Maven中导入Java 库, @Grab('org.apache.commons:commons-math ...