嵌套查询和加入表

嵌套查询和加入表

本文介绍了parse.com - 嵌套查询和加入表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有嵌套查询问题。在 query5.whereEqualTo(piwo,followList2.get(0))我想要得到的对象,但followList2需要被声明为final它吐出错误,但是当它所有的匿名类红得与无法解析的构造函数(...)错误。之前,任何人得到这个?

  ParseQuery<&的parseObject GT; QUERY3 = ParseQuery.getQuery(Piwo);
                    query3.whereEqualTo(马卡,啤酒); // TODO如果(啤酒==ALL)那么就不要使用它
                    query3.findInBackground(新FindCallback<&的parseObject GT;(){
                        公共无效完成(列表<&的parseObject GT; followList2,ParseException的E){                            如果(followList2!= NULL){
                                Log.d(ASD,Szukane piwo:+ followList2.get(0).getString(马尔卡));
                            }其他{
                                Log.d(ASD,零wyników1);
                            }                            ParseQueryAdapter<&的parseObject GT;适配器=
                                    新ParseQueryAdapter<&的parseObject GT;(这一点,新ParseQueryAdapter.QueryFactory<&的parseObject GT;(){
                                        公共ParseQuery<&的parseObject GT;创建() {
                                            //这里我们可以配置一个ParseQuery我们的心脏的欲望。
                                            ParseQuery QUERY5 =新ParseQuery(以上的价格);
                                            query5.whereContainedIn(LOKAL清单);
                                            query5.whereEqualTo(piwo,followList2.get(0);
                                            query5.include(piwo);
                                            query5.include(LOKAL);
                                            query5.orderByAscending(价格从);
                                            返回QUERY5;
                                        }
                                    });
                            adapter.setTextKey(lokal.place);
                            adapter.setImageKey(照片);                            ListView控件的ListView =(ListView控件)findViewById(R.id.listview);
                            listView.setAdapter(适配器);


解决方案

如果我理解正确的话,你已经尝试过:

  ...
公共无效完成(最终名单<&的parseObject GT; followList2,ParseException的E){
...

由于某种原因使编译器不开心。

我想可能有两个可能的解决方案。


  1. 如果您计划使用followList2在活动/片段别处对象。然后,只需声明一个字段变量保存结果,并从阅读代替。通过这种方式,匿名内部类应该可以访问它。

  2. 写followList2到被声明为final另一个局部变量。这种方式,我们不会改变()完成回调的签名。

解决方案1:

 列表<&的parseObject GT; mFollowList2; //字段变量的方法外
...
公共无效完成(列表<&的parseObject GT; followList2,ParseException的E){
    mFollowList2 = followList2;
    //在code的其余部分使用mFollowList2
...

解决方案2:

 公共无效完成(列表<&的parseObject GT; followList2,ParseException的E){
    最终名单<&的parseObject GT; finalFollowList2 = followList2;
    //在code的其余部分使用finalFollowList2
...

由于在评论中说,我不记得有过同样的问题,但我希望这解决了该问题。

第三个建议是尝试螺栓(自带解析API)。如果您熟悉javascript中的承诺,螺栓基本上是Java的是一样的。它消除了嵌套调用的需求,使得code的金字塔形的块为根据查询的增长量。然而,它确实需要一些时间来适应,并在简单的情况下,它是没有必要的。

奖励:

由于您在使用文本麻烦您包括您的适配器,我会告诉你我的一些code为例。

首先,我有一个项目一个简单的布局:
RES /布局/ view_adapter_item_simple.xml

 <的RelativeLayout的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    机器人:layout_width =match_parent
    机器人:layout_height =WRAP_CONTENT
    机器人:layout_margin =5DP
    机器人:背景=机器人:ATTR / activatedBackgroundIndicator
    机器人:paddingTop =5DP>    <的TextView
        机器人:ID =@ + ID /文
        机器人:layout_width =WRAP_CONTENT
        机器人:layout_height =WRAP_CONTENT
        机器人:layout_alignParentLeft =真
        机器人:文字=项/>
< / RelativeLayout的>

接下来,这里是我的自定义适配器:

 公共类SimpleParseAdapter<吨延伸的parseObject>扩展
        ParseQueryAdapter< T> {    私有静态最后弦乐TAG = SimpleParseAdapter.class.getSimpleName();    私人最终字符串textCol;    公共SimpleParseAdapter(上下文的背景下,字符串textCol,
            QueryFactory< T> queryFactory){
        超(背景下,queryFactory);
        this.textCol = textCol;
    }    TextView的文本;    @覆盖
    公共查看getItemView(T对象,视图V的ViewGroup以及母公司){        如果(V == NULL){
            V = View.inflate(的getContext(),R.layout.view_adapter_item_simple,
                    空值);
        }        super.getItemView(对象,V,父母);        文字=(TextView的)v.findViewById(R.id.text);        text.setText(object.getString(textCol));        返回伏;    }
}

注意:我们仍然还没有应用。这种工作原理类似于标准ParseQueryAdapter因为它仅着眼于用当前类的栏目 text.setText(object.getString(textCol))

然而,人们可以很容易写出专用适配器以处理嵌套包括,例如:

 公共类SimpleParseIncludeAdapter<吨延伸的parseObject>扩展
        ParseQueryAdapter< T> {    私有静态最后弦乐TAG = SimpleParseIncludeAdapter.class.getSimpleName();    私人最终字符串includeCol;
    私人最终字符串textCol;    公共SimpleParseIncludeAdapter(上下文的背景下,字符串includeCol,字符串textCol,
            QueryFactory< T> queryFactory){
        超(背景下,queryFactory);
        this.includeCol = includeCol;
        this.textCol = textCol;
    }    TextView的文本;    @覆盖
    公共查看getItemView(T对象,视图V的ViewGroup以及母公司){        如果(V == NULL){
            V = View.inflate(的getContext(),R.layout.view_adapter_item_simple,
                    空值);
        }        super.getItemView(对象,V,父母);        文字=(TextView的)v.findViewById(R.id.text);        text.setText(object.getParseObject(includeCol).getString(textCol));        返回伏;    }
}

现在使用的适配器是这样的:

 新SimpleParseIncludeAdapter(** **背景下,LOKAL,地点,** ** queryFactory);

凡queryFactory有义务做 query.include(LOKAL)(包括整个LOKAL指针),或`query.include(LOKAL。地方)(仅包括LOKAL')的地点栏;

额外的奖励 - 子类化

最后要注意,它看起来并不像你使用的是子类化,但是如果你做到了,你也可以有以上的价格子类专门定制的适配器。

 公共类CenaParseAdapter扩展
        ParseQueryAdapter<&以上的价格GT; {    私有静态最后弦乐TAG = CenaParseAdapter.class.getSimpleName();    公共CenaParseAdapter(上下文的背景下,
            QueryFactory<&以上的价格GT; queryFactory){
        超(背景下,queryFactory);    }    TextView的文本;    @覆盖
    公共查看getItemView(以上的价格以上的价格,视图V的ViewGroup以及母公司){        如果(V == NULL){
            V = View.inflate(的getContext(),R.layout.view_adapter_item_simple,
                    空值);
        }        super.getItemView(对象,V,父母);        文字=(TextView的)v.findViewById(R.id.text);        text.setText(cena.getPlace());        返回伏;    }
}

在这种情况下, cena.getPlace()可查找包含LOKAL:

  //以上的价格sublass内公共LOKAL getLokal(){//假设LOKAL也是子类
    回报(LOKAL)getParseObject(LOKAL);
}公共字符串getPlace(){
    返回(getLokal()!= NULL)? 。getLokal()getPlace():;
}// LOKAL子类中,公共字符串getPlace(){
    返回的getString(地点);
}

I have problem with nested query. In query5.whereEqualTo("piwo", followList2.get(0)) I want to get the object, but it spits error that followList2 needs to be declared final, but when it does all the anonymous class gets in red with Cannot resolve constructor(...) error. Anyone got this before?

ParseQuery<ParseObject> query3 = ParseQuery.getQuery("Piwo");
                    query3.whereEqualTo("marka", beer); // TODO if(beer == "all") then don't use it
                    query3.findInBackground(new FindCallback<ParseObject>() {
                        public void done(List<ParseObject> followList2, ParseException e) {

                            if (followList2 != null) {
                                Log.d("ASD", "Szukane piwo: " + followList2.get(0).getString("marka"));
                            } else {
                                Log.d("ASD", "Zero wyników1");
                            }

                            ParseQueryAdapter<ParseObject> adapter =
                                    new ParseQueryAdapter<ParseObject>(this, new ParseQueryAdapter.QueryFactory<ParseObject>() {
                                        public ParseQuery<ParseObject> create() {
                                            // Here we can configure a ParseQuery to our heart's desire.
                                            ParseQuery query5 = new ParseQuery("Cena");
                                            query5.whereContainedIn("lokal", list);
                                            query5.whereEqualTo("piwo", followList2.get(0);
                                            query5.include("piwo");
                                            query5.include("lokal");
                                            query5.orderByAscending("cena");
                                            return query5;
                                        }
                                    });
                            adapter.setTextKey("lokal.place");
                            adapter.setImageKey("photo");

                            ListView listView = (ListView) findViewById(R.id.listview);
                            listView.setAdapter(adapter);
解决方案

If I understand you correctly, you already tried:

...
public void done(final List<ParseObject> followList2, ParseException e) {
...

Which for some reason makes the compiler unhappy.

I think there might be two possible solutions

  1. If you plan to use the followList2 objects elsewhere in your Activity/Fragment. Then simply declare a field variable to hold the result and read from that instead. This way the anonymous inner class should have access to it.
  2. Write followList2 to another local variable that is declared final. This way we are not altering the signature of the done() callback.

Solution 1:

List<ParseObject> mFollowList2; // field variable outside method
...
public void done(List<ParseObject> followList2, ParseException e) {
    mFollowList2 = followList2;
    // use mFollowList2 in rest of code
...

Solution 2:

public void done(List<ParseObject> followList2, ParseException e) {
    final List<ParseObject> finalFollowList2 = followList2;
    // use finalFollowList2 in rest of code
...

As said in the comments, I cannot recall having had the same problem but I hope this addresses the issue.

A third suggestion would be to try out Bolts https://github.com/BoltsFramework/Bolts-Android (comes with the parse API). In case you are familiar with promises in javascript, Bolts is essentially the same for Java. It removes the need for nesting calls, making a pyramid shaped chunk of code as the amount of depending queries grows. However, it does take some time to get used to, and in the simple cases it is not necessary.

Bonus:

As you have trouble using the text from your include in your adapter, I will show you some of my code as an example.

First, I have a simple layout for an item:res/layout/view_adapter_item_simple.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="5dp"
    android:background="?android:attr/activatedBackgroundIndicator"
    android:paddingTop="5dp">

    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:text="item" />


</RelativeLayout>

Next, here is my custom adapter:

public class SimpleParseAdapter<T extends ParseObject> extends
        ParseQueryAdapter<T> {

    private static final String TAG = SimpleParseAdapter.class.getSimpleName();

    private final String textCol;

    public SimpleParseAdapter(Context context, String textCol,
            QueryFactory<T> queryFactory) {
        super(context, queryFactory);
        this.textCol = textCol;
    }

    TextView text;

    @Override
    public View getItemView(T object, View v, ViewGroup parent) {

        if (v == null) {
            v = View.inflate(getContext(), R.layout.view_adapter_item_simple,
                    null);
        }

        super.getItemView(object, v, parent);

        text = (TextView) v.findViewById(R.id.text);

        text.setText(object.getString(textCol));

        return v;

    }


}

NOTICE: We are still not quite there yet. This works similar to the standard ParseQueryAdapter in that it only looks at the columns of the current class using text.setText(object.getString(textCol)).

However, one could fairly easy write a special purpose adapter to handle the nested include, for example:

public class SimpleParseIncludeAdapter<T extends ParseObject> extends
        ParseQueryAdapter<T> {

    private static final String TAG = SimpleParseIncludeAdapter.class.getSimpleName();

    private final String includeCol;
    private final String textCol;

    public SimpleParseIncludeAdapter(Context context, String includeCol, String textCol,
            QueryFactory<T> queryFactory) {
        super(context, queryFactory);
        this.includeCol = includeCol;
        this.textCol = textCol;
    }

    TextView text;

    @Override
    public View getItemView(T object, View v, ViewGroup parent) {

        if (v == null) {
            v = View.inflate(getContext(), R.layout.view_adapter_item_simple,
                    null);
        }

        super.getItemView(object, v, parent);

        text = (TextView) v.findViewById(R.id.text);

        text.setText(object.getParseObject(includeCol).getString(textCol));

        return v;

    }


}

Now using the adapter like this:

new SimpleParseIncludeAdapter(**context**, "lokal", "place",**queryFactory**);

Where the queryFactory is obligated to do query.include("lokal") (includes the whole 'lokal' pointer), or `query.include("lokal.place") (only include the 'place' column of 'lokal');

Extra bonus - subclassing

As a final note, it does not look like you are using subclassing, but if you did, you could also have a specialized custom adapter for Cena subclasses.

public class CenaParseAdapter extends
        ParseQueryAdapter<Cena> {

    private static final String TAG = CenaParseAdapter.class.getSimpleName();



    public CenaParseAdapter(Context context,
            QueryFactory<Cena> queryFactory) {
        super(context, queryFactory);

    }

    TextView text;

    @Override
    public View getItemView(Cena cena, View v, ViewGroup parent) {

        if (v == null) {
            v = View.inflate(getContext(), R.layout.view_adapter_item_simple,
                    null);
        }

        super.getItemView(object, v, parent);

        text = (TextView) v.findViewById(R.id.text);

        text.setText(cena.getPlace());

        return v;

    }


}

In this case cena.getPlace() could look up the included lokal:

// inside Cena sublass

public Lokal getLokal() { // assuming Lokal also is subclassed
    return (Lokal)getParseObject("lokal");
}

public String getPlace() {
    return (getLokal() != null) ? getLokal().getPlace() : "";
}

// inside Lokal subclass

public String getPlace() {
    return getString("place");
}

这篇关于parse.com - 嵌套查询和加入表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-28 03:51