ORMLite 中的集合

Posted

技术标签:

【中文标题】ORMLite 中的集合【英文标题】:Collections in ORMLite 【发布时间】:2011-07-28 07:49:33 【问题描述】:

你好 我想在我的 android 应用程序中使用 ORMlite 保留一些集合数据。例如:

class Person 
  @DatabaseField(generatedId=true)
  private int id;

  @DatabaseField
  private String name;

  @DatabaseField
  private String surname;

  @ForeignCollectionField
  private Collections<Phone> phones;


class Phone 
  @DatabaseField(generatedId=true)
  private int id;

  @DatabaseField
  private String number;

  @DatabaseField
  private String type; 

我应该如何保存这个集合。

编辑

如你所说,我使用 ForeignCollectionField。但现在我有另一个问题 - 有可能这样的构造(我改变了一点课程)

@DatabaseTable
public class Student 

    @DatabaseField(generatedId=true)
    private int id;

    @DatabaseField
    private String name;

    @DatabaseField
    private String surname;

    @DatabaseField
    private String semestr;

    @ForeignCollectionField
    private Collection<Adres> adres;


public class Adres implements Serializable 

    @DatabaseField(generatedId=true)
    private int id;

    @DatabaseField(foreign=true, columnName="student_id")
    private Student student;

    @DatabaseField
    private String miasto;

    @DatabaseField
    private String ulica;

    @DatabaseField
    private String nr;

    @ForeignCollectionField
    private Collection<Phone> phone;


public class Phone 

    @DatabaseField(generatedId=true)
    private int id;

    @DatabaseField
    private String number;

    @DatabaseField(foreign=true, columnName="adres_id" )
    private Adres adres;

我建造了这个结构,我有 3 个 tabelas。

Student queryForStudentMarcin = simpleDao.queryForId(studentMarcin.getId());
Collection<Adres> adres = queryForStudentMarcin.getAdres();

for (Adres a : adres) 
    int id = a.getId();
    String miasto = a.getMiasto();
    String ulica = a.getUlica();
    String nr = a.getNr();

然后我这样做并出现错误:

04-03 15:55:58.392: ERROR/AndroidRuntime(6506): FATAL EXCEPTION: main
04-03 15:55:58.392: ERROR/AndroidRuntime(6506): java.lang.NullPointerException
04-03 15:55:58.392: ERROR/AndroidRuntime(6506):     at com.j256.ormlite.field.FieldType.buildForeignCollection(FieldType.java:579)
04-03 15:55:58.392: ERROR/AndroidRuntime(6506):     at com.j256.ormlite.stmt.mapped.BaseMappedQuery.mapRow(BaseMappedQuery.java:58)
04-03 15:55:58.392: ERROR/AndroidRuntime(6506):     at com.j256.ormlite.stmt.SelectIterator.nextThrow(SelectIterator.java:107)
04-03 15:55:58.392: ERROR/AndroidRuntime(6506):     at com.j256.ormlite.stmt.SelectIterator.next(SelectIterator.java:120)
04-03 15:55:58.392: ERROR/AndroidRuntime(6506):     at com.example.orm.MainActivity.dodajDoBazyCollection(MainActivity.java:140)
04-03 15:55:58.392: ERROR/AndroidRuntime(6506):     at com.example.orm.MainActivity$2.onClick(MainActivity.java:66)
04-03 15:55:58.392: ERROR/AndroidRuntime(6506):     at android.view.View.performClick(View.java:2408)
04-03 15:55:58.392: ERROR/AndroidRuntime(6506):     at android.view.View$PerformClick.run(View.java:8816)
04-03 15:55:58.392: ERROR/AndroidRuntime(6506):     at android.os.Handler.handleCallback(Handler.java:587)
04-03 15:55:58.392: ERROR/AndroidRuntime(6506):     at android.os.Handler.dispatchMessage(Handler.java:92)
04-03 15:55:58.392: ERROR/AndroidRuntime(6506):     at android.os.Looper.loop(Looper.java:123)
04-03 15:55:58.392: ERROR/AndroidRuntime(6506):     at android.app.ActivityThread.main(ActivityThread.java:4627)
04-03 15:55:58.392: ERROR/AndroidRuntime(6506):     at java.lang.reflect.Method.invokeNative(Native Method)
04-03 15:55:58.392: ERROR/AndroidRuntime(6506):     at java.lang.reflect.Method.invoke(Method.java:521)
04-03 15:55:58.392: ERROR/AndroidRuntime(6506):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
04-03 15:55:58.392: ERROR/AndroidRuntime(6506):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
04-03 15:55:58.392: ERROR/AndroidRuntime(6506):     at dalvik.system.NativeStart.main(Native Method)

有什么建议吗?

编辑2

问题是从 db 读取数据。这个程序工作正常,现在很好,但我只是用它来理解 ORMlite。非常感谢格雷的帮助。

