Grails面试试题:GORM / 数据库篇

Tomás Lin在其博客中公布了一套面试Grails开发人员的题目,本站将陆续公布问题的答案。今天公布的是GORM / 数据库 部分的试题回答。

GORM / 数据库

  • 请解释一下dbCreate参数的不同值的区别?
  • 可用值有create-drop、create、update和validate:

    • create:启动时重新建表;
    • create-drop:启动时重新建表,停止时,drop所有表;
    • update:启动时更新当前的schema,相当于alter table。
    • validate:检查当前的Schema是否跟Domain匹配,不会对数据库做任何修改。
    • null:什么也不干
  • 什么是动态查找器?
  • 动态查找器是根据Domain Class属性生成的查找方法,这些方法由前缀为findBy和findAllBy的构成,构造规则(以findBy为例):DomainClass.findBy([Property][Comparator] [Boolean Operator])?[Property][Comparator]。详情可参见本站Grails 1.2参考文档速读(8):GORM中的查询

  • 动态查找器最多有几个参数?
  • 3,其中2个是属性,另一个是操作符。比如:

    Book.findBy([Property][Comparator][Boolean Operator])
  • 衣柜里有许多鞋。我想保持衣柜对象中鞋子的插入顺序。该怎么办?
  • 将鞋子属性设置成List,比如:

    class Closet  {
       List shoes
       static hasMany = [shoes:Shoe]
    }
    
  • 请解释一下GORM的joinTable。
  • joinTable,顾名思义,指的是“关联表”,如多对多中用来保存关系的“中间表”。但是关联表不是多对多的专利,在一对多时,若只有hasMany,而没有belongsTo,同样也会GORM创建关联表。因为此时表示,多端不一定有一端对应的类,即多端的一端可能为null。这句话有点绕口不是吗?简单点,就是外键可能为null。这对于关系数据库来讲可不是一个好的实践。所以对于只有hasMany的Domain Class来讲,在它们之间创建关联表最合适。可视为退化的“多对多”。

    关于关系的详情,请参见Grails 1.2参考文档速读(6):GORM基础和关系建模。这部分内容可是本站独家,参考文档上是没有的哦!

  • 请解释一下GORM的lock(),什么情况下会使用它?
  • 想获得悲观锁时,详情请参见Grails 1.2参考文档速读(7):GORM建模的其余事项及持久化基础

  • GORM中read()和get()的区别是什么?
  • 都是根据指定ID获得Domain Class。但read的目的是读出来的对象用于只读,而get则没有这个限制。 

  • Domain对象中的removeFrom()是什么意思?
  • 跟addTo方法相对,在多端的关联中移除实例。

  • 什么是命名查询?在哪里定义它们?
  • 即可重用的Criteria,使用namedQueries定义。

  • 动态查找器、HQL和Criteria的不同点是什么?
  • 动态查找器是根据Domain Class的属性生成的查找方法,诸如findBy**、findAllBy**。最多应用于2个属性;返回结果集是以Domain Class为单位的,无法返回任意结果集,如只包含部分Domain Class的属性的结果集;无法用于任意类之间的关联,关联的类之间需存在关系。

    HQL,类似SQL,通过executeQuery使用。可以返回任意的结果集,可以实现任意类之间的关联。

    Criteria,即Hibernate的Criteria在GORM中的DSL,通过createCriteria或withCriteria方法使用。无属性个数限制,可以实现复杂的关系操作。

  • Grails中的projection什么意思?
  • 即关系代数中的投影概念,可用于自定义返回的结果,如select中指定返回的列,就是一种投影操作。在HQL和Criteria中均可使用。

  • Grails中如何直接运行SQL?
  • new Sql(dataSource).execute sqlstr
  • Gorm提供了两个自动时间戳的变量,是什么?
  • lastUpdated和dateCreated

  • 解释一下GORM的事件,并举2例。
  • 可视为GORM的触发器,其作用跟数据库的触发器类似,通过在Domain Class中定义闭包实现,在Domain对象保存之前或之后执行。例如:beforeInsert、afterUpdate。

  • Domain Class中有一个属性,不想持久化。如何保证这个属性不会在数据库中生成一个字段?
  • 在Domain Class中使用“transients”,例如:

    class User {   
       String address
       ......
       static transients = ['address']
    }
    
  • 我想在Grails应用中包含一个Hbernate的HBM文件,该怎么做?
  • 在grails-app/conf/hibernate目录下,创建hibernate.cfg.xml,并把HBM文件也防置在这个目录下。

  • 如何查看Grails的内置HSQL数据库?
  • 可以将代码:

    org.hsqldb.util.DatabaseManager.main()
    

    在应用内的任何地方或者Grails Console中,运行上述代码会启动HSQLDB的Console连接界面。在这个界面中,将URL属性值jdbc:hsqldb:mem:* 中的“*”更换成devDB或者你自己定义的数据库名,如“jdbc:hsqldb:mem:devDB”,之后单击OK,就能够看到该数据库中的表结构了。

    或者直接使用:

    org.hsqldb.util.DatabaseManagerSwing.main( ['--url', 'jdbc:hsqldb:mem:devDB'] as String[] )
    
  • Grails如何使用多个数据库?
  • 使用Datasources插件

  • 如何根据数据库生成Domain Classe?
  • 可以使用Grails逆向工程插件实现,具体使用可参见本站《使用Grails进行数据库逆向工程》

    或者使用GRAG

关于Hibernate的内容不可不读,尤其是《Java Persistence with Hibernate》这本书。

By huwh - Posted on 03 二月 2011