# mit .odb Datenbank verbinden



## kaoZ (30. Sep 2014)

Aloha, ich wollte nur mal fragen ob jemand Erfahrung damit hat mit einer (OpenOffice) .odb Datenbank zu verbinden.

(Ich finde es recht angehen in Base die Datenbank zu erstellen, deswegen wollte ich das mal versuchen, ich muss dazu sagen ich bin vollkommender Datenbank noob, da ich diese Art der Persistenten Speicherung bislang nicht genutzt habe, mich dort jetzt aber mal reinfuchsen möchte  )

Soweit ich das gelesen habe muss ich die .odb Datei anscheinend erst entpacken und und die dort enthaltenen Dateien umbenennen.

zudem muss ich anscheinend den richtigen Treiber laden (augenscheinlich hsqldb)

welchen ich aus der hsqldb.jar bekommen soll, wo genau finde ich diese jar ? diese scheint nicht mit in der standard lib zu sein , oder hab ich was übersehen ?!

wäre super falls jemand so gnädig sein könnte und mich mal fix aufklärt oder mir nen gutens Tutorial empfehlen kann.

Danke im Vorraus.:rtfm:


Hat jemand ggf. ein Beispiel oder ein Tutorial , viel mehr als die hinweise habe ich nämlich nicht wirklich gefunden.


----------



## Tobse (1. Okt 2014)

Ich habe das auch schon einmal probiert, es ist aber relativ sinnlos.  Und das aus folgenden Gründen:

- wenn im realen Einsatz programme wie OpenOffice Base oder M$ Access benutzt werden, dann nur in Verbindung mit einer richtigen Datenbank. Eine .ODB-Datei kann die Datenmengen, welche in größeren Unternehmen anfallen, nicht bewältigen; und das schon garnicht auf mehreren Systemen.

- Die Tabellen/Abfragen/Report Assistenten sind zwar schön zu benutzen, haben aber gegen richtig geschriebenes (und optimiertes) SQL keine chance.

Daher mein Rat: Beschäftige dich erstmal mit SQL an sich. Mit Tools wie phpMyAdmin oder der MySQL Workbench kann man sich da ziemlich einfach reinfinden. Wenn du dann erstmal SQL beherrschst (mit JOINS, GROUPS, Views, Stored Procedures und Relations umgehen kannst), kannst du praktisch jeden SQL Server (MySQL, MSSQL, OracleDB etc...) damit bedienen.

EDIT: P.S.: Mit XAMPP bekommst du einen MySQL-Server und einen Apache 2 mit phpMyAdmin vorinstalliert. Damit kannst du dann üben und später dann mit Java direkt die Verbindung zum MySQL-Server aufnehmen. Wenns um Java Web-Anwendungen geht, ist auch ein Tomcat mit dabei.


----------



## kaoZ (1. Okt 2014)

sowas ähnliches dachte ich mir bereits, mit phpMyAdmin habe ich früher bereits einmal gearbeitet ist aber auch schon jahre her,
was mich wirklich interessieren würde ist wie das ganze auch lokal realisieren kann ohne auf einen MySQL-Server zurückgreifen zu müssen , .odb wäre ja in dem Sinne nichts anderes als eine lokal angelegt Datenbank wenn ich mich nicht irre ?!

_Unter anderem würde ich eine Lokale lösung z.B für Stand-alone Applikation nutzen wollen, anstelle von bisher genutzen Möglichkeiten ( Serialisierung etc.....)_

Unter Verwendung von Android weiß ich das es die Möglichkeit gibt über SQLlite wohl eine Möglichkeit gibt das ganze Lokal zu lösen .

Wäre super wenn du irgendwas an vorschlägen hättest ( vergleichbares ).

die SQL Workbench habe ich mir schonmal angeschaut, da müsste ich mich allerdings erst reinfuchsen, anscheinend erstellt man einfach ein Model, welches dann die Tabellen enthält, hier ist soweit ich das sehen kann aber auch wieder ein Server notwendig wenn mich nicht alles täuscht.


----------



## kaoZ (1. Okt 2014)

Ich spiele gerade mit HSQLDB rum und versuche mich da hinein zu fuchsen , scheint zumindest augenscheinlich langsam zu klappen ich poste dann gleich mal ergebnisse insofern ich es zum laufen bekomme xD


----------



## kaoZ (1. Okt 2014)

Das scheint zumindest schonmal rudimentär zu funktionieren..... 


