【问题标题】:Grails domain object storing Map<K,V>Grails 域对象存储 Map<K,V>
【发布时间】:2017-01-05 16:39:12
【问题描述】:

我从 Grails/GORM 文档中知道,如果您希望存储对象 Map,键和值都需要是字符串:Map&lt;String,String&gt;

我想使用另一个域对象 (Animal) 作为此映射中的键,但由于上述限制,这是不可能的。 Animal 的标识符可以很容易地转换为字符串类型,但如果我这样做,我不相信 GORM 会足够聪明地在检索父对象时执行映射。

有人遇到过这种情况吗?

【问题讨论】:

    标签: grails grails-orm


    【解决方案1】:

    我认为这应该可行:

    假设您有一个包含地图的域类:

    class Test {
       String name
       Map myAnimals=[:]
    
      //When given a specific key it will return actual animal object
      def findAnimal(String myKey) {
        return myAnimals.find{it.key==myKey}?.value
        //What above is doing can be seen broken down here:
        //def ani = myAnimals.find{it.key==myKey}
        //println "ANI::: ${ani} ${ani.value}"
        //def animal = ani?.value
        //return animal
    
      }
    }
    

    保存到地图时在服务中

    class TestService {
        def save(values) {
        Test test1 = new Test()
        test1.name='something'
        // so to add 3 of animal objects above values would be
        def animal1=Animal.find()
        String key1='ANI'  //For animals 
        def animal2=Monkey.find()  // where Monkey extends Animal (hence the keys)
        String key2='MON'  //For monkeys only
        test1.myAnimals[key1]=animal1
        test1.myAnimals[key2]=animal2
        test1.save()
    
          /**
          * When you have a real values map that contains useful method you can
          * do it this way - left commented out FYI on manual process above
          Test test = new Test()
          // you now have some map of values coming in that contains a key 
          // and actual object so you could make this up if you are testing
         values.animals?.each{k,v->
                    test.myAnimals[k]=v
                }
        }    
        test.save()
        */        
     }
    

    所以第一个示例 values.each 是您构建自己的地图的地方,其中包含一个键和正在保存的实际域对象。

    第二个 test1 示例是我手动完成的,没有自动值作为测试传入,可能是最好的起点。

    然后当你有测试对象来获得实际的动物(如你所见仅限于)键时,一只动物一只猴子一只鸟等

    当你有

    Test test = Test.findByName('something)
    def animal = test.findAnimal('ANI')
    def monkey = test.findAnimal('MON')
    println "animal is ${animal} ${animal.getClass()} monkey is ${monkey} ${monkey.getClass()}"
    

    现在将查找域类方法并尝试根据调用返回动物对象

    在启动它之前,我需要添加 1 只动物和 1 只猴子,因为它会在上面找到或执行查找或第一个对象。所以在我的引导中:

    import test.Animal
    import test.Monkey
    
    class BootStrap {
    
        def init = { servletContext ->
    
            Animal animal = new Animal()
            animal.name='Daffy Duck'
            animal.save(flush:true)
            Monkey monkey = new Monkey()
            monkey.name='King Kong'
            monkey.save(flush:true)
        }
        def destroy = {
        }
    }
    

    当我运行它时,我会从 println

    animal is class test.Animal class java.lang.Class monkey is class test.Monkey class java.lang.Class
    

    还有一些类到字符串错误,不确定是哪位导致它 - 输出中的 println 看起来像你想要的那样。

    您可能必须选择不同的方法来保存键并使用 Animal 作为主类来查询,以便键的一些其他代码然后您可以将 findByAnimal 更改为始终返回 Animal 对象:

    //When given a specific key it will return actual animal object
        Animal findAnimal(String myKey) {
          Animal animal = myAnimals.find{it.key==myKey}?.value
          return animal
        }
    

    更高的调用发生了变化,因为它是 AnimalMonkey 扩展了 Animal。上面示例中缺少两个类:

    package test
    
    class Animal {
        String name
    
    }
    package test
    
    class Monkey extends Animal {
    
    
    }
    

    【讨论】:

      猜你喜欢
      • 2022-01-23
      • 2019-10-10
      • 2011-04-21
      • 2022-11-30
      • 2019-07-30
      • 2019-01-23
      • 1970-01-01
      • 2012-12-01
      • 2018-11-23
      相关资源
      最近更新 更多