Grails里DOMAIN类的一对一,一对多,多对多关系总结及集成测试
终于干完这一章节,收获很多啊。
和DJANGO有类似,也有不同。
User.groovy:
package com.grailsinaction class User { String loginId String password Date dateCreated static hasOne = [profile: Profile] static hasMany = [posts: Post, tags: Tag, following: User] static mapping = {posts sort: 'dateCreated'} static constraints = { loginId size: 3..20, unique: true, nullable: false password size: 6..8, nullable:false, validator: { passwd, user -> passwd != user.loginId } profile nullable: true } }
Profile.groovy:
package com.grailsinaction class Profile { User user byte[] photo String fullName String bio String homepage String email String timezone String country String jabberAddress static constraints = { fullName blank: false bio nullable: true, maxSize: 1000 homepage url:true, nullable: true email email: true, blank: false photo nullable:true, maxSize: 2 * 1024 * 1024 country nullable: true timezone nullable: true jabberAddress email: true, nullable: true } }
Post.groovy:
package com.grailsinaction class Post { String content Date dateCreated static constraints = { content blank: false } static belongsTo = [user: User] static hasMany = [tags: Tag] static mapping = { sort dateCreated: "desc"} }
Tag.groovy:
package com.grailsinaction class Tag { String name User user static constraints = { name blank: false } static hasMany = [posts: Post] static belongsTo = [User, Post] }
UserIntegrationSpec.groovy:
package com.grailsinaction import grails.test.mixin.integration.Integration import grails.transaction.* import spock.lang.* @Integration @Rollback class UserIntegrationSpec extends Specification { def setup() { } def cleanup() { } def "Saving our first user to the database"() { given: "A brand new user" def joe = new User(loginId: 'Joe', password: 'secret') when: "the user is saved" joe.save() then: "it saved successfully and can be found in the database" joe.errors.errorCount == 0 joe.id != null User.get(joe.id).loginId == joe.loginId } def "Updating a saved user changes its properties"() { given: "An existing user" def existingUser = new User(loginId: 'Joe', password: 'secret') existingUser.save(failOnError: true) when: "A property is changed" def foundUser = User.get(existingUser.id) foundUser.password = 'sesame' foundUser.save(failOnError: true) then: "The change is reflected in the database" User.get(existingUser.id).password == 'sesame' } def "Deleting an existing user removes it from the database"() { given: "An existing user" def user = new User(loginId: 'Joe', password: 'secret') user.save(failOnError: true) when: "The user is deleted" def foundUser = User.get(user.id) foundUser.delete(flush: true) then: "The user is removed from the database" !User.exists(foundUser.id) } def "Saving a user with invalid properties causes an error"() { given: "A user which fails several field validations" def user = new User(loginId: 'Joe', password: 'tiny') when: "The user is validated" user.validate() then: user.hasErrors() "size.toosmall" == user.errors.getFieldError("password").code "tiny" == user.errors.getFieldError("password").rejectedValue !user.errors.getFieldError("loginId") } def "Recovering from a failed save by fixing invalid properties"() { given: "A user that has invalid properties" def chuck = new User(loginId: 'chuck', password: 'tiny') assert chuck.save() == null assert chuck.hasErrors() when: "We fix the invalid properties" chuck.password = "fistfist" chuck.validate() then: "The user saves and validates fine" !chuck.hasErrors() chuck.save() } def "Ensure a user can follow other users"() { given: "A set of baseline users" def joe = new User(loginId: 'joe', password: 'password').save() def jane = new User(loginId: 'jane', password: 'password').save() def jill = new User(loginId: 'jill', password: 'password').save() when: "Joe follows Jan & Jill, and Jill follows Jane" joe.addToFollowing(jane) joe.addToFollowing(jill) jill.addToFollowing(jane) then: "Follower counts should match follow people" 2 == joe.following.size() 1 == jill.following.size() } }
PostIntegrationSpec.groovy:
package com.grailsinaction import grails.test.mixin.integration.Integration import grails.transaction.* import spock.lang.* @Integration @Rollback class PostIntegrationSpec extends Specification { def setup() { } def cleanup() { } def "Adding posts to user links post to user"() { given: "A brand new user" def user = new User(loginId: 'joe', password: 'secret') user.save(failOnError: true) when: "Several posts are added to the user" user.addToPosts(new Post(content: "First post.....w002!")) user.addToPosts(new Post(content: "Second post......")) user.addToPosts(new Post(content: "Third post....")) then: "The user has a list of posts attached" 3 == User.get(user.id).posts.size() } def "Ensure posts linked to a user can be retrieved"() { given: "A user with several posts" def user = new User(loginId: 'joe', password: 'secret') user.addToPosts(new Post(content: "First")) user.addToPosts(new Post(content: "Second")) user.addToPosts(new Post(content: "Third")) user.save(failOnError: true) when: "The user is retrieved by their id" def foundUser = User.get(user.id) def sortedPostContent = foundUser.posts.collect { it.content }.sort() then: "The posts appear on the retrieved user " sortedPostContent == ['First', 'Second', 'Third'] } def "Exercise tagging several post with various tags"() { given: "A user with a set of tags" def user = new User(loginId: 'joe', password: 'secret') def tagGroovy = new Tag(name:"groovy") def tagGrails = new Tag(name:"grails") user.addToTags(tagGroovy) user.addToTags(tagGrails) user.save(failOnError: true) when:"The user tags two fresh posts" def groovyPost = new Post(content: "A groovy post") user.addToPosts(groovyPost) groovyPost.addToTags(tagGroovy) def bothPost = new Post(content: "A groovy and grails post") user.addToPosts(bothPost) bothPost.addToTags(tagGroovy) bothPost.addToTags(tagGrails) then: user.tags*.name.sort() == ['grails', 'groovy'] 1 == groovyPost.tags.size() 2 == bothPost.tags.size() } }
Grails里DOMAIN类的一对一,一对多,多对多关系总结及集成测试的更多相关文章
- SQLAlchemy_定义(一对一/一对多/多对多)关系
目录 Basic Relationship Patterns One To Many One To One Many To Many Basic Relationship Patterns 基本关系模 ...
- JPA级联(一对一 一对多 多对多)注解【实际项目中摘取的】并非自己实际应用
下面把项目中的用户类中有个:一对一 一对多 多对多的注解对应关系列取出来用于学习 说明:项目运行正常 问题类:一对多.一对一.多对多 ============一对多 一方的设置 @One ...
- Python进阶----表与表之间的关系(一对一,一对多,多对多),增删改查操作
Python进阶----表与表之间的关系(一对一,一对多,多对多),增删改查操作,单表查询,多表查询 一丶表与表之间的关系 背景: 由于如果只使用一张表存储所有的数据,就会操作数 ...
- mybatis 一对一 一对多 多对多
一对一 一对多 多对多
- SSAS中事实表中的数据如果因为一对多或多对多关系复制了多份,在维度上聚合的时候还是只算一份
SSAS事实表中的数据,有时候会因为一对多或多对多关系发生复制变成多份,如下图所示: 图1 我们可以从上面图片中看到,在这个例子中,有三个事实表Fact_People_Money(此表用字段Money ...
- JPA实体关系映射:@ManyToMany多对多关系、@OneToMany@ManyToOne一对多多对一关系和@OneToOne的深度实例解析
JPA实体关系映射:@ManyToMany多对多关系.@OneToMany@ManyToOne一对多多对一关系和@OneToOne的深度实例解析 今天程序中遇到的错误一 org.hibernate.A ...
- day 69-70 一对一 一对多 多对一联表查询
day 69 orm操作之表关系,多对多,多对一 多对一/一对多, 多对多{类中的定义方法} day69 1. 昨日内容回顾 1. 单表增删改查 2. 单表查询API 返回QuerySet对象的: 1 ...
- 使用NHibernate(7)-- 一对一 && 一对多 && 多对多
1, 一对一. 对于数据量比较大的时候,考虑查询的性能,肯能会把一个对象的属性分到两个表中存放:比如用户和用户资料,经常使用的一般是Id和用户名,用户资料(学校,籍贯等)是不经常被查询的,所以就会分成 ...
- JPA 一对一 一对多 多对一 多对多配置
1 JPA概述 1.1 JPA是什么 JPA (Java Persistence API) Java持久化API.是一套Sun公司 Java官方制定的ORM 方案,是规范,是标准 ,sun公司自己并没 ...
随机推荐
- 一款使用C# .NET开发的SIP网络电话客户端完整源码
一款使用C# .NET开发的SIP客户端开源项目.测试可编译通过运行,特此分享一下.可以对接ASTGO.VOS2009.VOS3000.NTS.UCS等各种SIP协议的软交换! 下载地址:https: ...
- PCB 自动发送邮件---加入表格实现方法
先看一下手动发送邮件内容加入表格操作(下图所示),直接复制Excel内容,再粘贴到邮件内容中,就是这么便捷,如果我们想自动发送邮件,也实现同样的效果如果实现呢,在这里介绍2种方法: 一.读取Excel ...
- Linex系统 配置php服务器
此文是可以参考 楼主也不是系统管理员只是迫不得已所以自己才找的 大家可以参考 .... ..... 安装apache 安装mysql 安装PHP 测试服务器 php -v 查询php的版本 就这些了 ...
- C# 清除coockies
if (Request.Cookies["zxcookies"] != null) { HttpCookie mycookie; ...
- Web程序安全机制
ASP.NET提供了一个多层的安全模型,这个模型能够非常容易的保护Web应用程序. 安全策略没有必要非常复杂,但是需要应用安全策略的地方却是非常广泛的.程序员需要保证自己的应用程序不能被骗取,而把私有 ...
- Spring Boot (25) RabbitMQ消息队列
MQ全程(Message Queue)又名消息队列,是一种异步通讯的中间件.可以理解为邮局,发送者将消息投递到邮局,然后邮局帮我们发送给具体的接收者,具体发送过程和时间与我们无关,常见的MQ又kafk ...
- 【转】Java 集合系列01之 总体框架
Java集合是java提供的工具包,包含了常用的数据结构:集合.链表.队列.栈.数组.映射等.Java集合工具包位置是java.util.*Java集合主要可以划分为4个部分:List列表.Set集合 ...
- HTML+CSS(12)
n CSS浮动和清除 Float:让元素浮动,取值:left(左浮动).right(右浮动). Clear:清除浮动,取值:left(清除左浮动).right(清除右浮动).both(同时清除上面的 ...
- 前端-Node.js思维导图笔记
看不清的朋友右键保存或者新窗口打开哦!喜欢我可以关注我,还有更多前端思维导图笔记
- JS高级——arguments
arguments 1.函数内部的一个对象,在函数调用的时候,默认的会将所有传入的实参依次存入该对象 2.是一个伪数组 3.arguments.length 可以用来表示传入实参的个数 4.argum ...