```
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;


public class DBConnect{
	
	
	public DBConnect(){}
	
	static void connect() throws ClassNotFoundException, SQLException{

//		treiber laden
//		Class.forName("org.hsqldb.jdbcDriver");
		
//		verbindungs eigenschaften + datenbank ort & name
		String user	 = "root";
		String pass	 = "";
		String url	 = "jdbc:hsqldb:file:";
		String db	 = "H:/Apps/Database/db;";
		
//		Verbindung hestellen
		Connection con = DriverManager.getConnection(url + db, user, pass);
		
//		befehl Objekt erstellen
		Statement stmt = con.createStatement();
		
//		Tabelle + Spalten erstellen
		String command = "CREATE TABLE User(ID Int, Name varchar(255))";
		ResultSet set = stmt.executeQuery(command);
		
//		Eintrag erstellen
		String e1 = "INSERT INTO User(ID,Name)" + "VALUES('1','Max')";
		String e2 = "INSERT INTO User(ID,Name)" + "VALUES('2','Peter')";
		stmt.executeUpdate(e1);
		stmt.executeUpdate(e2);
		
//		Eintrag auslesen
		String query = "SELECT ID,Name FROM User";
		set = stmt.executeQuery(query);
		
		while(set.next()){
			String id = set.getString(1);
			String name = set.getString(2);
			System.out.println(id + " " + name);
		}
		
		 set.close();
		 stmt.close();
	}

	public static void main(String[] args) throws ClassNotFoundException, SQLException, InstantiationException, IllegalAccessException{
		DBConnect.connect();
	}
}
```

In die ganze Geschichte mit dem Treiber und co muss ich mich allerdings wirklich erst einmal reinfuchsen , ohne Tutorial ging da nicht wirklich was ^^

Zusammenfassend kann man sagen 

 -Connection ( Stellt die verbindung zur Datenbank da)
 -Statement ( Befehlt der ausgeführt werden soll)
 - ResultSet (enthält die vom Statement ausgeführten ergebnisse)

mal grundlegend zu den SQL Befehlen 

 - CREATE
 - INSERT
 - DROP
 - UPDATE
 - SELECT

Wie schaut das ganze denn nun aus wenn ich bestimmte einträge in einer bestimmten Zeile / Spalte ändern, löschen oder hinzufügen will ?

EDIT :

Sehe ich das richtig das ich , insofern ich über den Drivermanager den treiber lade , das laden per Class.forName() weglassen kann ?


----------



## stg (1. Okt 2014)

kaoZ hat gesagt.:


> mal grundlegend zu den SQL Befehlen
> - CREATE
> - INSERT
> - DROP
> ...


Zielt deine Frage nun auf SQL-Grundlagen ab? Wenn ja, dann schau dir ein entsprechendes Einsteiger-Tutorial o.Ä. dazu an. 
Falls du Probleme mit der Umsetzung in Java haben solltest, dann formulier deine Frage noch einmal um, so dass klar wird, was genau das Problem ist...



> EDIT :
> Sehe ich das richtig das ich , insofern ich über den Drivermanager den treiber lade , das laden per Class.forName() weglassen kann ?



Ja, so ungefähr. Schau z.B. hier: http://www.onjava.com/2006/08/02/jjdbc-4-enhancements-in-java-se-6.html mal den Abschnitt "Auto-Loading of JDBC Driver" an


----------



## MR_UNIX (1. Okt 2014)

kaoZ hat gesagt.:


> mal grundlegend zu den SQL Befehlen
> 
> - CREATE
> - INSERT
> ...



Den Befehl zum Hinzufügen kennst du doch schon, du hast ihn zumindest schon aufgelistet: "INSERT INTO tabelle (spalte1, spalte2, ...) VALUES (wert1, wert2, ...);"
Ändern geht über "UPDATE tabelle SET spalte = wert" - hier sollte man noch eine WHERE-Clause anfügen, wenn man nicht alle Einträge in der Tabelle modifizieren will, bspw. ein "WHERE id = 2" anhängen, dann wird nur der Eintrag mit der ID 2 bearbeitet.
Löschen geht mit "DELETE FROM tabelle WHERE id = x" - wenn du hier die WHERE-Clause weglässt, ist die Tabelle anschließend leer. Natürlich kannst du fürs WHERE auch beliebige andere Bedingungen festlegen.

Hoffe, ich konnte helfen


----------



## Tobse (1. Okt 2014)

