Комментарии 38
В ActiveAndroid, как я погляжу, можно на уровне аннотаций задать имя поля, тогда можно использовать нормальные наименования для свойств класса, а имя поля задавать аннотациями.
А в других нельзя так? В OrmLite, например, если я на свойство
p.s. а вы сами используете какие-то ORM? Если бы речь шла о каком-то серверном приложении, то я бы не спрашивал, на клиенте просто редко сталкиваешься с ситуации, когда тонны данных записываются/читаются в SQLite.
А в других нельзя так? В OrmLite, например, если я на свойство
name
класса поставил DatabaseField
, то в таблице необходимо, чтобы поле называлось именно так?p.s. а вы сами используете какие-то ORM? Если бы речь шла о каком-то серверном приложении, то я бы не спрашивал, на клиенте просто редко сталкиваешься с ситуации, когда тонны данных записываются/читаются в SQLite.
0
Было бы интересно увидеть именно сравнение этих библиотек. Наличие/отсутствие каких-либо функций, по которым уже можно делать свой выбор. В частности для меня было критично то, что, например, ORMLite не умеет работать через ContentProvider. Планирую как-нибудь попробовать Сupboard, там, говорят, есть возможность работать через провайдер.
+3
Для ormlite есть возможность использовать ContentProvider. Например github.com/jakenjarvis/Android-OrmLiteContentProvider
0
Сейчас будет имхо: полноценный ORM на мобильных устройствах — оверхед как по памяти, так и по производительности.
Как правило, достаточно просто библиотеки, которая обеспечивает вам уход от прямой работы с неудобным API ContentProvider и/или SQLiteDatabase.
И такие библиотеки есть:
BambooStorage мейтенится мной, используется в продакшене в нескольких приложениях, полет нормальный, есть мощные планы по 2.0 (постоение запросов через билдеры, поддержка SQLiteDatabase без ContentProvider, поддержка RxJava, compile-time генерация методов для парсинга/сериализации).
На данный момент оно предоставляет Collection-like API для хранения ваших «классов» в ContentProvider, при этом оверхед по производительности сведен к минимуму, по памяти — оверхеда вообще нет
Как правило, достаточно просто библиотеки, которая обеспечивает вам уход от прямой работы с неудобным API ContentProvider и/или SQLiteDatabase.
И такие библиотеки есть:
- CupBoard — https://bitbucket.org/qbusict/cupboard/wiki/Home
- BambooStorage — https://github.com/pushtorefresh/bamboo-storage
BambooStorage мейтенится мной, используется в продакшене в нескольких приложениях, полет нормальный, есть мощные планы по 2.0 (постоение запросов через билдеры, поддержка SQLiteDatabase без ContentProvider, поддержка RxJava, compile-time генерация методов для парсинга/сериализации).
На данный момент оно предоставляет Collection-like API для хранения ваших «классов» в ContentProvider, при этом оверхед по производительности сведен к минимуму, по памяти — оверхеда вообще нет
+4
storIOSQLite
.get()
.listOfObjects(Tweet.class)
.withQuery(Tweet.ALL_TWEETS_QUERY)
.withMapFunc(Tweet.MAP_FROM_CURSOR)
.prepare()
.createObservableStream() // here is the magic! It will be subscribed to changes in tables from Query
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<List<Tweet>>() {
@Override public void call(List<Tweet> tweets) {
// display the data
// magic: this will be called on each update in "tweets" table
}
});
Это конечно круто. Как понимаю внутри Callable interface?
А что на счет добавления группы записей?
В ContentProvider можно использовать bulkInsert для этого
@Override
public int bulkInsert(Uri uri, ContentValues[] values) {
...
Как у вас организовано?
Хорошо бы пример использования такого случая…
0
Тут такое дело:
1 — BambooStorage это теперь StorIO, 100% новый код, новый подход, релиз 1.0.0 уже скоро
2 — StorIO предоставляет API для работы как с SQLiteDatabase, так и с ContentResolver
В StorIO есть три операции: Get, Put, Delete. На данный момент BulkInsert для ContentResolver к сожалению в такой подход вписывается плохо, т.к. гарантий, что конфликтов при записи в контент провайдер нет, перед вставкой, каждая запись проверяется: нет — insert, есть — update. Так что ответ пока такой — bulkInsert не поддерживается, возможно мы что-то предложим в будущем.
1 — BambooStorage это теперь StorIO, 100% новый код, новый подход, релиз 1.0.0 уже скоро
2 — StorIO предоставляет API для работы как с SQLiteDatabase, так и с ContentResolver
Как понимаю внутри Callable interface?не понял о чём конкретно вопрос :)
А что на счет добавления группы записей?
В ContentProvider можно использовать bulkInsert для этого
В StorIO есть три операции: Get, Put, Delete. На данный момент BulkInsert для ContentResolver к сожалению в такой подход вписывается плохо, т.к. гарантий, что конфликтов при записи в контент провайдер нет, перед вставкой, каждая запись проверяется: нет — insert, есть — update. Так что ответ пока такой — bulkInsert не поддерживается, возможно мы что-то предложим в будущем.
0
1000 записей добавить, через транзакцию делать самому?
И что будет с ContentObserver на курсоре. Именно bulkInsert решал проблему дергания 1000 раз в приведенном примере 1000 запросов
Встретил в ваших примерах знакомую конструкцию)
Подумал внутри что то подобное…
dataBase.beginTransaction();
...
dataBase.insert
...
dataBase.setTransactionSuccessful();
dataBase.endTransaction();
И что будет с ContentObserver на курсоре. Именно bulkInsert решал проблему дергания 1000 раз в приведенном примере 1000 запросов
Встретил в ваших примерах знакомую конструкцию)
Подумал внутри что то подобное…
public class DoTask implements Callable<Object> {
public Object call() {
return retDo;
}
}
0
StorIOSQLite конечно же поддерживает транзакции, но вот в случае с ContentProvider — вы не можете через ContentResolver начать транзакцию и вызывать insert, update, delete.
BulkInsert в ContentResolver, на мой взгляд, — хак, т.к. по сути его можно использовать только для своего контент провайдера, когда вы точно знаете что он пустой или что там таких записей нет и все значения успешно заинсертятся. Как правило, bulkInsert применяется для первоначального наполнения контент провайдера, но в таком случае это ваш контент провайдер и можно напрямую записать через транзакцию в SQLite если, конечно, в контент провайдере используется SQLite.
Когда мы обращаемся в чужой контент провайдер, у нас нет гарантий, что там нет таких же данных, bulkInsert в таком случае опасен.
BulkInsert в ContentResolver, на мой взгляд, — хак, т.к. по сути его можно использовать только для своего контент провайдера, когда вы точно знаете что он пустой или что там таких записей нет и все значения успешно заинсертятся. Как правило, bulkInsert применяется для первоначального наполнения контент провайдера, но в таком случае это ваш контент провайдер и можно напрямую записать через транзакцию в SQLite если, конечно, в контент провайдере используется SQLite.
Когда мы обращаемся в чужой контент провайдер, у нас нет гарантий, что там нет таких же данных, bulkInsert в таком случае опасен.
0
Как правило, bulkInsert применяется для первоначального наполнения контент провайдера
Да именно это и имел в виду. Иногда надо небольшими пачками дописывать. Использовал действительно только в одном месте и был уверен
Даже скажу применил
long id = db.insertWithOnConflict(TABLE_NAME, null, value, SQLiteDatabase.CONFLICT_REPLACE);
Все же думаю попробовать UcaOrm
Подкупило описание на хабре из трех статей стэб бай стэп так сказать. Описано именно то что требовалось в проекте, а также сверх.
MIT лицензия!
0
вот в случае с ContentProvider — вы не можете через ContentResolver начать транзакцию и вызывать insert, update, delete.Вы можете реализовать
ContentProvider.applyBatch(ArrayList<ContentProviderOperation> operations)
, список operations — это ваши insert/update/delete, полученные с помощью ContentProviderOperation.new*
(). В реализации поддерживайте транзакции и не вызывайте notifyChange когда не надо.0
Да, можно реализовать applyBatch, это подойдёт для удаления множества записей, но Put Operation требует проверки на конфликт, соответственно, сначала нужно проверить есть ли такая запись, а затем сделать insert или update, StorIOContentResolver будет использовать applyBatch там, где это возможно
0
Проверка на конфликт не всегда нужна. Если вы используете ContentProvider поверх SQLite, то можно использовать
db.insertWithOnConflict(table, null, values, SQLiteDatabase.CONFLICT_REPLACE)
, и это будет то же самое, только все проверки будет делать за вас SQLite. Всё, конечно, зависит от конкретного случая.0
Да, согласен. Но insertWithOnConflict не всегда подходит, к сожалению. В StorIO можно определить свое поведение для каждого типа операций и использовать insertWithOnConflict, вместо query -> insert/update, например.
0
public User() { } public User(String username, String password,int age){ ... }
Зачем юзеру контекст?User johndoe = new User(getContext(),"john.doe","secret",19);
0
Sugar вообще откровенно так себе написан: синглтон, SugarContext.init(context) приведет к мемори ликам, если передать туда не ApplicationContext и все такое. Разработчик еще пишет, что в Application.onTerminate() (который никогда не вызывается) нужно вызывать SugarContext.terminate(), более менее опытный человек бы такого не понаписал, конечно
+3
А вы не поясните про мемори лики в синглтоне?
0
Конкретно в Sugar вызов SugarContext.init(context) с передачей в качестве контекста, например, Activity, вы получите постоянно удерживаемую сильную ссылку на эту Activity, соответственно, GC не сможет освободить память, связанную с данной Activity, пока есть хоть одна сильная ссылка на нее.
Правильным решением, со стороны Sugar, было бы вызывать context.getApplicationContext() при сохранении ссылки в SugarContext, к тому же, это бы дало runtime проверку на передачу null в качестве контекста.
Правильным решением, со стороны Sugar, было бы вызывать context.getApplicationContext() при сохранении ссылки в SugarContext, к тому же, это бы дало runtime проверку на передачу null в качестве контекста.
0
Смею предположить, что там доступ к ресурсам нужен будет…
0
Realm не является ORM, он даже не использует SQLite. Это написанная с нуля NoSql база.
Фраза " Realm написан на С++ и запускается прямо на вашем устройстве (без интерпретации), что обеспечивает очень высокую производительность" вообще не понятна, все ORM как бы запускается на устройстве.
А кто-то использовал ORM вместе с Kotlin? Завести Realm не получилось из-за его особенности процессинга аннотаций и требований к классам модели.
Фраза " Realm написан на С++ и запускается прямо на вашем устройстве (без интерпретации), что обеспечивает очень высокую производительность" вообще не понятна, все ORM как бы запускается на устройстве.
А кто-то использовал ORM вместе с Kotlin? Завести Realm не получилось из-за его особенности процессинга аннотаций и требований к классам модели.
+3
Перешел на Realm, работает быстро, писать просто. Жду когда введут запросы на ссылки.
0
В 0.72 уже появились:
realm.io/news/
We just released Realm Java 0.72.0 to this website and to Maven. It includes support for Eclipse, Link Queries, Sorting on more field types, Transaction Rollback and more!
realm.io/news/
0
Почему не использовать встраиваемые объектные БД? вроде db4o. Минус один уровень абстрагирования
0
Наконец все идет к тому, что дизайн — это прежде всего удобство пользования (или если хотите — юзабилити), а не оформление и эффекты.
0
«создание запросов — занятие скучное и ленивое» — не согласен. Я даже немного скучаю по былым временам девелопинга под 1cv8, когда многие алгоритмы строятся с использованием запросов, составление которых порой превращается в хитромудрый квест, делающих до 70-80% работы алгоритма.
0
В Android есть еще одно хранилище, очень простое — SharedPreferences
-3
Это не БД, это просто XML файлы в определённой директории. Несвязный набор пар ключ-значение. При чем тут ORM?
0
Внесу свою лепту к этой статье: я бы не советовал использовать любые ОРМ в тех случаях, если у вас огромные наборы данных и вложенные коллекции больше 2х уровней. Выборка большого количества данных ужасно медленно работает.
Также, как сказал товарищ выше, ORMLite не умеет работать с ContentProvider, поэтому приходится искать обходные пути.
Также, как сказал товарищ выше, ORMLite не умеет работать с ContentProvider, поэтому приходится искать обходные пути.
-2
Перепробовав все ORM на Android я выбрал для себя следующий набор для работы с БД:
1: ProviGen — для генерации CP и SQLiteOpenHelper на базе контракта.
2: Cupboard — для удобного построения запросов и cursor to object преобразований.
1: ProviGen — для генерации CP и SQLiteOpenHelper на базе контракта.
2: Cupboard — для удобного построения запросов и cursor to object преобразований.
-1
Не знаю как вы, но я использую в играх для мобил лучший ORM (с поддержкой MongoDB/Membase и кучей других хранилищ данных) Spring Data projects.spring.io/spring-data/
1. Простотота
2. Скорость
3. Отсутвие велосипедов
Если есть время изучать велосипеды с синтаксическим сахором, ради бога. Но я более-менее выбираю «стандарт»
1. Простотота
2. Скорость
3. Отсутвие велосипедов
Если есть время изучать велосипеды с синтаксическим сахором, ради бога. Но я более-менее выбираю «стандарт»
+1
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
5 лучших ORM для Android