| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Java ME (J2ME) > работа со Storage |
| Автор: redrick 29.11.2005, 16:34 |
| в RMS столкнулся с проблемой : на J2ME девайсе необходимо хранить достаточно много информации (на грани ограничений по памяти), которая имеет довольно сложную структуру. Реально все это не больше не меньше чем несколько (~5) таблиц БД. Соответственно с ними нужно выполнять операции сродни select, join. Приходится довольно много писать руками (на языке вертится "писать СУБД"). Собственно вопрос : если кто-то сталкивался с такой проблемой - как решали ? мне первое, что приходит в голову - поискать исходники/библиотеки в которых это реализовано в том или ином виде. самое близкое к желаемому, что сумел найти : http://developers.sun.com/techtopics/mobility/midp/articles/databaserms/ |
| Автор: javastic 30.11.2005, 14:22 |
| Я ничего похожего на БД не видел. И пользовался той ссылкой что ты написал (когда-то). Использовал Hashtable и данные из одного рекордСтора, потом искал по ключю в другом рекордСторе. Можно создать ещё третий рекордСторе в котором будут содержаться ключи из предедущих двух. Например: recordStore 1: Cars Key (допустим это CarId): 1, Value (Допустим это CarName): Jeep Key (допустим это CarId): 2, Value (Допустим это CarName): Mitsubishi Key (допустим это CarId): 3, Value (Допустим это CarName): Citroen recordStore 2: Wheels Key (допустим это WheelId): 1, Value (Допустим это WheelType): 14" Key (допустим это WheelId): 2, Value (Допустим это WheelType): 15" Key (допустим это WheelId): 3, Value (Допустим это WheelType): 25" recordStore 3: CarsWheelsRelations Key (допустим это WheelId): 1, Value (Допустим это WheelType): 3 Key (допустим это WheelId): 2, Value (Допустим это WheelType): 1 Key (допустим это WheelId): 3, Value (Допустим это WheelType): 2 вот с такой бадьи можно делать выборку. а вообще можно придумать какой нибудь разделитель, например "|" и в один рекордсет пихать данные в виде текстовой таблицы, например: // table Products (справочник товаров) // Pid, ProductType, Name, Qty, Unit, Price, VendorId // String products = new String("1|AB|Pepsi-Cola|153|B|21.5|41232"); далее загоняем это в рекордСтор, в трёх других у нас будет храниться ProductTypes (как TypeId, TypeName) в виде (3|Drinks), Units (как UnitId, UnitName) в виде (12|Bottle), Vendors (как VendorId, Name, Phone, Address, и т.д.) в виде (41232|Pepsi Bottlers Company|+7-812-xxx-xxxx|Promzona Parnas|... и т.д.) Написав раз нормальный класс по обработке этого всего дела можно пользоваться в будущем и я думаю что такой компонент даже можно продавать. |
| Автор: redrick 30.11.2005, 15:17 |
| понятно, спасибо. насчет компонента - солидарен - порываюсь это сделать, да только времени нема - хватает лишь на написание под конкретную задачу. Плюс еще такая мысль : нехило бы сделать отложенную запись, т.е. юзер заходи в меню "управление моими авто", добавляет, удаляет, меняет данные, потом жмет "доне" - и мы сохраняем все. Или "кансел" - и мы не сохраняем ничего. PS. если увеличить число таблиц и полей в них, то чем не БД ? |
| Автор: javastic 30.11.2005, 15:22 | ||
Тогда смотри метод в рекордСторе по изменению его содержимого. Должен быть такой. Можно в виде коммандного текста сохранить в коллекции (например Stack), а после кнопки "done" перебирать всё что юзер наделал и автоматом выполнять нужные действия. |
| Автор: redrick 30.11.2005, 16:18 | ||||||
не понял мысли - имеется ввиду setRecord() ? (на всякий случай - речь идет об MIDP 1.0) как он обеспечивает отложенность ?
да, это первое что приходит в голову... однако при таком подходе изменения станут доступны только после сохранения в хранилище, а иногда хочется видеть их сразу и отражать где то в другом месте (на другом скрине) так что сейчася я пришел к загрузке и распарсиванию всех данных из хранилища в начале произведения операций, потом операции производятся над этими данными и по "доне" - скидываются в Storage. Недостаток очевидем - много памяти жрет.
неужели нет таких до сих пор ? или не искал ? |
| Автор: Dancer 30.11.2005, 16:33 |
| а почему просто тогда в RMS сразу всё не сохранять, что пользователь делает, но только это будет у тебя новый RecordStore (имя такое же как тот рекордстор в который производишь плюсь добавляешь _TMP или какой-то идентификатор, как душе угодно) Когда делешь выборку значений из таблиц основной, смотришь, по такой-то записи есть что-то в _TMP, или если же вообще _TMP не сущетвует, то берёшь из основной таблицы, если же существует, то берёшь значение, елси оно есть из _TMP, если нужного значения (записи, строки таблицы, или как лучше назвать не знаю) нету, то берёшь из основной рекордсторе. Если юзер захотел изменения внести, то из _TMP вносятся данные в основую таблицу и _TMP уничтожается. Если же не захотел вносить изменения, то просто удаляем _TMP Надеюсь, я доступно объяснил и меня поняли |
| Автор: redrick 30.11.2005, 17:50 |
| Dancer не, все доступно ) недостаток предложенного тобой подхода - скорость. Операции с этим самым хранилищем довольно тормозные, особенно когда их много. По крайней мере мой WTK-шный эмулятор загибался надолго. Поэтому операции с хранилищами лучше делать "batched" - т.е. по возможности все и сразу. |
| Автор: Dancer 30.11.2005, 20:34 |
| ну, либо скорость - либо память А ещё можно в файловой системе телефона (нужна поддержка JSR-75 на телефоне) хранить файлики (ну, скажем в виде xml) и используя kXML работать с этими файликами. |
| Автор: redrick 30.11.2005, 21:23 | ||
Dancer
с этим конечно не поспоришь - только разбазаривать такты и мегабайты на право и налево тоже не хорошо =) твой подход крайность с одной стороны, мой - с другой. охота оптимальности. Но так можно долго оптимизировать. всем спасибо. |
| Автор: Dancer 1.12.2005, 11:25 |
| Слушай, можно сделать так: создаётся Hashtable в ней ключ будет имя таблицы и идентификатор записи. Как ты делаешь какое-то действие с записью таблицы (RMS) сначала проверяешь, нету ли этой записи в Hashtable, если есть - то информацию берём из Hashtable. Когда нужно откатиться, то просто убивается запись в Hashtable, в RMS ничего не делаем. Если нужно закоммитить изменения, то данные из Hashtable кладём в RMS, и из Hashtable эти данные убираются. Мы экономим память, по сравнению с предложеным подходом Stack (javastic), и в принципе не очень нагружаем RMS когда работаем с записью которая располагается в Hashtable Да, и конечно придётся повозиться с алгоритмами поиска записей (как организовать хеш-ключи или ещё как то), вот этим то и можно будет добиться производительности. Могу заняться этим (зацепило меня это дело, неужели нету такого компонента, ХМММММ...... тогда это упущение нужно исправить! |
| Автор: redrick 1.12.2005, 16:47 |
| =) здорово. Чтож - меня это дело конечно интересует, как и тебя - и я буду им заниматься по мере возможности. Просто сейчас есть более срочные задачи - запарка - едва успеваю делать просто чтобы работало, не то чтобы там оптимально =) Кароче говоря сохраняю топик и буду держать в курсе дела, чего и тебе желаю =) |