Zum Thema Lokale Datenbank: Wenn du vermeiden möchtest, einen SQL-Server laufen zu haben ist SQLite meiner meinung nach die Beste lösung. Da gibts auch libraries für alle möglichen Sprachen - 100%ig auch welche für Java.
Ob und wie du dich mit phpMyAdmin oder der Workbench auf eine SQLite Datenbank verbinden kannst, weiss ich nicht. Es sollte aber generell einfacher sein, als sich auf eine ODB-Datenbank zu verbinden.

Zum SQL-Thema:
Es gibt verschiedene Befehle, wie du schon erkannst hast. Einfügen, Auslesen, Löschen, Erneuern usw.... Es gibt natprlich auch befehle für die Tabellenstrukturen (bspw: CREATE, ALTER, DROP, TRUNCATE u.s.w).
Zu diesen Befehlen kann man dann Klauseln anhängen, z.B. um die betroffenen Daten einzushcränken (WHERE, ON, HAVING...), sie zu sortieren (ORDER BY, GROUP BY...) oder zu limitieren (LIMIT, etwa für Pagination) und natürlich sehr viele weitere. Auch kann man Tabellen miteinander verknüpfen (JOINs, UNIONs, Views u.s.w) aber das sprengt den Ramen dieses Threads total.
Das alles ist allgemeines SQL und hat mit der Konkoreten Datenbank-Implementierung nichts zu tun.
Ich selbst habe SQL über ein PHP-Buch und die MySQL-Dokumentation gelernt. Das Tutorial vom W3C ist sicher auch nicht schlecht.


----------



## kaoZ (1. Okt 2014)

Die SQL-Befehle sind an sich nicht das problem, ich glaube es scheitert eher noch an dem Verständniss bei folgender Situation,

Ich habe eine Stand-alone Anwendung, welche die Daten zzt. noch serialisiert speichert, und ich möchte dazu übergehen die Daten in einer (vorab erstellten) lokalen DB zu halten.

also HSQLDB find ich ziemlich angenehm , es läuft, Tabellen erstellen und Querys funktionieren, Commands bekommen ich auch hin,bleibt halt noch offen wie ich das ganze dann so hinbekomme, das die DB schon beim "Installieren" initialisiert wird, denn ohne das die DB existiert kann ich ja auch keine commands oder querys zur db senden ^^
bleibt noch offen wie ich es umsetzen kann

Zu den JOINTS (tabellen verknüpfen) , sehe ich das richtig das ich diese benötige wenn ich z.B Objekte abbilden möchte, da sonst ja innerhalb der tabelle dies ja nicht möglich wäre , ich meine da was von relationalem mapping gelesen zu haben.

was ich zzt. noch etwas strange finde ist das ich in dem Verzeichniss in dem die Db liegt, nur folgende dateien haben :





was mich irgendwie stutzig macht , da es den anschein hat das es halt nur temporäre dateien sind ^^


----------



## stg (1. Okt 2014)

JOINTS sind noch mal was ganz anderes :smoke:

Deinen Satz hierzu verstehe ich trotzdem nicht..  JOINS und ORM haben jedenfalls nicht direkt etwas miteinander zu tun.


----------



## kaoZ (1. Okt 2014)

Was so ein einzelnes T doch ausmacht 

Ich belese mich gerade zu den einzelnen Befehlen , das mit den JOIN hatte ich falsch verstanden,

angenommen ich habe keinen Primitiven Datentyp sondern ein Objekt welches ich in der Datenbank speichern möchte , 

wie würde ich a) die Datenbank anlegen müssen und b) wie würde z.B der befehl aussehen um ein Objekt zu speichern / in der DB abzubilden ( mapping ) ?

Wäre super wenn du mir da ggf. ein Beispiel geben könntest, wie man z.B ein Objekt mit dessen Attributen ohne verwendung eines Frameworks in einer DB storen kann.

Vielleicht habe ich es nicht richtig formuliert, mich würde interessieren wie man z.B bei einer Stand alone Anwendung , welche die Daten in einer DB speichern soll, die Datenbank anlegt, da diese ja auf dem Zielsystem nicht im normalfall nicht existiert.




> _Im einfachsten Fall werden Klassen auf Tabellen abgebildet, jedes Objekt entspricht einer Tabellenzeile und für jedes Attribut wird eine Tabellenspalte reserviert. Die Identität eines Objekts entspricht dem Primärschlüssel der Tabelle. Hat ein Objekt eine Referenz auf ein anderes Objekt, so kann diese mit einer Fremdschlüssel-Primärschlüssel-Beziehung in der Datenbank dargestellt werden._


