Вступление
Платформа как услуга (PaaS) заботится об инфраструктуре, промежуточном программном обеспечении, конфигурации и других проблемах, связанных с платформой, от разработчиков и позволяет им сосредоточиться на своей ключевой компетенции, то есть на разработке и разработке своих доменных приложений. В этой статье я собираюсь продемонстрировать, как с минимальными усилиями создать «приложение Polyglot», включающее хранение и поиск данных в RDBMS и NoSQL.
Что такое приложение Polyglot?
В контексте приложений баз данных приложение полиглот включает в себя постоянство нескольких баз данных. Это несложно, когда задействованные бизнес-объекты хранятся в базах данных РСУБД. Все становится сложным, когда эти базы данных неоднородны по своей природе (например, сочетание различных NoSQL и, возможно, также RDBMS). Возьмем, к примеру, случай пользователей, у которых много адресов. Пользователь должен храниться в MongoDB, а адреса должны храниться в RDBMS.
(1-M) User ---------> Address (MongoDB) (MySQL)
Этот вид использования ставит некоторые действительно сложные задачи, такие как:
1. Кривая обучения
Базы данных NoSQL имеют свой собственный API (и есть клиенты высокого уровня). Они имеют длительную кривую обучения, и для их работы обычно требуются разработчики, которые уже имеют опыт работы с ними.
2. Сложность развития
Управление различными бизнес-объектами, которые будут сохранены в гетерогенных системах, представляет собой проблему при разработке на уровне доступа к данным. Ваш код будет использовать разные API, что затруднит разработку, тестирование и поддержку вашего кода.
3. Сложность развертывания
Различные базы данных NoSQL имеют свои собственные настройки, структуру и механизм развертывания. Они должны быть настроены для лучшей производительности и потребностей приложений. Самостоятельное управление этой разнообразной инфраструктурой является сложной задачей с точки зрения затрат и сложности. Поставщик решений должен тратить время на решение бизнес-задач наилучшим образом, а не на решение и борьбу с проблемами, которые ставят эти технологии.
Так что же нам делать?
Первые две из этих проблем могут быть решены с помощью Kundera в качестве библиотеки отображения объектного хранилища данных. Кундера поддерживает постоянство Полиглота и, как мы увидим, это почти не требует усилий для управления различными объектами для разных баз данных. Третья проблема решается с помощью провайдера PaaS. Ваш поставщик PaaS будет отвечать за управление базами данных, аппаратными ресурсами, серверами приложений и т. Д. При разработке приложения. OpenShift от RedHat — это платформа приложений в облаке, где разработчики приложений и команды могут создавать, тестировать, развертывать и запускать свои приложения. OpenShift предоставляет различные «картриджи», которые вы можете добавить в свое приложение в соответствии с вашими потребностями. MongoDB и MySQL среди них. Мы создадим приложение, которое читает и записывает бизнес-объекты в MySQL и MongoDB, используя Kundera.
Давайте готовьтесь
Теперь мы готовы построить наше приложение polyglot, включающее две сущности: User и Address. Пользователь будет храниться в MongoDB, а Адрес в MySQL. Вот шаги, которые вы должны выполнить:
1. Зарегистрируйтесь и войдите в OpenShift .2. Добавить Java-приложение на основе Tomcat 7 (картридж JBoss EWS 2.0) 3. Добавить картриджи — База данных MongoDB Nosql 2.2 и база данных MySQL 5.14. Напишите ваше приложение NoSQL. Вставьте свой код в Git-репозиторий, созданный в OpenShift. (Артефакты развертываются на серверах автоматически) .6. Протестируйте ваше приложение.
Регистрация и вход
1. Посетите веб-сайт https://www.openshift.com/ 2. Нажмите «Зарегистрироваться» и введите данные. Подтвердите и войдите.
Создать приложение
1. Нажмите Мои приложения -> Добавить приложение2. Выберите Java в раскрывающемся списке.3. Нажмите на Tomcat (JBoss EWS 2.0) 4. Дайте вашему приложению имя и нажмите «Создать приложение».
Добавить картриджи
1. Нажмите Мои приложения -> <Имя вашего приложения> 2. Нажмите «Добавить картридж» 3. Добавьте «MySQL Database 5.1 ″, добавляя этот картридж, запишите учетные данные аутентификации базы данных и имя схемы, лучше сделайте снимок экрана) 4. Повторите вышеуказанный шаг для добавления картриджа «База данных MongoDB NoSQL 2.2».
Написать приложение NoSQL
Мы покажем, как написать простое приложение для чтения и записи между хранилищами данных на MySQL и MongoDB.
1. Добавьте зависимости в pom.xml
Add Kundera repositories under repositories tag inside pom.xml:
<repository>
    <id>sonatype-nexus</id>
    <name>Kundera Public Repository</name>
    <url>https://oss.sonatype.org/content/repositories/releases</url>
    <releases>
        <enabled>true</enabled>
    </releases>
    <snapshots>
        <enabled>false</enabled>
    </snapshots>
