Kleines Beispiel zur Verwendung der Derby DB in Java 6

Thomas Darimont

Erfahrenes Mitglied
Hallo,

hier mal ein kleines Beispiel wie man in einer Java 6 Anwendung die mitgelieferte Derby Datenbank verwenden kann.

Damit das Beispiel läuft muss man das derby.jar in den Classpath legen:
C:\Programme\Java\jdk1.6.0\db\lib\derby.jar

Java:
/**
 * 
 */
package de.tutorials;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

/**
 * @author Tom
 */
public class DerbyEmbeddedDatabaseExample {

  /**
   * @param args
   */
  public static void main(String[] args) throws Exception {
    Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
    Properties properties = new Properties();
    properties.put("user", "user1");
    properties.put("password", "user1");
    Connection connection = DriverManager.getConnection("jdbc:derby:c:/TEMP/tutorialsDB;create=true", properties);

    createTableTestIfItDoesntExistYet(connection);
    populateTableTestIfItHasNotBeenPopulatedYet(connection);
    showContentsOfTableTest(connection);
    
    connection.close();
  }

  /**
   * @param connection
   * @throws SQLException
   */
  private static void showContentsOfTableTest(Connection connection) throws SQLException {
    Statement statement = connection.createStatement();
    ResultSet resultSet = statement.executeQuery("SELECT * FROM test");
    int columnCnt = resultSet.getMetaData().getColumnCount();
    boolean shouldCreateTable = true;
    while (resultSet.next() && shouldCreateTable) {
      for(int i = 1; i <= columnCnt;i++){
        System.out.print(resultSet.getString(i) +  " ");
      }
      System.out.println();
    }
    resultSet.close();
    statement.close();
  }

  private static void populateTableTestIfItHasNotBeenPopulatedYet(Connection connection) throws Exception {

    boolean shouldPopulateTable = true;
    Statement statement = connection.createStatement();
    ResultSet resultSet = statement.executeQuery("SELECT COUNT(*) FROM test");
    if (resultSet.next()) {
      shouldPopulateTable = resultSet.getInt(1) == 0;
    }
    resultSet.close();
    statement.close();

    if (shouldPopulateTable) {
      System.out.println("Populating Table test...");
      PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO test VALUES (?,?)");
      String[] data = { "AAA", "BBB", "CCC", "DDD", "EEE" };
      for (int i = 0; i < data.length; i++) {
        preparedStatement.setInt(1, i);
        preparedStatement.setString(2, data[i]);
        preparedStatement.execute();
      }
      preparedStatement.close();
    }
  }


  private static void createTableTestIfItDoesntExistYet(Connection connection) throws Exception {
    ResultSet resultSet = connection.getMetaData().getTables("%", "%", "%", new String[] { "TABLE" });
    int columnCnt = resultSet.getMetaData().getColumnCount();
    boolean shouldCreateTable = true;
    while (resultSet.next() && shouldCreateTable) {
      if (resultSet.getString("TABLE_NAME").equalsIgnoreCase("TEST")) {
        shouldCreateTable = false;
      }
    }
    resultSet.close();
    if (shouldCreateTable) {
      System.out.println("Creating Table test...");
      Statement statement = connection.createStatement();
      statement.execute("create table test (id int not null, data varchar(32))");
      statement.close();
    }
  }
}

Gruß Tom
 

jeipack

Erfahrenes Mitglied
Thx a lot.
Nimm ich gleich mal in meine Favoriten :)

Code:
connection.getMetaData().getTables("%", "%", "%", new String[] { "TABLE" });
Macht das das gleiche wie ein SHOW TABLES?
Ahja nach der Beschreibung können die ersten zwei Pattern (die ersten zwei "%") durch null ersetzt werden, so werden trozdem alle miteinbezogen, es wird aber nicht zuerst nach einer Übereinstimmung gesucht.

Gruss
 

Vatar

Erfahrenes Mitglied
Ich bevorzuge hierfür immer eine DataSource, da ich es persönlich etwas übersichtlicher finde.

Java:
public void startDatabase(String location)  {
	ds = new EmbeddedDataSource();
	ds.setCreateDatabase("create");
	ds.setDatabaseName(location); // location = "C:/Test/DB"
	try {
		ds.getConnection();
	} catch (SQLException e) {
		e.printStackTrace();
	}
}

public void stopDatabase(){
	ds.setShutdownDatabase("shutdown");
	try {
		ds.getConnection();
	} catch (SQLException e) {
		// SQLException wird immer geworfen, da nach dem Beenden keine Connection mehr
		// vorhanden ist. Designbedingte Exception
	}
}

Wer das ganze mal auf einem Handy/PDA laufen lassen will braucht das EmbeddedDataSource nur durch ein EmbeddedSimpleDataSource zu ersetzen.
 

flashray

Erfahrenes Mitglied
Hallo,

warum muss derby.jar runtergeladen und eingebunden werden, wenn es schon heißt es ist in das JDK6 eingegliedert?


Vg Erdal
 

thieste

Grünschnabel
Hallo,

das Beispiel funktioniert ja ganz gut aber.. das mit den properties user und password.. haut irgendwie nicht hin..

Wenn ich den Benutzer/Passwort ändere oder auch ganz weglasse.. wird trotzdem der Tabelleninhalt ausgeben.. sind password und user nicht genau dafür da.. dass das nicht passiert.. create=true habe ich nach dem ersten "Lauf" auf false gestellt.. damit nicht ne neue DB angelegt wird.
 

MusYa

Grünschnabel
hey,

mit dem Derby DB klappt es wunderbar bis auf die DELETE-Anweisung. Ich habe 2 Varianten schon durchprobiert, aber bei keinem von den 2 Varianten hat es klappen wollen. Kann mir jemand dabei weiterhelfen?

Code:
        Statement stmt = connection.createStatement();
        String sql = "DELETE FROM myTableName WHERE colName='a'";
        stmt.executeUpdate(sql);
        stmt.close();

und

Code:
        Statement stmt = connection.createStatement();
        String sql = "DELETE FROM myTableName WHERE colName=?";
        PreparedStatement pstmt = connection.prepareStatement(sql);
        pstmt.setString(1, "a");
        deleteCount = pstmt.executeUpdate();

Immer wieder bekomme ich denselben Fehler:
"java.sql.SQLSyntaxErrorException: Column 'A' is either not in any table in the FROM list or appears within a join specification and is outside the scope of the join specification or appears in a HAVING clause and is not in the GROUP BY list. If this is a CREATE or ALTER TABLE statement then 'A' is not a column in the target table."
 
Zuletzt bearbeitet:

MusYa

Grünschnabel
hey,

ich hab es hinbekommen. Ich musste nur noch clearParameters(); hinzufügen.

Code:
PreparedStatement pstmt = con.prepareStatement("DELETE FROM bilgi WHERE ColName = ?");
pstmt.clearParameters();
pstmt.setString(1, "a");
pstmt.executeUpdate();
pstmt.close();
 

takidoso

Erfahrenes Mitglied
Hallo,

warum muss derby.jar runtergeladen und eingebunden werden, wenn es schon heißt es ist in das JDK6 eingegliedert?
Vg Erdal

Ich wollte mich der Frage mal anschließen, da ich gerade mal versucht habe die jar Dateien zu finden, die ich in einer Java 6 Umgebung eigetnlich vermutet hätte.

Muss man derby tatsächlich nachinstallieren auch bei Java 6?
Wenn ja, was ist dann eigetnlich von Java 6 dann übernommen worden bezogen auf Derby?

mit nachbohrenden Grüßen

Takidoso