【问题标题】:How to design entity structures using Google App Engine Datastore for this particular situation?如何针对这种特殊情况使用 Google App Engine Datastore 设计实体结构?
【发布时间】:2016-04-03 13:26:55
【问题描述】:

好的,这是我的需要。我想构建一个使用 Google App Engine Datastore 作为后端数据库的网络应用程序。

该应用程序允许用户免费注册一个帐户。当每个注册用户都可以有一个储蓄账户时,他们可以在他们的储蓄账户中存款或取款。

使用此链接中的信息https://cloud.google.com/appengine/docs/java/datastore/entities

我想出了这些代码

public class RegistrationServlet extends HttpServlet {

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String name = request.getParameter("name");
        String email = request.getParameter("email");
        String pass = request.getParameter("pass");

        DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();


        Entity user = new Entity("User");
        user.setProperty("name",name);
        user.setProperty("email",email);
        user.setProperty("pass",pass);


        datastore.put(user);
    }

    public void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws IOException {
        DatastoreService ds=DatastoreServiceFactory.getDatastoreService();

        String email = request.getParameter("email");
        String pass = request.getParameter("pass");
        double credit=request.getParameter("credit");
        double debit=request.getParameter("debit");

        int userKeyInt=0;
        Query q=new Query ("User");
        PreparedQuery pq=ds.prepare(q);
        for (Entity u1:pq.asIterable()){
           String emailStr=u1.getProperty("Email").toString();
           String userIDStr=u1.getProperty("UserID").toString();
           String passStr=u1.getProperty("Pass").toString();
           if(emailStr.equals(email) && passStr.equals(pass)) {
                 userKeyInt=Integer.parseInt(userIDStr);
           }
        }
        Key userKey=KeyFactory.createKey("User", userKeyInt);
        try{
           Entity user = ds.get(key);

           Entity savingAccount=new Entity ("SavingAccount");
           savingAccount.setProperty("UserID",  user.getKey());
           savingAccount.setProperty("Debit",debit);
           savingAccount.setProperty("Credit",credit);


         }

         catch (EntityNotFoundException e){
            e.printStackTrace();
         }


    }
}

因此,Savingaccount 的字段“UserID”起到外键的作用。

Entity user = new Entity("User");
Entity savingAccount=new Entity ("SavingAccount");
savingAccount.setProperty("UserID",  user.getKey());

但我不确定我所做的是否正确,因为无法检查外键约束,我们是否需要像此链接https://cloud.google.com/appengine/articles/modeling 中所述的建模实体关系

如果我确实需要建模实体关系,那该怎么做?

注意:每个用户可以有多个储蓄账户。

【问题讨论】:

  • NB1:调用getProperty 时不要调用toString() - 使用强制转换。否则,您将永远不会知道您是否犯了错误并在属性中存储了错误的数据类型。
  • NB2:循环遍历所有用户是非常低效的。使用查询查找具有正确电子邮件地址的用户。
  • NB3:为什么将 UserID 作为属性存储在 User 实体中?使用数据存储区自动生成的 ID。此外,ID 存储为 Long 值 - 使用整数可能会导致问题。
  • @AndreiVolgin,您说“循环遍历所有用户的效率非常低。使用查询来查找具有正确电子邮件的用户。”,那我该怎么办?好的,我们知道 email 是唯一的,那么如何在提供 email 时获取 user 对象呢?
  • @AndreiVolgin,另外,我不将 UserID 作为属性存储在 User 实体中,但我确实将 UserID 存储为 SavingAccount 实体的属性,因此它类似于关系数据库

标签: java entity-framework google-app-engine data-modeling google-cloud-datastore


【解决方案1】:

您可以使 SavingAccountEntity 成为 UserEntity 的子实体。当您决定更新事务中的实体以保持数据完整性时,它可能会变得有用。

使用这种方法,您可以通过对 SavingAccountEntity 的简单祖先查询来检索用户拥有的所有储蓄账户。

【讨论】:

  • 这样“Entity user = new Entity("User", "tom@gmail.com");"是否有效。我们直接使用电子邮件作为用户的 ID。如果我们这样做,那么它是否比我们使用“使用数据存储区自动生成的 ID”要慢
  • 36:25 的这段视频 (youtube.com/…) 中,我们可以看到这段代码 "Entity ikai=new Entity("User","ijai@ gmail.com")"。所以我认为使用电子邮件作为 UserID 是可以的
  • 还有,多对多关系呢,我们如何管理多对多关系?我看到了这个链接cloud.google.com/appengine/docs/java/datastore/jdo/…,但不确定它是正确的
  • 在我看来,使用电子邮件作为用户 ID 是一个坏主意,因为用户往往会随着时间的推移更改他们的电子邮件。它带来了很多挑战 - 更改 ID 将产生一个全新的密钥。
  • 也许不是电子邮件,但使用“用户名”而不是“电子邮件”呢?如果我们有多对多关系,如何设计数据存储结构。例如,每个承包商可以为多个公司工作,每个公司可以有多个承包商
猜你喜欢
  • 1970-01-01
  • 2011-05-18
  • 2018-02-11
  • 2016-04-02
  • 1970-01-01
  • 2013-08-11
  • 1970-01-01
  • 1970-01-01
  • 2015-07-25
相关资源
最近更新 更多