protected void czytajZBazy() throws SQLException 

    Dao<Student, Integer> simpleDao = getHelper().getSimpleDao();
    Dao<Adres, Integer> adresDao = getHelper().getAdresDao();
    Dao<Phone, Integer> phoneDao = getHelper().getPhoneDao();

    /**
     * wyswietl adresy dla studenta Marcin
     */
    QueryBuilder<Student, Integer> qbStudent = simpleDao.queryBuilder();;
    Where<Student, Integer> where = qbStudent.where();
    where.eq("name", "Marcin");
    PreparedQuery<Student> prepare = qbStudent.prepare();
    CloseableIterator<Student> iterator = simpleDao.iterator(prepare);
    while(iterator.hasNext())
        Log.v("inside ", "loop");
        Student next = iterator.next();
        Log.v("sudent", ""+next.getId()+" "+next.getName()+" "+next.getSurname());

        QueryBuilder<Adres, Integer> adresQB = adresDao.queryBuilder();
        Where<Adres, Integer> where2 = adresQB.where();

        where2.eq("student_id", next.getId());

        PreparedQuery<Adres> preparedAdres = adresQB.prepare();
        CloseableIterator<Adres> iterator2 = adresDao.iterator(preparedAdres);

        while(iterator2.hasNext())
            Log.v("iterator po adresie", "!!");
            Adres nextAdres = iterator2.next();
            Log.v("Adres", ""+nextAdres.getId()+" "+nextAdres.getMiasto());
            //wypisz telefony 
            QueryBuilder<Phone, Integer> queryPhone = phoneDao.queryBuilder();
            Where<Phone, Integer> where3 = queryPhone.where();
            where3.eq("adres_id", nextAdres.getId());

            PreparedQuery<Phone> preparedPhone = queryPhone.prepare();
            CloseableIterator<Phone> iterator3 = phoneDao.iterator(preparedPhone);

            while(iterator3.hasNext())
                Log.v("inside phone iterator", "");
                Phone next2 = iterator3.next();
                Log.v("phone", ""+next2.getId()+" "+next2.getNumber());
            
            iterator3.close();
        
        iterator2.close();
    
    iterator.close();

【问题讨论】:

您能直接与我联系 Bandzio 吗?在 ORMLite 主页底部点击我的名字,然后进入 Contact Gray:ormlite.com @Gray 如何让 ForeignCollection 进入我的光标。参考:***.com/questions/22071367/… 【参考方案1】:

有许多资源和手册可帮助您在 Android 下使用 ORMLite。

http://ormlite.com/docs/android http://ormlite.com/docs/android-examples

要持久化一个集合,您必须首先为该类获取一个 Dao,然后使用该 Dao 创建每个对象:

Dao<Person, Integer> personDao =
    DaoManager.createDao(androidConnectionSource, Person.class);
for (Person person : personCollection) 
    personDao.create(person);

Phone 类也几乎相同。


他真的在问如何使用 ORMLite 的ForeignCollectionField 功能。可在此处找到相关文档:

http://ormlite.com/docs/foreign-collection

还有一个使用它的示例项目。在上面的示例中,您在Phone 中缺少一个Person 字段。如果这个人有一个电话对象的集合,那么每个电话对象都需要有一个对应的人。这在 ORMLite 中称为“外来对象”。

http://ormlite.com/docs/foreign-object

【讨论】:

我的疑惑是关于如何在课堂上注释集合字段。例如,我有 Person 对象:Name : Martin; Surname : XXX; Phones : id = 1; number = 123123123; type = mobile ; id = 2 ;number = 877777123; type = mobile; id = 3; number = 127378643; type = mobile. 我需要 Table Person 和 Table Phone(在 onCreate() 中创建)来存储我的数据。在 JPA 中,我在这里使用 @OneToMany 之类的东西来在 Person 中注释现场电话。如何在 ORMLite 中实现这一点?还有如何实现@ManyToMany。如何在类中注释集合字段?感谢您的帮助和 OMRLite Gray :) 请编辑您的问题@Bandzio 以更好地代表您的问题,我将编辑我的答案。 我意识到我只需要保持简单。如果我的班级中有一些收集字段,那么秘诀就是手动创建它们。所有集合都有自己的表。我只想找到一些神奇的“注释”来为我做所有事情。但如果有人对这种方法有一些建议,我将不胜感激。 ORMLite 不像其他 ORM 库那么神奇。我已经注释了我的答案以展示如何使用异物。那就是缺少的东西。 ForeignCollectionField 无法在这里解决...我的 maven 依赖最可能的原因:com.j256.ormliteormlite-android4.9 com.j256.ormliteormlite-core 有人吗?

以上是关于ORMLite 中的集合的主要内容,如果未能解决你的问题,请参考以下文章

Android ORMLite ForeignCollection关联外部集合

使用 ServiceStack.ORMLite 的存储库模式中的事务

ormlite中的抽象嵌套类

在 android 中使用 ORMLite 持久化 Collection 类

ORMLite 更改 onUpgrade 中的 allowGeneratedIdInsert

servicestack ormlite 中的分页