2015-08-31 22 views
6

RxJava'yı SqlBrite ile birlikte kullanmaya başladım ve zip işleci ile ilgili bazı sorunlar yaşıyorum.RxJava ve Sqlbrite - hangi operatörün kullanıldığını

Diyelim ki 2 sınıfım var, User ve Tweet.

public class User { 
    public long id; 
    public List<Tweet> users; 
    ... 
} 

public class Tweet { 
    public long id; 
    public User poster; 
    ... 
} 

Ve kendi SQLite tablolar:

user 
--------- 
id INTEGER PRIMARY KEY 

tweet 
--------- 
id INTEGER PRIMARY KEY 
poster_id INTEGER 
FOREIGN KEY(poster_id) REFERENCES user(id) 

ve ilgili SqlBrite DAO

UserDao:

public class UserDao { 
    private final BriteDatabase briteDb; 
    private final TweetDAO tweetDao; 

    ... 

    public Observable<List<User>> getUsersWithTheirTweets() { 
     Observable<User> usersObs = briteDb.createQuery("user", "SELECT * FROM user") 
       .map(new Func1<SqlBrite.Query, List<User>>() { 
        @Override 
        public List<User> call(SqlBrite.Query query) { 
         Cursor cursor = query.run(); 
         List<User> result = new ArrayList<>(cursor.getCount()); 
         while (cursor.moveToNext()) { 
          User user = UserTable.parseCursor(cursor); 
          result.add(user); 
         } 
         cursor.close(); 
         return result; 
        } 
       }) 
       // transform Observable<List<User>> into Observable<User> 
       .flatMap(new Func1<List<User>, Observable<User>>() { 
        @Override 
        public Observable<User> call(List<User> users) { 
         return Observable.from(users); 
        } 
       }); 

     // combine each user with his tweets 
     return Observable.zip(usersObs, usersObs.flatMap(new Func1<User, Observable<List<Tweet>>>() { 
      @Override 
      public Observable<List<Tweet>> call(User user) { 
       return tweetDao.getTweetsByUser(user); 
      } 
     }), new Func2<User, List<Tweet>, User>() { 
      @Override 
      public User call(User user, List<Tweet> tweets) { 
       user.tweets = tweets; 
       return user; 
      } 
     }).toList(); 
    } 

} 

TweetDAO:

public class TweetDAO { 
    private final BriteDatabase briteDb; 

    ... 

    public Observable<List<Tweet>> getTweetsForUser(final User user) { 
     briteDb.createQuery("tweet", "SELECT * FROM tweet WHERE poster_id = ?", Long.toString(user.id)) 
       .map(new Func1<SqlBrite.Query, List<User>>() { 
        @Override 
        public List<Tweet> call(SqlBrite.Query query) { 
         Cursor cursor = query.run(); 
         List<Tweet> result = new ArrayList<>(cursor.getCount()); 
         while (cursor.moveToNext()) { 
          Tweet tweet = TweetTable.parseCursor(cursor); 
          tweet.user = user; 
          result.add(tweet); 
         } 
         cursor.close(); 
         return result; 
        } 
       }) 
    } 
} 

Eğer UserDao görebileceğiniz gibi, ben her User için Tweet listesini doldurmak için zip ve flatMap operatörleri bir arada kullanmaya çalıştı.

İlk soru: Bunu yapmanın daha iyi bir yolu var mı?

İkinci soru: zip operatör sonsuza asmak gibi görünüyor ve asla ben tweetDao.getTweetsByUser(user) denir görüyoruz ama zip ait Func asla denir ... Herkes bir fikrim var misin ... tamamlar?

Üçüncü soru: flatMap ve from bir arada kullanarak çok bir Observable<T> başka bir Observable<List<T>> dönüştüren daha iyi bir yolu var mı? RxJava güçlüdür ama öğrenme eğrisi oldukça dik olduğunu

Kahretsin, ...

cevap

4

Neden veritabanı katılmak halledeyim?

SELECT * FROM user INNER JOIN tweet ON user._id = tweet.poster_id 

İki tablonun aynı ada sahip sütunları varsa, bazı sütunları yeniden adlandırmanız gerekebilir.

+0

here katılır hakkında

Daha Bunu da işe yarayabilir sanırım. Kullanıcı başına her bir tweet satırını –

+0

@LordRaydenMk olarak gruplandırmam gerekiyordu, karmaşık bir sql olup olmadığını ve wrapContentProvider yöntemini kullanıyor muydu? –

İlgili konular