Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在GAE上检索/记录多个实体的最便宜方法_Java_Google App Engine_Jpa_Transactions_Google Cloud Datastore - Fatal编程技术网

Java 在GAE上检索/记录多个实体的最便宜方法

Java 在GAE上检索/记录多个实体的最便宜方法,java,google-app-engine,jpa,transactions,google-cloud-datastore,Java,Google App Engine,Jpa,Transactions,Google Cloud Datastore,我有一个具体的案例让我产生了一些疑问: 我的班级A与B有一对多的关系: A 1----->* B 据我所知,这使得它们的相关实例属于同一个实体组。 我必须检索一个特定的A实例和它的一个B实例,所以我搜索A并遍历它的B列表以找到特定的B(总是按Id搜索)。之后,我更改A和B的一个属性,并通过合并A提交我的更改。下面是我的问题: 知道我必须检索A和B(因为我必须修改这两个),我应该进行2次搜索而不是迭代B列表吗 进行2次搜索,如果我只保留A,对B的修改将被保留 在这种情况下,问题1和2的

我有一个具体的案例让我产生了一些疑问: 我的班级A与B有一对多的关系:

A  1----->*  B
据我所知,这使得它们的相关实例属于同一个实体组。 我必须检索一个特定的A实例和它的一个B实例,所以我搜索A并遍历它的B列表以找到特定的B(总是按Id搜索)。之后,我更改A和B的一个属性,并通过合并A提交我的更改。下面是我的问题:

  • 知道我必须检索A和B(因为我必须修改这两个),我应该进行2次搜索而不是迭代B列表吗
  • 进行2次搜索,如果我只保留A,对B的修改将被保留
  • 在这种情况下,问题1和2的答案是否相同:
  • 用一些代码补充问题:

    @Entity
    public class A
    {
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Key key;
    
        private int aField;
    
        @OneToMany(cascade={CascadeType.ALL})
        private List<B> bList;
    
        //...
    }
    
    @Entity
    public class B
    {
         @Id
         @GeneratedValue(strategy = GenerationType.IDENTITY)
         private Key key;
    
         private int someBField;
    
         // no way to get A from here...
    
         //...
    }
    
    public void someService1(Key aKey, Key bKey)
    {
         //...
    
         // Here, I'm sure that bKey is of an entity son of aKey entity (I trust the client)
         A a = entityManager.find(A.class, aKey);
         a.setAField(a.getAField()++);
    
         for(B b : a.getBList())
              if(b.getKey().equals(bKey))
                    b.setSomeBField(b.getSomeBField()++);
    
         entityManager.merge(a);
    
         //...
    }
    
    public void someService2(Key aKey, Key bKey)
    {
         //...
    
         // Here, I'm sure that bKey is of an entity son of aKey entity (I trust the client)
         A a = entityManager.find(A.class, aKey);
         a.setAField(a.getAField()++);
    
         B b = entityManager.find(B.class, bKey);
         b.setSomeBField(b.getSomeBField()++);
    
         entityManager.merge(a);
    
         //...
    }
    
    @实体
    公共A类
    {
    @身份证
    @GeneratedValue(策略=GenerationType.IDENTITY)
    私钥;
    私人外场;
    @OneToMany(cascade={CascadeType.ALL})
    私人名单;
    //...
    }
    @实体
    公共B级
    {
    @身份证
    @GeneratedValue(策略=GenerationType.IDENTITY)
    私钥;
    萨姆博菲尔德私人酒店;
    //没有办法从这里得到一个。。。
    //...
    }
    公共服务1(密钥aKey,密钥bKey)
    {
    //...
    //在这里,我确信bKey是aKey实体的子实体(我信任客户)
    A=entityManager.find(A.class,aKey);
    a、 setAField(a.getAField()++);
    对于(B:a.getBList())
    如果(b.getKey().equals(bKey))
    b、 setSomeBField(b.getSomeBField()++);
    entityManager.merge(a);
    //...
    }
    公共服务2(密钥aKey,密钥bKey)
    {
    //...
    //在这里,我确信bKey是aKey实体的子实体(我信任客户)
    A=entityManager.find(A.class,aKey);
    a、 setAField(a.getAField()++);
    B=实体管理器查找(B.class,bKey);
    b、 setSomeBField(b.getSomeBField()++);
    entityManager.merge(a);
    //...
    }
    

    好吧,如果我做的每件事都是对的,那么someService1和someService2都会做同样的事情。哪一个更好?

    如果我理解正确,您不必重复任何内容,而是在您喜欢的任何
    查询中使用。示例(Python):


    如果您正在使用Java,您将在查询中使用()。

    如果您知道id(并且您说您正在按id搜索),那么只需对A执行
    em.find
    ,对B执行
    em.find
    。两次调用。遗憾的是,JPAAPI没有
    em.findAll
    。另一方面,JDO确实有
    pm.getObjectsById

    对不起,我忘了说我使用Java和JPA。我不明白,过滤器的使用如何转化为搜索或数据存储读取的数量?我如何使用它检索实体和祖先?请注意,我正在使用ID查找这两个实例。@Roberto我现在必须走了。。但一般来说,如果在数据存储中使用关系,则必须熟悉可应用于查询的过滤器。。我建议您浏览一下概述(最后一个链接)并熟悉它。如果有一些示例代码开始,它将非常有用。这个问题太抽象了,很难回答。例如,您说一对多关系意味着它们都在同一个实体组中,但这不是建模此类关系的唯一方法。如果是这样建模的,您可以使用祖先查询在Bs上迭代——为什么要使用Bs的ID?等等。如果您展示了您实际拥有的代码并提出了一些有针对性的问题,那么所有这些猜测都是不必要的。@GuidovanRossum好的,我编辑了我的问题。我需要一个特定的B,所以我迭代并使用id来查找它。问题其实很简单(但很难表达):迭代一个列表,我已经找到了一个元素,但是,忘记这个列表,直接搜索这个元素,因为我有id,这两者之间有什么区别(在成本方面)。谢谢。你这么说是因为它比迭代B列表便宜,对吧?想想数据存储访问。。。获取A,然后获取B实体的列表。。。或者得到A,得到B。可能两个数据存储都访问(看看日志,它告诉你(谷歌插件的最新版本)),但后者检索的信息(带宽)更少。我认为在迭代列表时(列表中的每个元素搜索一次)会花费更多的读取操作。这取决于GAE如何管理它。。。这是一个电话。。。而是对许多实体对象的调用。我的建议是,只需要一个实体,所以永远不会花费更多
    @Entity
    public class A
    {
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Key key;
    
        private int aField;
    
        @OneToMany(cascade={CascadeType.ALL})
        private List<B> bList;
    
        //...
    }
    
    @Entity
    public class B
    {
         @Id
         @GeneratedValue(strategy = GenerationType.IDENTITY)
         private Key key;
    
         private int someBField;
    
         // no way to get A from here...
    
         //...
    }
    
    public void someService1(Key aKey, Key bKey)
    {
         //...
    
         // Here, I'm sure that bKey is of an entity son of aKey entity (I trust the client)
         A a = entityManager.find(A.class, aKey);
         a.setAField(a.getAField()++);
    
         for(B b : a.getBList())
              if(b.getKey().equals(bKey))
                    b.setSomeBField(b.getSomeBField()++);
    
         entityManager.merge(a);
    
         //...
    }
    
    public void someService2(Key aKey, Key bKey)
    {
         //...
    
         // Here, I'm sure that bKey is of an entity son of aKey entity (I trust the client)
         A a = entityManager.find(A.class, aKey);
         a.setAField(a.getAField()++);
    
         B b = entityManager.find(B.class, bKey);
         b.setSomeBField(b.getSomeBField()++);
    
         entityManager.merge(a);
    
         //...
    }
    
    query.filter('height >', 42).filter('city = ', 'Seattle')
    
    query.filter('user = ', users.get_current_user())