Trabajando con dos bases al mismo tiempo

Muy a menudo hay situaciones en las que necesita trabajar con dos bases al mismo tiempo. Por ejemplo, lee datos de una base de datos, los procesa y los escribe en otra.

O incluso más común. Su aplicación tiene una base de datos local para trabajar y también puede leer datos de varias fuentes remotas que admiten el formato de consulta de datos SQL. Por ejemplo Excel.

Para estas fuentes de datos remotas, puede ser muy útil personalizar su mapeo de Hibernate para que la lógica comercial de la aplicación sea más simple y funcione solo con objetos Java.

La forma más sencilla de hacer esto es tener varios archivos de configuración. Por ejemplo, así:

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/codegym/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/codegym/hibernate/multipledatabase/employee.hbm.xml"/>
   </session-factory>
</hibernate-configuration>

Bueno, todo el código de inicialización de Hibernate en realidad está duplicado:

Configuration oracleCfg = new Configuration();
oracleCfg.configure("/com/codegym/hibernate/multipledatabase/hibernate_oracle.cfg.xml");
SessionFactory oracleSessionFactory = oracleCfg.buildSessionFactory();
Session oracleSession = oracleSessionFactory.openSession();

Configuration mysqlCfg = new Configuration();
mysqlCfg.configure("/com/codegym/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");

base en la memoria

Hay DBMS, que son bases de datos que están completamente en la memoria. Dichos DBMS a menudo se distribuyen simplemente como bibliotecas y son fáciles de incluir en una aplicación típica. Tales DBMS, por ejemplo, son H2 o Hsqldb.

Puede agregarlos a su proyecto de la misma manera que cualquier otra biblioteca, utilizando una dependencia en Maven:

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

E inmediatamente un ejemplo de la segunda base:

base de datos H2
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>2.1.214</version>
    <scope>test</scope>
</dependency>

Puede configurar el trabajo con ellos de la misma manera que con las bases de datos regulares. Pero vamos a dar un par de ejemplos por conveniencia:

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>

La diferencia clave entre las dos configuraciones es la conexión.url:

base de datos H2
<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>