HSQLDB Introductie

Introductie

HSQLDB staat voor Hypersonic SQL Database en is een lichtgewicht Java SQL database die veel wordt gebruikt voor testdoeleinden. Dat heeft te maken met het feit dat HQSLDB in-memory databases ondersteunt. Met HSQLDB kunnen eenvoudig Unit en Integratietests worden gemaakt zonder daarvoor een zware database omgeving nodig te hebben. Een Java applicatie kan runtime een test database aanmaken, gebruiken zonder dat lokale opslag en beheer inspanning nodig is.

Een database kan in-memory en file based worden gebruikt. Een database kan in embedded en server mode draaien. Als het embedded draait kan het alleen worden benaderd door het Java proces wat het aangemaakt heeft. Als het in server mode draait is het ook benaderbaar door andere processen. Om Server mode te kunnen gebruiken moet ook een HSQLDB Server worden opgestart. Er zijn 3 soorten servers: HSQL Server, HTTP Server en Servlet Server. De eerste is de meest gebruikte en maakt gebruik van HSQLDB specifieke toegangsprotocollen. HTTP Server maakt gebruik van http protocol. De Servlet Server maakt gebruik van een specifieke Servlet.

Server mode is met name handig als je gebruik wilt maken van de Database Manager utility om de database te kunnen manipuleren buiten de Java applicatie om. In sommige situaties is het echter niet handig om aparte database opstart acties te moeten uitvoeren. Zeker niet als er handmatige acties nodig zijn bij het opzetten van autonome unit tests.

Naast in memory en file based bestaat ook nog de variant Resource based, zoals in een jar file. Dit type is altijd read-only en wordt minder toegepast.

NB: HSQLDB werk in principe met hoofdletters. Alle tabel en kolom definities worden in hoofdletters opgezet. Dit is vergelijkbaar met databases zoals Oracle. Maar bijv. bij MySQL is dat niet het geval.

Database inrichting

Installatie

Installatie is eenvoudig toevoegen van de hsqldb.jar in het classpath. Dat kan in Eclipse bijv. door deze toe te voegen in het Build Path, of bij gebruik van Maven op te nemen in de pom.xml.
Voorbeeld van Maven dependency:

        <dependency>
        	<groupId>org.hsqldb</groupId>
        	<artifactId>hsqldb</artifactId>
        	<version>2.2.8</version>
        </dependency>

Database creatie en toegang

Een HSQLDB database wordt benaderd via een pad specificatie in een getConnection call.
Een HSQLDB database wordt automatisch gemaakt als deze nog niet aanwezig is. Tenzij met opties wordt aangegeven dat dit niet de bedoeling is.

De pad specificatie bestaat uit ondermeer de volgende mogelijkheden :

  • In memory :       jdbc:hsqldb:mem:databasenaam
  • File based:          jdbc:hsqldb:file:filepad/databasenaam
  • Server mode:     jdbc:hsqldb:hsql:serverurlpad/databasenaam

In Memory / Embedded database

In onderstaand voorbeeld de connectie en aanmaak voor in memory database “mydb”. De standaard user is “sa”, zonder wachtwoord.

Connection conn = DriverManager.getConnection("jdbc:hsqldb:mem:mydb","sa","");

File Based / Embedded database

In onderstaand voorbeeld de connectie en aanmaak voor een file database “mydb”. Deze bevindt zich in directory pad test\data (of test/data).

Connection conn = DriverManager.getConnection("jdbc:hsqldb:file:test.data.mydb","sa","");

Server database

In onderstaand voorbeeld de connectie en aanmaak voor een server database “mydb”. Deze bevindt zich in server url pad localhost. (Een database naam is niet echt nodig).

Connection conn = DriverManager.getConnection("jdbc:hsqldb:hsql://localhost/mydb","sa","");

Een server moet worden opgestart. Dit kan op verschillende manieren.

Serveropstart Commandline
In een terminal kan met volgend commando de server worden gestart:

java -cp ../lib/hsqldb.jar org.hsqldb.server.Server --database.0 file:mydb --dbname.0 mydb

Serveropstart Programmatisch
Met Java code kan een server worden aangemaakt en gestart. De Server class is org.hsqldb.server.Server.

        Server server = new Server();
        server.setAddress("localhost");
        server.setDatabaseName(0, "mydb");
        server.setDatabasePath(0, "file:c:/test/data");
        server.setPort(8088);
        server.start();

Server Opstart binnen Eclipse
Binnen Eclipse kan de server worden opgestart door de hsqldb.jar file binnen een project te selecteren en met context menu het commando “Run As Java Application” te geven. Dan wordt een dialoog geopend met de verschillende startbare applicaties binnen de jar, waaronder de org.hsqldb.server.Server.

Gebruik Database Manager

Met de Database manager kan een server mode database worden benaderd en gemanipuleerd.
Deze kan commandline of binnen Eclipse worden opgestart.

Commandline :

java -cp hsqldb.jar org.hsqldb.util.DatabaseManagerSwing

Binnen Eclipse:
Selecteer de hsqldb.jar file binnen een project en geef met context menu het commando “Run As Java Application”. Dan wordt een dialoog geopend met de verschillende startbare applicaties binnen de jar, waaronder de org.hsqldb.util.DatabaseManager. Daarna opent de Database Manager.

Als de Database Manager is gestart kan een connectie worden gemaakt. De verschillende mogelijkheden in-memory, filebased, server based worden netjes gepresenteerd.

Toepassing met JPA / Hibernate