Bei einer Vererbungshierarchie müssen ja die Tabellen irgendwie zusammenhängen, um Objekte später aus der DB wieder herzustellen, oder liege ich da nun irgendwie daneben ?

Da muss ich mich dann wohl erstmal stück für stück reinfuchsen ^^


----------



## Tobse (1. Okt 2014)

Zu deinem ersten Problem: Wo ist denn das problem bei der Installation ein CREATE DATABASE auszuführen?

Zum ORM Thema: Kleines Beispiel:


```
class Cat extends ORMObject
{
    public String name;
    public int age;
}

Cat mieze = new Cat();
mieze.name = "Mieze-Katze";
mieze.age = 2;
mieze.save();

Cat mieze = Cat::findByName("Mieze-Katze");

/*
Ob die Eigenschaften jetzt public/protected/private sind, ist egal. Hauptsache ORMObject kann sie per Refelction sehen, denn ORMObject handelt das daten ein- und auslesen.
*/
```


```
Tabelle cats
id                  | name         | age
INT, AUTO_INCREMENT | VARCHAR(255) | INT(3)
--------------------+--------------+---------
                  1 | Mieze-Katze  | 3
--------------------+--------------+---------
```

Wenn jetzt so ein Object nicht nur primitive Datentypen enthält sondern auch andere Objekte referenziert, müssen diese ebenfalls von ORMObject erben.

```
class Cat extends ORMObject
{
    protected CatFood food;
}
class CatFood extends ORMObject { ... }
```


```
Tabelle cats
id                  | name         | age      | food
INT, AUTO_INCREMENT | VARCHAR(255) | INT(3)   | INT(10)
--------------------+--------------+----------+---------
                  1 | Mieze-Katze  | 3        | 1
--------------------+--------------+----------+---------

Tabelle cat_foods
id                  | amount
INT, AUTO_INCREMENT | INT(3)
--------------------+--------
                  1 | 15
--------------------+--------
```

Ich weiss, das ist ein schlechtes beispiel. Aber ich denke zum Verständis reichts. Das selbst zu implementieren setzt aber schon fortgeschrittene SQL-kenntnisse vorraus (One-To-One, One-To-Many, Many-To-Many, Contraints (Foreign Keys etc...)). Es gibt für Java etliche, fertige ORM Bibliotheken die dir das abnehmen.


----------



## kaoZ (1. Okt 2014)

Ich vermute eine davon wäre dann Hibernate ?!

CREATE DATABASE ....... da hätte ich auch drauf kommen können xD

hatte vorher nur CREATE TABLE gesehen ....:lol:


----------



## stg (2. Okt 2014)

Allererste (ganz grobe) Faustregel:

Pro Klasse eine Tabelle in der Datenbank.
Eine Instanz einer Klasse entspricht dann schlicht einer Zeile in der entsprechenden Tabelle in der DB.

Um Vererbung solltest du dich später kümmern. Hierzu gibt es einige konzeptuell verschiedene Ansätze, wie soetwas umgesetzt werden kann.

Interessanter und wichtiger ist zunächst die Frage, wie die Beziehungen unter den Klassen nun dargestellt werden. Wenn du das nicht alles von Hand machen willst (und das willst du nicht!), dann solltest du dich mit der JPA auseinander setzen. Siehe z.B. hier: Introduction to the Java Persistence API - The Java EE 6 Tutorial


----------



## kaoZ (2. Okt 2014)

Ich versuche gerade mal das mit dem erstellen der Datenbank zu realisieren:


```
public class DBConnect{
	
	Statement statement;
	Connection connection;
	
	public DBConnect() throws SQLException{
		String user = "root";
		String pass = "";
		String url = "jdbc:hsqldb:file:H:/Apps/";
		
		connection = DriverManager.getConnection(url, user, pass);
		
		statement = connection.createStatement();
		
		String command = "CREATE DATABASE db";
		
		int i = statement.executeUpdate(command);
		System.out.println(i);
	}

	public static void main(String[] args) throws ClassNotFoundException, SQLException, InstantiationException, IllegalAccessException{
		new DBConnect();
	}
}
```

bekomme aber immer eine SQL Exception 



> Exception in thread "main" java.sql.SQLSyntaxErrorException: unexpected token: DATABASE



dabei habe ich mich an einem Artikel von Stackoverflow orientiert.

Create SQL DB in Java

oder funktioniert das bei lokal angelegten Datenbanken nicht ?


----------



## Tobse (2. Okt 2014)

Ja, Hibernate ist eine davon.

Wegen dem CREATE DATABASE: Ich weiss nicht, warum du 
	
	
	
	





