Arbeid med to baser samtidig

Ganske ofte er det situasjoner når du trenger å jobbe med to baser samtidig. For eksempel leser du data fra en database, behandler den og skriver den til en annen.

Eller enda mer vanlig. Applikasjonen din har én lokal database å jobbe med, og kan også lese data fra ulike eksterne kilder som støtter SQL-dataspørringsformatet. For eksempel Excel.

For disse eksterne datakildene kan det være svært nyttig å tilpasse Hibernate-kartleggingen slik at forretningslogikken til applikasjonen kan være enklere og bare fungere med Java-objekter.

Den enkleste måten å gjøre dette på er å ha flere konfigurasjonsfiler. For eksempel slik:

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>

Vel, all Hibernate-initieringskoden er faktisk bare duplisert:

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 i minnet

Det er DBMS, som er databaser som er fullstendig i minnet. Slike DBMS-er distribueres ofte enkelt som biblioteker og er enkle å inkludere i en typisk applikasjon. Slike DBMS er for eksempel H2 eller Hsqldb.

Du kan legge dem til prosjektet ditt på samme måte som alle andre biblioteker – ved å bruke en avhengighet i Maven:

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

Og umiddelbart et eksempel på den andre basen:

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

Du kan konfigurere arbeid med dem på samme måte som med vanlige databaser. Men la oss gi et par eksempler for enkelhets skyld:

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>

Hovedforskjellen mellom de to konfigurasjonene er 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>