Работа с двумя базами одновременно

Довольно часто возникают ситуации, когда тебе нужно работать с двумя базами одновременно. Например, ты читаешь данные из одной базы, обрабатываешь их и пишешь в другую.

Или же еще более частый вариант. Твое приложение имеет одну локальную базу данных для работы, а также может читать данные из различных удаленных источников, которые поддерживают SQL-формат запроса данных. Например, Excel.

Для этих удаленных источников данных бывает очень полезно настроить свой Hibernate-маппинг, чтобы бизнес-логика приложения могла быть проще и работать только с Java-объектами.

Самый простой способ это сделать — иметь несколько файлов конфигураций. Например, так:

hibernate_oracle.cfg.xml
<hibernate-configuration>
   <session-factory>
      <property name="hibernate.dialect">org.hibernate.dialect.OracleDialect</property>
      <property name="hibernate.connection.driver_class">oracle.jdbc.OracleDriver</property>
      <property name="hibernate.connection.url">jdbc:oracle:thin:@localhost:1521:xe</property>
      <property name="hibernate.connection.username">system</property>
      <property name="hibernate.connection.password">secret<property>
 
      <mapping resource="com/javarush/hibernate/multipledatabase/employee.hbm.xml"/>
   </session-factory>
</hibernate-configuration>
hibernate_mysql.cfg.xml
<hibernate-configuration>
   <session-factory>
      <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
      <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
      <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/employee</property>
      <property name="hibernate.connection.username">root</property>
      <property name="hibernate.connection.password">secret</property>
 
      <mapping resource="com/javarush/hibernate/multipledatabase/employee.hbm.xml"/>
   </session-factory>
</hibernate-configuration>

Ну и весь код инициализации Hibernate фактически просто дублируется:


   Configuration oracleCfg = new Configuration();
   oracleCfg.configure("/com/javarush/hibernate/multipledatabase/hibernate_oracle.cfg.xml");
   SessionFactory oracleSessionFactory = oracleCfg.buildSessionFactory();
   Session oracleSession = oracleSessionFactory.openSession();
 
   Configuration mysqlCfg = new Configuration();
   mysqlCfg.configure("/com/javarush/hibernate/multipledatabase/hibernate_mysql.cfg.xml");
   SessionFactory mySqlSessionFactory = mysqlCfg.buildSessionFactory();
   Session mysqlSession = mySqlSessionFactory.openSession();
                                        	
   Employee emp = oracleSession.get(Employee.class, "E0087");
   System.out.println("Employee retrived from Oracle Database");
                          	
   Transaction tx = mysqlSession.beginTransaction();
   mysqlSession.save(emp);
   tx.commit();
   System.out.println("Employee inserted in MySQL Database");

База в памяти

Существуют СУБД, которые представляют собой базы данных, полностью размещенные в памяти. Такие СУБД часто распространяются просто в виде библиотек и их легко включить в обычное приложение. Такими СУБД, например, являются H2 или Hsqldb.

Добавить их в свой проект можно так же, как и любые другие библиотеки — с помощью зависимости в Maven:

Hsqldb
<dependency>
    <groupId>org.hsqldb</groupId>
    <artifactId>hsqldb</artifactId>
    <version>2.6.1</version>
	<scope>test</scope>
</dependency>

И сразу пример второй базы:

H2 database
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>2.1.214</version>
    <scope>test</scope>
</dependency>

Конфигурировать работу с ними можно так же, как с обычными базами. Но давай для удобства приведем пару примеров:

Hsqldb
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">org.hsqldb.jdbc.JDBCDriver</property>
        <property name="hibernate.connection.url">jdbc:hsqldb:mem:test</property>
        <property name="hibernate.connection.username">sa</property>
        <property name="hibernate.connection.password"></property>
        <property name="hibernate.dialect">org.hibernate.dialect.HSQLDialect</property>
        <property name="hibernate.show_sql">true</property>
        <property name="hibernate.format_sql">true</property>
        <property name="hibernate.hbm2ddl.auto">create-drop</property>
        <property name="hibernate.current_session_context_class">thread</property>
    </session-factory>
</hibernate-configuration>

Ключевое отличие двух конфигураций — это connection.url:

H2 database
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">org.h2.Driver</property>
        <property name="hibernate.connection.url">jdbc:h2:mem:test</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password"></property>
        <property name="hibernate.dialect">org.hibernate.dialect.H2Dialect</property>
        <property name="hibernate.show_sql">true</property>
        <property name="hibernate.format_sql">true</property>
	    <property name="hibernate.hbm2ddl.auto">create-drop</property>
        <property name="hibernate.current_session_context_class">thread</property>
    </session-factory>
</hibernate-configuration>