```
executeUpdate
```
 benutzt um ein CREATE auszuführen, versuchs mal mit executeStatement oder sowas.
Falls das auch nicht zieht - was spricht dagegen, die Datenbank roh anzulegen und bei der installation einfach nur zu kopieren?


----------



## kaoZ (2. Okt 2014)

> Wegen dem CREATE DATABASE: Ich weiss nicht, warum du
> 
> 
> 
> ...



In dem von mir geposteten Link wird unter verwendung des executeUpdate() Befehles die Datenbank angelegt, ich hatte es bereits nur mit execute() versucht, allerdings führte dies zum gleichen Ergebnis.



> was spricht dagegen, die Datenbank roh anzulegen und bei der installation einfach nur zu kopieren?



Du meinst schon beider Entwicklung die DB anzulegen?

Da mein alter Herr (welcher die Software nutzen soll) die Applikation selbstständig "Installieren" können soll, und ich nicht vorhatte ihm zu zeigen wie er selbst eine DB einrichtet.

Die Frage die sich mir stellt ist nun wenn der CREATE DATABASE Befehl nicht greift, wie kann ich gewährleisten das während der Installation eine DB erzeugt wird? oder kann ich eine schon angelegte Datebank im Build-Path hinterlegen, die dann entweder genutzt, oder wie du sagtest dann an den Rootpfad der Anwendung, der während der installaion gewählt wird kopiert wird.


----------



## kaoZ (2. Okt 2014)

> When a server instance is started, or when a connection is made to an in-process database, a new, empty database is created if no database exists at the given path.



ein CREATE DATABASE Command ist unnötig, da wie ich nun gelesen habe die Datenbank bereits beim erstellen der Connection angelegt wird. ( HSQLDB )

ich kann dann einfach CREATE TABLE Table, aufrufen 

Testweise hab ich das so versucht und es klappt:

db.ini

```
url		 = jdbc:hsqldb:file:
db		 = H:/Apps/Database
```

und die DBInit.java

```
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;


public class DBInit{

	private static String PATH = "db.ini";
	private Properties props;
	
	public DBInit(){
		loadProperties();
		initialise();
	}
	
	private void loadProperties(){
		props = new Properties();
		try {
			props.load(getClass().getResourceAsStream(PATH));
		}
		catch (IOException e) {
			return;
		}
	}
	
	private void initialise(){
		String url = props.getProperty("url");
		String db = props.getProperty("db");
		
		try {
			Connection con = DriverManager.getConnection(url + db, "root","");
			Statement statement = con.createStatement();
			
			statement.execute("CREATE TABLE USER (ID Int, USER varchar(255))");
			statement.executeUpdate("INSERT INTO USER(ID, USER)" + "VALUES('1','Musermann')");
			
			ResultSet set = statement.executeQuery("SELECT * FROM USER");
			
			while(set.next()){
				String id = set.getString(1);
				String name = set.getString(2);
				System.out.println(id + " " + name);
			}
			
		}
		catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args){
		new DBInit();
	}
}
```

Vielen Dank nochmal für deine Hilfe


----------



## Tobse (2. Okt 2014)

Ich meinte, die dateien im Datenbankpfad so wie sie sind, zu kopieren. Aber offentlichtlich hat sich das erledigt.

Um noch ein bisschen best practice anzubringen: Schreibe Queries nie direkt in den Code. Das wird bei größeren Anwendungen unübersichtlich und nervig.
Ich lagere queries meist in zentralen, eigens dafür angelegten Dateien. Das kann entweder eine Java-Klasse alá

```
class QuerySotrage {
    public static PreparedStatement getQuery(String identifier);
}
```

sein, oder aber (so wie es bei mir in der Firma erledigt wird) eine XML, bspw.:

```
<db>
    <section name="customers">
        <query name="get-zipcode-by-id">SELECT zipcode FROM customer_addresses INNER JOIN customers ON customers.id = ? LIMIT 1</query>
    </section>
</db>
```
Und dann im Code soetwas wie 
	
	
	
	





```
int zipcode = Query.run("customers.get-zipcode-by-id", new Object[]{ customerID });
```
Oder eben per ORM auf eine View, etc...


----------



## kaoZ (2. Okt 2014)

Die query hatte ich nur zum testen im Code, aber danke für die Tips, wenn man den dreh erstmal raus hat isses Garnicht so schwer, lediglich die Wahl des Treibers und das erstellen der db hatte mich anfänglich verwirrt


----------

