|
|
|||||||||||||||||||||||||||||
|
Использование Oracle Berkeley DB Java Edition в качестве менеджера хранения объектов для Google Web ToolkitИсточник: oracle Эрик Одет & Грегори Бурд
При построении Web-приложений с применением Google Web Toolkit, использование Berkeley DB Java Edition в качестве хранилища данных может значительно сократить расходы на проект. Стандартное для Java Platform Enterprise Edition ( Java EE ) решение в Web -приложениях для хранения объектов ( OP - object persistence ) заключается в использовании Enterprise JavaBeans ( EJB ), техники объектно-реляционного отображения ( object - to - relational mapping - ORM ). Java -объекты транслируются в/из SQL -предложения и запоминаются в базе данных реляционной СУБД как строки в таблицах базы данных. Это наиболее типичный подход по следующей причине. Большинство пользователей обнаруживают, что многие аспекты деятельности их организаций зависят от SQL и серверов реляционной СУБД Oracle при управлении критически важной информацией. В этих случаях EJB и интерфейс Java Persistence API ( JPA ) являются наилучшими подходами для хранения объектов. Пользователи совместно используют Java -приложения и существующие приложения, "говорящие" на одном и том же языке SQL , чтобы получить доступ к одним и тем же данным базы. Интересно, что некоторые EJB -приложения хранят данные в реляционной базе данных просто потому, что это типовой и привычный подход, а не потому, что другие приложения используют эти же данные через SQL ради своих целей. Если же этих данных нет в существующей реляционной базе и нет планов по доступу к ним с применением других (не ORM ) средств, то сам уровень ORM может быть лишним. В некоторых случаях доступ к таким данным может выполняться какими-то SQL -средствами при реализации нерегламентированных ( ad hoc ) запросов, но это неверно в нашем случае. Глядя со стороны объектов, подход с ORM добавляет много необязательной работы в том случае, когда этот подход является единственным способом взаимодействия с реляционной SQL -базой. В отличие от этого, Direct Persistence Layer ( DPL ) - Уровень непосредственного хранения - в Oracle Berkeley DB Java Edition хранит объектные данные прямо в базе данных Btree , что не требует их транслирования в некоторый промежуточный язык. В этой статье рассмативается практический пример комбинирования Berkeley DB Java Edition и Google Web Toolkit для создания высокоэффективного решения в области хранения объектов. Oracle Berkeley DB Java Edition Oracle Berkeley DB Java Edition - один из трех продуктов , приобретенных корпорацией Oracle при покупке компании Sleepycat Software в феврале 2006 г . Это " чистокровный Java- движок " базы данных (pure-Java database engine), разработанный для хранения данных в локальной файловой системе . Он поддерживает транзакции, соответствующие ACID ( Atomicity , Consistency , Isolation , Durability ), обеспечивает высокие уровни множественного доступа, может масштабировать обработку данных до терабайт и использовать предварительно заданную часть оперативной памяти виртуальной Java -машины как буфер для этих хранимых данных. Berkeley DB Java Edition - это реинкарнация чрезвычайно успешной СУБД Berkeley DB , которая была написана на ANSI C . Но Java -версия значительно отличается от нее. Основными отличиями являются интерфейс DPL API в Berkeley DB Java Edition . Он поддерживает набор Java -аннотаций типа JPA ( Java annotations ), позволяющих легко задавать хранение, индексирование, изменение и уничтожение графов объектов без транслирования данных объектов в/из SQL . При применении интерфейса DPL в Berkeley DB Java Edition не используются ORM -компонент или другая база данных или соединение клиент-сервер. DPL позволяет задавать хранение графов объектов, взаимоотношений и индексов в очень интуитивной и эффективной манере. Аннотации в DPL подобны и по именам, и концептуально JPA . Интерфейс позволяет задавать хранение любых объектов типа Plain Old Java Objects ( POJO , http :// ru . wikipedia . org / wiki / POJO ) и правил хранения и конфигурирования для них в том же самом классе. Это первое ключевое отличие и преимущество DPL в Berkeley DB Java Edition в сравнении с решениями типа ORM ; нет необходимости поддерживать внешние конфигурационные файлы. Этот подход ведет к резкому росту производительности разработчиков, сокращению сложности проектов и перегрузки во время их выполнения. Приложения, разработанные с использованием EJB -решений, как правило, требуют конфигурационный файл для каждого класса, отображенного на физическую таблицу базы данных. Хотя такой подход к хранению объектов в виде Hibernate также использует Java -аннотации, на практике требуется, как минимум, понимание и контроль файла Hibernate . config . xml для управления строками соединений и другими установками, обеспечивающими приложению соединение с сервером реляционной базы данных через Java DataBase Connectivity ( JDBC ). Несмотря на превосходную интеграцию в средах разработки приложений типа IDE ( integrated development environment ), управление конфигурационными файлами и другую поддержку для EJB -решений, разработчик неизбежно придет к ручному редактированию этих файлов, а этот процесс требует много времени и приводит к множеству ошибок. Использование аннотаций на Java в Berkeley DB Java Edition для инкапсуляции установок в хранимые POJO -классы - это уникальный, простой и значительно снижающий число ошибок способ. Аннотации DPL обеспечивают контекст хранения в одном месте очевидным и интуитивным образом: этот исходный код находится именно там, где разработчик ожидает найти его. Google Web Toolkit - набор инструментов для построения Web -приложений Google Web Toolkit ( GWT ) - набор инструментов для реализации подхода "модель-представление-поведение" ( model - view - controller - MVC ), при котором выделяется процесс написания HTML , JavaScript и преобразования связанных с ними Asynchronous JavaScript и XML ( Ajax ) в код, написанный на Java , и затем обработанный GWT для размещения на серверах приложений с Java EE . Это снимает проблему сложности ручного кодирования HTML , JavaScript и других элементов, которые связывают действия JavaScript , запускаемые на HTML -странице (код на стороне клиента, выполняемый в браузере пользователя), с управляющим слоем, выполняющимся на сервере приложений Java Enterprise (на стороне сервера, на котором расположена база данных). Разработанный в хорошей IDE -среде GWT может предложить неизмеримые преимущества над другими наборами инструментов при значительно меньшей стоимости и сложности проекта. GWT также предоставляет среду отладки, так называемый хост-способ ( hosted mode ). Это позволяет разработчикам отлаживать свой клиент-код ( JavaScript и HTML ) в реальном времени, просто перемещая свой исходный Java -код в среду привычного стиля отладки. GWT справляется в реальном времени с отображениями между сгенерированным JavaScript / HTML - кодом и Java -кодом, резко сокращая время разработки для сложных Web -приложений. Аспекты хранения данных приложения также могут быть быстро отлажены хост-способом. Разработчики могут сосредоточиться на приложении, так как их инструменты снимают проблемы с конфигурированием и необязательной сложностью. GWT и BBD Java Edition DPL - "сладкая парочка" GWT и DPL -интерфейс в Berkeley DB Java Edition легко сочетаются. Управляющая GWT -среда ( GWT controller framework ) хорошо понимается и легко адаптируется. Приводимая ниже диаграмма последовательностей представляет типичный поток вызовов между механизмом RPC ( remote procedure call - вызов удаленной процедуры) в GWT и Berkeley DB Java Edition . Widget (или любой другой клиентский класс пользовательского интерфейса GWT в пакете com . google . gwt . user . client . ui ) содержит элементы управления пользовательского интерфейса, такие как Buttons или ListBoxes . Эти элементы обрабатывают события, инициированные пользователем, просматривающим страницу в своем Web -браузере. У каждого из этих элементов есть определение такого рода событий на экране, которые он может обработать. Эти события, такие как " OnClick ", могут привести к вызову кода классов на стороне сервера, используя интерфейс GWT RemoteService . До вызова RemoteService этот Widget должен создать Data Transfer Object ( DTO - типовой шаблон проектирования в Java EE ) из своих widget -полей. Затем создается метод AsynCallBack (сохранить DTO ), который передается данному RemoteService . Этот класс на стороне сервера создаст объект модели ( POJO ), представляющий данные, доставляемые из браузера к серверу с применением этого DTO , которые затем обрабатываются Berkeley DB Java Edition через вызовы к объекту BusinessService . Затем DataAccessors используются объектом бизнес-сервисов и управляют транзакционным хранением различных концептуальных объектов в базе данных Oracle Berkeley DB Java Edition .
Детали и код демо-примера В этой секции подробно рассматривается, как реализовать предложенную архитектуру на примере нескольких ключевых исходных кодов-примеров ( download zip ). Чтобы понять это, читатель должен быть знаком с Ajax , Java -аннотациями и объектно-ориентированным проектированием. Модель данных Два концептуальных класса моделей используются для иллюстрации этого примера: общий класс, называемый Person и подкласс этого класса, называемый User . Эти объекты и их взаимоотношения легко выражается DPL -аннотациями. Berkeley DB Java Edition затем сохранит эти данные с использованием транзакций в файлах локальной базы данных.
Класс Person
package ...
import com.sleepycat.persist.model.Persistent;
import com.sleepycat.persist.model.PrimaryKey;
@Persistent
public class Person {
@PrimaryKey
private String userName;
private String lastName;
private String firstName;
...
}
Класс User
package ...
import static com.sleepycat.persist.model.Relationship.ONE_TO_MANY;
import java.util.ArrayList;
import com.sleepycat.persist.model.Entity;
@Entity
public class User extends Person {
private String injury;
...}
Пользовательский интерфейс в GWT , обратные вызовы и DTO Наш пример использует очень простую концепцию задания номинальной информации и данных о болезни существующего пользователя (или пациентя). Он показывает как можно использовать концепцию наследования в базе данных Berkeley DB Java Edition DPL . Следующий рисунок - это простой Widget , используемый для создания отчета о болезни пользователя.
Приведем действительный код для этого примера: public class Profile extends Composite {
private TextBox injury;
private TextBox userNameTextBox;
private ListBox typesOfInjuries;
public Profile() {
...
final Button saveButton = new Button();
absolutePanel.add(saveButton, 13, 6);
saveButton.addClickListener(new ClickListener() {
public void onClick(final Widget sender) {
saveProfile();
}
});
saveButton.setText("Save");
...
protected void saveProfile() {
AsyncCallback callback = new AsyncCallback() {
public void onSuccess(Object result) {
Window.confirm("Profile Saved");
}
public void onFailure(Throwable ex) {
Window.confirm(ex.getMessage());
}
};
UserDTO wUserDTO = new UserDTO();
wUserDTO.setUserName( userNameTextBox.getText() );
wUserDTO.setInjury( injury.getText() );
ProfileService.Util.getInstance().save( wUserDTO, callback);
}
В этом коде-примере можно увидеть, что SaveButton event " OnClick " вызывает метод SaveProfile (). Этот метод использует простой блок обратного вызова для обработки возвращенного объекта от метода класса (на стороне сервера) UserService . createUser (). UserDTO , POJO , используется для передачи данных со стороны сервера на сторону клиента и содержит только базисные типы Java -данных, что позволяет ему быть классом сериализации. JavaScript работает только с базисными типами данных. Они должны быть сериализованы для передачи Web -браузеру клиента и удаленному серверу приложений; это ограничение становится требованием всех DTO в GWT . Если внимательно посмотреть на наши классы сущностей, то видно, что они не придерживаются какой-либо концепции клиентских приложений и не реализуют GWT -интерфейсов. Они полностью изолированы от клиентских приложений. Для достижения такого отделения используется шаблон проектирования Java EE - DTO . Эти DTO содержат только базисные типы данных и используются обоими пакетами ( Services и GWT Remote Services ). Они должны реализовать интерфейс GWT IsSerializable и конфигурационный XML -файл GWT также нужно создать. Другая важная причина для использования DTO заключается в том, что клиентские классы GWT должны быть преобразованы в код JavaScript . Для этого GWT использует Java -подобный ассемблер, который не поддерживает полную Java Platform , Standard Edition API или последние функции, такие как: аннотации и типизированные массивы ( typed arrays ). Это небольшое ограничение проектирования в GWT , оно не влияет на большинство задач программирования. Примечания:
Удаленные сервисы, бизнес-сервисы и средства доступа Remote Services, Business Services, and Accessors К данному моменту концептуальные сущности ( conceptual entities ) созданы и должным образом аннотированы с применением аннотаций DPL в Berkeley DB Java Edition . Методы базисных сервисов должны управлять состояниями транзакций этих сущностей. Следующий шаг - это создание GWT Remote Services . Они будут вызывать код DPL в Berkeley DB Java Edition для хранения данных. Remote Services - это стандартный способ коммуникаций с сервером приложений Java EE со стороны браузера на стороне клиента. Это делается с использованием стандарта Ajax , особенно HTTP POST , вызова сгенерированного и управляемого GWT . Код на стороне сервера для этого Ajax -вызова находится в "серверном" пакете (" server " package ) данного приложения GWT . Этот код выполняется в контейнере сервлета или сервера приложений Java EE (так как мы на стороне сервера, это - Java -код, в то время как код, выполняемый в браузере, - на JavaScript ) и именно здесь действия пользователя в браузере встраиваются в бизнес-логику, а DPL в Berkeley DB Java Edition используется для хранения объектов. Реализация RemoteService метода save(): Реализация RemoteService метода save():
...
public void createUser(UserDTO pUserDTO) {
//transform the presentation layer object into a conceptual object
User wUser = new User();
wUser.setUserName(pUserDTO.getUserName());
wUser.setInjury( pUserDTO.getInjury());
UserService userService = new UserService();
userService.createUser(wUser);
}
...
Модельные объекты ( Model objects ) - это классы бизнес-данных, которые реализуют аспекты управления данными приложения в базе данных. Программист, использующий EJB , может в первом приближении определить UserService как stateless session bean . Сам по себе класс BaseService не работает с какой-либо логикой. Этот класс управляется с транзакционным состоянием определенной задачи по одному или нескольким объектам в базе данных. Чтобы добавить логику бизнес-процесса сервису, это приложение (его разрабочик) должно расширить класс BaseService . В нашем примере класс UserService будет функционировать в этой роли и управляться со всем доступом к сущности User , обеспечивая реализации для методов, таких как createUser (), saveUser () и getUser (). Эта реализация размещена в пакете на стороне сервера данного проекта. Она вызывает бизнес-сервис UserService . Именно UserService реализует бизнес-логику для конкретного экземпляра. В нашем примере теперь нужно трансформировать объект UserDTO в объект User , а модель POJO с аннотациями DPL будет храниться в базе данных Oracle Berkeley DB Java Edition . Вспомните, что эта база данных - это просто набор файлов, размещенных в файловой системе сервера, к которой есть доступ у контейнера сервлета Web -приложения. Проверенные подходы проектирования требуют, чтобы в приложении объекты DTO были отделены от бизнес-объектов благодаря уровням ( layering ) и абстрагированию. Бизнес-сервисы не должны знать о классах DTO , они должны взаимодействовать только с концептуальными моделями объектов. Эти объекты хранятся в базе данных Berkeley DB Java Edition . Классы бизнес-сервисов отвечают за управление концептуальных моделей объектов в хранилище данных. Для соотношения этого с EJB , UserService подобна stateless session bean . Ниже приведен метод UserService . createUser (): ...
public User createUser( User pUser ) throws DatabaseException, Exception{
UserAccessor wUserAccessor = new UserAccessor();
//check mandatory fields
if ( pUser.getFirstName().equals("") //
pUser.getLastName().equals("") //
pUser.getUserName().equals("") ){
throw new Exception("Missing mandatory fields");
}
open( false, wUserAccessor);
// Start a transaction.
startTransaction();
// Put it in the store. Note that this causes our secondary key
// to be automatically updated for us.
try {
wUserAccessor.userByUserName.put( pUser );
// Commit the transaction. The data is now safely written to the
// store.
commit();
} catch (DatabaseException dbe) {
try {
System.out.println("Error creating a user");
} catch (Exception willNeverOccur) {
}
txn.abort();
throw dbe;
} catch (Exception e) {
txn.abort();
e.printStackTrace();
}
return pUser;
}
...
Этот метод использует унаследованные методы open () и startTransaction (), чтобы установить и использовать Berkeley DB Java Edition как базу данных ( aka сущность хранилище), а затем стартует транзакцию. Это разделение (функций) помогает разработчикам не делать ошибок при установке соединений с Berkeley DB Java Edition и позднее транзакций в процессе. Класс UserAccessor class ответственен за установку различных средств доступа интерфейса DPL в Berkeley DB Java Edition , особенно индексов, для доступа к данным. Этот класс инкапсулирует индексы, используемые позднее в данном коде для создания, изменения и уничтожения объектов в базе данных Berkeley DB Java Edition . Ниже приведено содержание класса UserAccessor: UserAccessor:
...
public class UserAccessor extends DefaultAccessor {
public PrimaryIndex<String, User> userByUserName;
public UserAccessor() {}
public void init() throws DatabaseException{
userByUserName = entityStore.getPrimaryIndex( String.class, User.class );
}
}
...
С установкой этих средств доступа, слой бизнес-сервисов упрощается и согласуется. Задача создания и управления индексами выделена как единое изолированное целое, которое не будет взаимодействовать с вашей бизнес-логикой. Вот пример, в котором используется индекс для выборки экземпляра User по имени. wUser = wUserAccessor.userByUserName.get( pUser.getUserName() ); Иначе, для выборки пользовательского объекта без использования этих методов средств ( accessor methods ), этот код должен был бы выглядеть примерно так: PrimaryIndex<String, User> userByUserName; userByUserName = entityStore.getPrimaryIndex( String.class, User.class ); User wUser = userByUserName.get( Преимущество этого метода должны быть очевидны: код намного проще в первом случае. Этот подход проектирования надо рассматривать при комбинировании GWT и Berkeley DB Java Edition . Эволюция GWT и устойчивое решение Berkeley DB Java Edition DPL Любое решение для хранения объектов имеет свои плюсы и минусы. Это относится и к Berkeley DB Java Edition . Преимущества :
Недостатки :
Выводы Основное преимущество комбинирования GWT и Berkeley DB Java Edition - это простота. Оба продукта разработаны для легкого использования и ликвидации привычных и часто воспринимаемых как неизбежность перегрузок на всех стадиях разработки приложений. Web -приложения могут быть сложными по многим причинам. Разработчики должны выбирать из десятков различных комбинаций подходов проектирования и инструментов при создании своих Web -приложений. Но благодаря таким компаниям, как Google и Oracle , разработчики способны снизить сложность разработки Web -приложений до контролируемого уровня. Во многих случаях совместное применение EJB и ORM имеет смысл ради аспекта хранения (или Model ) Web -приложения, но в нашем особенном случае мы не требовали внешнего, через SQL доступа к нашим данным. Слой ORM и реляционная база данных нам не были нужны. Рассмотренный способ управления хранением данных, такой же эффективный и быстрый как реляционная СУБД, оказался более подходящим в других отношениях. Berkeley DB Java Edition - это устойчивое решение ( persistence layer ) в части уровня хранения объектов. Оно ликвидирует барьер ORM и решает ряд проблем:
Такие продукты, как: GWT , JavaServer Faces , Echo 2 и другие, недавно пополнили парадигму программирования для Web 2.0. Они возвращают быструю разработку приложений, имевшую место до наступления Web -эры. Эти продукты позволяют создавать профессиональные и масштабируемые Web -приложения. Хотя все эти продукты предлагают разную функциональность, общее, что есть у них, -возможность абстрагироваться от сложности синтаксиса на стороне клиента. Они обеспечивают эту возможность благодаря генерации и поддержке приложений на стороне клиента в среде браузера. Как реально сочетаются GWT и Berkeley DB Java Edition на практике? Как в случае с любой новой и обещающей идеей, люди сомневаются и ждут, чтобы им показали, как это работает на большем проекте. Berkeley DB Java Edition может быть новым явлением для хранения данных Web -приложений, эта СУБД за последние пять лет обрела зрелость и и справляется с хранением терабайт данных в задачах, которые вы можете даже не представлять себе. Web -разработчики должны подумать об изменении своего менталитета, о замене ORM на решение типа Berkeley DB Java Edition . Если Oracle Berkeley DB Java Edition работает на нас, то она сможет работать и на вас также. Эрик Одет ( Eric Audet ) , M . Sc ., TechSolCom , - 16 лет опыта работы в IT , главным образом, в качестве архитектора ПО и данных. В настоящее время он работает архитектором ПО для разработки транзакционных SOA -, беспроводных ( Wireless ) и Web -приложений с применением технологий WSDL , Java EE и Java ME . Грегори Бурд ( Gregory Burd ) - продукт-менеджер по СУБД корпорации Oracle - Berkeley DB , Berkeley DB Java Edition и Berkeley DB XML . Он работает в этой области с 2003 года и продолжает работать над продуктами Berkeley DB в рамках подразделения корпорации Oracle - Embeddable Databases Group . У Грэга большой опыт в проектировании ПО, управлении проектами, консультировании в области ПО масштаба предприятия, использования и продаж разного ПО. Он принимал участие в ряде проектов класса open source and free software projects . Ссылки по теме
|
|
|||||||