Bij gebruik met JPA en bijv. Hibernate kan een database automatisch worden gemaakt via instellingen in het persistence.xml bestand en eventuele configuratie in de specifieke server omgeving.

Hieronder een voorbeeld van een persistence.xml die de gehele jdbc toegang specificeert:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" 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 http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
    <persistence-unit name="PU">
        <class>org.biz.model.Hond</class>
        <class>org.biz.Poes</class>
        <properties>
            <property name="hibernate.archive.autodetection" value="class, hbm"/>
            <property name="hibernate.show_sql" value="true"/>
            <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"/>
            <property name="hibernate.connection.password" value=""/>
            <property name="hibernate.connection.url" value="jdbc:hsqldb:mem:dierentuindb"/>
            <property name="hibernate.connection.username" value="sa"/>
            <property name="hibernate.hbm2ddl.auto" value="update"/>
            <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
            <property name="hibernate.c3p0.min_size" value="5"/>
            <property name="hibernate.c3p0.max_size" value="20"/>
            <property name="hibernate.c3p0.timeout" value="300"/>
            <property name="hibernate.c3p0.max_statements" value="50"/>
            <property name="hibernate.c3p0.idle_test_period" value="3000"/>
        </properties>
    </persistence-unit>
</persistence>

Hieronder een voorbeeld van een persistence.xml die gebruik maakt van een JNDI data resource referentie java:/mydb.

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0"
   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


http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">

   <persistence-unit name="primary" transaction-type="JTA">
      <jta-data-source>java:/mydb</jta-data-source>
      <class>org.biz.entities.Employee</class>
      <properties>
         <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
         <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
         <property name="hibernate.format_sql" value="false" />
         <property name="hibernate.show_sql" value="false" />
      </properties>
   </persistence-unit>
</persistence>

Via de Hibernate property “hibernate.hbm2ddl.auto” kan de database automatisch worden aangemaakt. Er hoeven dus geen schema’s, tabellen en overige zaken te worden aangemaakt voor bijv. een testsituatie. Met de property waarde “create-drop” worden tabellen elke keer opnieuw gemaakt. Met de waarde “update”worden alleen veranderingen doorgevoerd.

De JNDI data resource wordt gespecificeerd in de server omgeving. Bijv. voor JBoss in standalone.xml:

<datasource jta="true" jndi-name="java:/mydb" pool-name="mydb" enabled="true" use-java-context="true">
    <connection-url>jdbc:hsqldb:hsql://localhost</connection-url>
    <driver>hsqldb</driver>
    <transaction-isolation>TRANSACTION_READ_COMMITTED</transaction-isolation>
    <security>
        <user-name>sa</user-name>
    </security>
</datasource>

In bijv. een OpenEJB / TomEE server omgeving wordt de JNDI data resource gespecificeerd in het bestand openejb.xml:

<Resource id="mydb" type="DataSource">
  JdbcDriver org.hsqldb.jdbcDriver
  JdbcUrl jdbc:hsqldb:mem:employeedb
  UserName sa
  Password
  JtaManaged true
</Resource>

Toepassing met Spring

Hieronder een voorbeeld van de configuratie van een HSQLDB database in een Spring metagegevens configuratie bestand.

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
      p:driverClassName="org.hsqldb.jdbcDriver"
      p:url="jdbc:hsqldb:mem:mydb"
      p:username="sa" p:password="" />

Database gebruik

Het gebruik van de database hangt uiteraard af van het type applicatie en welke technologie daarin wordt toegepast. Ruwweg kan onderscheid worden gemaakt tussen gebruik van Object-Relationship-Mapping (ORM) frameworks zoals JPA, Hibernate en het gebruik van de native JDBC api.

Bij gebruik van JPA , Hibernate frameworks is de HSQLDB toepassing verder eigenlijk transparant. Hierna wordt het gebruik van native JDBC toegelicht. In combinatie met JPA / Hibernate kan de native JDBC toegang een rol spelen bij het maken en initiëren van test databases.

Hieronder een voorbeeld van het maken van de connectie met een in-memory database, het maken en uitvoeren van een SQL statement, en het uitlezen van de resultset met het resultaat.

try {
   Connection conn = DriverManager.getConnection("jdbc:hsqldb:mem:employeedb","sa","");
   Statement statement = conn.createStatement();
   PreparedStatement pst=conn.prepareStatement("SELECT * FROM department");
   pst.clearParameters();
   ResultSet rs=pst.executeQuery();
   while(rs.next()){
      System.out.println(rs.getString(1) + " / " +
                         rs.getString(2) + " / " + rs.getString(3) + " / " + rs.getString(4));
   }

   statement.close();
} catch (SQLException e) {
   e.printStackTrace();
}

Als er geen JPA / Hibernate wordt gebruikt waarbij de database tabellen automatisch worden gemaakt, dan kunnen deze via de JDBC api worden gemaakt, zoals in onderstaand voorbeeld.

statement.execute("create table department ("
				+ "departmentId integer generated always as identity, "
                			+ "address varchar(64), "
                			+ "budget integer, "
                			+ "name  varchar(64))");

statement.execute("alter table department add primary key (departmentId)");

statement.execute("INSERT INTO department (name,address,budget) VALUES ('Inkoop', 'Keizersgracht 100, Amsterdam', '1000')");
This entry was posted in Databases, Java, Testen and tagged . Bookmark the permalink.

Geef een reactie

Je e-mailadres wordt niet gepubliceerd.

De volgende HTML tags en attributen zijn toegestaan: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>