</repository>
<repository>
    <id>kundera-missing</id>
    <name>Kundera Public Missing Resources Repository</name>
    <url>http://kundera.googlecode.com/svn/maven2/maven-missing-resources</url>
    <releases>
        <enabled>true</enabled>
    </releases>
    <snapshots>
        <enabled>true</enabled>
    </snapshots>
</repository>
Add following dependencies under dependencies tag inside pom.xml:
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.6</version> </dependency> <!-- Kundera Dependency --> <dependency> <groupId>com.impetus.client</groupId> <artifactId>kundera-rdbms</artifactId> <version>2.6</version> </dependency> <dependency> <groupId>com.impetus.core</groupId> <artifactId>kundera-core</artifactId> <version>2.6</version> </dependency> <dependency> <groupId>com.impetus.client</groupId> <artifactId>kundera-mongo</artifactId> <version>2.6</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> </dependency>
2. Напишите классы сущностей
User.java
import javax.persistence.CascadeType;
 
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;
 
@Entity
@Table(name = "User", schema = "PaaSMongo@mongo-openshift_pu")
public class User {
 @Id
 @Column(name = "ID")
 private int id;
 
@Column(name = "NAME")
 private String name;
 
@Column(name = "AGE")
 private int age;
 
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
 @JoinColumn(name = "ADDRESS_ID")
 private Address address;
 
//Getters and setters omitted
 
}
Address.java
import javax.persistence.Column;
 
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
 
@Entity
@Table(name = "ADDRESS", schema = "PaaSMongo")
public class Address
{
 @Id
 @Column(name = "ADDRESS_ID")
 private String addressId;
 
@Column(name = "STREET")
 private String street;
 
//Getters and setters omitted
 
}
3. Напишите persistence.xml
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence https://raw.github.com/impetus-opensource/Kundera/Kundera-2.0.4/kundera-core/src/test/resources/META-INF/persistence_2_0.xsd" version="2.0"> <!-- Persistence Units for Twitter application --> <persistence-unit name="mongo-openshift_pu"> <provider>com.impetus.kundera.KunderaPersistence</provider> <class>com.impetus.kundera.mongo.entities.User</class> <exclude-unlisted-classes>true</exclude-unlisted-classes> <properties> <property name="kundera.nodes" value="127.5.210.1" /> <property name="kundera.port" value="27017" /> <property name="kundera.keyspace" value="PaaSMongo" /> <property name="kundera.dialect" value="mongodb" /> <property name="kundera.client.lookup.class" value="com.impetus.client.mongodb.MongoDBClientFactory" /> <property name="kundera.cache.provider.class" value="com.impetus.kundera.cache.ehcache.EhCacheProvider" /> <property name="kundera.cache.config.resource" value="/ehcache-test.xml" /> <property name="kundera.username" value="admin" /> <property name="kundera.password" value="eaGbuGfS1ct4" /> </properties> </persistence-unit> <persistence-unit name="rdbms-openshift_pu"> <provider>com.impetus.kundera.KunderaPersistence</provider> <class>com.impetus.kundera.mongo.entities.Address</class> <exclude-unlisted-classes>true</exclude-unlisted-classes> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" /> <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" /> <property name="hibernate.connection.url" value="jdbc:mysql://127.5.210.1:3306/PaaSMongo" /> <property name="hibernate.connection.username" value="adminlRwnUcy" /> <property name="hibernate.connection.password" value="jvsq6w131Y1p" /> <property name="kundera.client.lookup.class" value="com.impetus.client.rdbms.RDBMSClientFactory" /> <property name="hibernate.show_sql" value="true" /> <property name="hibernate.format_sql" value="true" /> </properties> </persistence-unit> </persistence>
4. Напишите web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" metadata-complete="false"> <listener> <listener-class>com.impetus.kundera.mongo.listener.StartUpListener</listener-class> </listener> </web-app>
5. Напишите CRUD-операции
OperationHandler.java
import java.util.List;
 
import com.impetus.kundera.mongo.entities.User;
 
public interface OperationHandler
{
 
void saveUser(User user);
 
User findUserById(Class clazz, Object id);
 
List<User> findUserByName(String clazz, String name);
 
List<User> findUserByAge(String clazz, int age);
 
List<User> findAllUser(String clazz);
}
OperationHandlerImpl.java
import java.util.List;
 
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
 
import com.impetus.kundera.mongo.entities.User;
 
public class OperationHandlerImpl implements OperationHandler {
 
private EntityManagerFactory emf;
 
private EntityManager em;
 
@Override
 public void saveUser(User user) {
 getEntityManager();
 em.persist(user);
 }
 
@Override
 public User findUserById(Class clazz, Object id) {
 getEntityManager();
 return em.find(User.class, id);
 }
 
@Override
 public List<User> findUserByName(String clazz, String name) {
 
getEntityManager();
 Query q = em.createQuery("Select u from " + clazz + " u "
 + "where u.name = " + name);
 return q.getResultList();
 
}
 
@Override
 public List<User> findUserByAge(String clazz, int age) {
 getEntityManager();
 Query q = em.createQuery("Select u from " + clazz + " u "
 + "where u.age = " + age);
 return q.getResultList();
 }
 
@Override
 public List<User> findAllUser(String clazz) {
 getEntityManager();
 Query q = em.createQuery("Select u from " + clazz + " u ");
 return q.getResultList();
 }
 
private EntityManager getEntityManager() {
 
if (emf == null) {
 emf = Persistence
 .createEntityManagerFactory("mongo-openshift_pu,rdbms-openshift_pu");
 em = emf.createEntityManager();
 
} else if (em == null) {
 em = emf.createEntityManager();
 }
 return em;
 }
 
public void removeAll(String clazz) {
 getEntityManager();
 Query q = em.createQuery("Delete from " + clazz + " u ");
 }
 
public void close() {
 em.close();
 emf.close();
 }
 
public void clear() {
 em.clear();
 }
}
6. Создать Startup Listener
import javax.servlet.ServletContextEvent;</pre>
import javax.servlet.ServletContextListener;
 
import com.impetus.kundera.mongo.entities.Address;
import com.impetus.kundera.mongo.entities.User;
import com.impetus.kundera.mongo.handler.OperationHandlerForUser;
 
public class StartUpListener implements ServletContextListener {
 OperationHandlerForUser handler = null;
 int userId1;
 int userId2;
 
@Override
 public void contextDestroyed(ServletContextEvent arg0) {
 
 }
 
@Override
 public void contextInitialized(ServletContextEvent arg0) {
 handler = new OperationHandlerImpl();
 persist();
 find();
 }
 
private void persist() {
 Double d = Math.random();
 Long t1 = System.currentTimeMillis();
 Address address1 = new Address();
 address1.setAddressId(t1.toString());
 address1.setStreet("AAAAAAA");
 
Address address2 = new Address();
 address2.setAddressId(t1.toString() + "1");
 address2.setStreet("BBBBBBB");
 
User user1 = new User();
 userId1 = d.intValue();
 user1.setPersonId(d.intValue());
 user1.setPersonName("Kuldeep");
 user1.setAge(24);
 user1.setAddress(address1);
 
User user2 = new User();
 userId2 = d.intValue() + 1;
 user2.setPersonId(d.intValue() + 1);
 user2.setPersonName("Amresh");
 user2.setAge(30);
 user2.setAddress(address2);
 
handler.saveUser(user1);
 handler.saveUser(user2);
 handler.clear();
 
}
 
private void find() {
 User user1 = handler.findUserById(User.class, userId1);
 System.out.println(user1.getPersonName());
 System.out.println(user1.getAge());
 System.out.println(user1.getAddress().getAddressId());
 System.out.println(user1.getAddress().getStreet());
 
User user2 = handler.findUserById(User.class, userId2);
 System.out.println(user2.getPersonName());
 System.out.println(user2.getAge());
 System.out.println(user2.getAddress().getAddressId());
 System.out.println(user2.getAddress().getStreet());
 }
}
Push-код и тестовое приложение
1. Скопируйте ваши открытые ключи в операционной системе в Моя учетная запись -> Открытые ключи2. Клонируйте ваш репозиторий git.3. Зафиксируйте код и нажмите.4. Проверьте данные, записанные в базу данных с консоли MySQL и MongoDB, и проверьте вывод, напечатанный в журналах Tomcat.
Вывод
Как мы видим, Kundera + Openshift значительно облегчают разработку и развертывание. Все, что нам нужно, это несколько кликов на веб-странице Openshift и простая настройка в persistence.xml. На самом деле мы сосредоточились на написании сущностей и кода CRUD. Kundera также поддерживает доступ на основе REST для данных, хранящихся в нескольких хранилищах данных. Для этого необходимо добавить запись сервлета JAX-RS в дескриптор развертывания веб-приложения. Это открывает для вас новую возможность представить свои данные различным приложениям.


