Internet Fanclub roteteufel.de

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

Ausführbares Programm mit Datenbank erstellen

fck_lunae

Well-Known Member
Hallihallo!



Vielleicht hat ja jemand eine Ahnung..



Im Rahmen eines Schulprojektes gilt es, einen Geschäftsprozess durch die Programmierung eines Java-Programms mit einer Datenbankanbindung zu optimieren.



Wir benutzen eine MySQL-Datenbank und benutzen Xampp, um diese zu starten.



Unsere Frage ist nun: Wie erstellen wir ein Setup oder eine .exe (.jar) von unserem Programm, in dem die Datenbank mehr oder minder direkt mit drin steckt, damit der Benutzer nur dieses Setup/nur diese .exe (.jar) ausführen muss und nicht noch irgendwas anderes installieren muss??



Über eine (recht schnelle) Antwort wäre ich (auch stellvertretend für meine Gruppenmitglieder) sehr sehr dankbar!



LG

lunae
 
Wenn Du eclipse verwendest dann google mal nach fatjar



edit: Ihr könnt auch manuell ein jar-File erstellen welche alle libs enthält, aber mit fatjar geht das halt automatisch. Dann kann man die Anwendung mit java -jar anwendung.jar starten



edit2: vielleicht sollte ich erst richtig lesen. Die Datenbank steckt dann nicht direkt mit drin, sondern nur der JDBC-Treiber. Wenn man alles zusammen haben möchte dann kann man HSQLDB einsetzen. Das ist eine embedded Java DB.
 
Okay, klingt gut!
default_smile.png


Aber wie ist das mit der Datenbank? Die ist ja aktuell noch lokal auf meinem Rechner installiert. Wie mach ich das denn?
default_icon_redface.gif




Ach, und wenn du gerade mal da bist...
default_icon_cool.gif




Wir haben einen Lösungsansatz von unserem Ausbilder bekommen, bekommen ihn aber leider nicht mehr zu Gesicht, bevor das Programm fertig sein muss (widere Umstände mit der Firma..
default_icon_rolleyes.gif
):



Wir sollen eine zweidimensionale Object-Array dynamisch erweitern, indem wir den Variablennamen dynamisch ändern.

Äh ja.. Wie gehtn das?
default_laugh.png
 
Wir ehrlich gesagt auch nicht so wirklich.
default_icon_redface.gif




Vielleicht schildere ich unser Problem etwas genauer, eventuell hast du ja eine einfache(re) Lösung für uns. (Wenn des klappt, geb ich dir mal ein Bier aus!
default_wink.png
)



Also, wir haben verschiedene Datenbanktabellen, deren Inhalt wir in eine JTable mit eigenem TableModel auslesen wollen.

In der Tabelle sollen also auch nur so viele Zeilen dargestellt werden, wie Einträge in der Datenbank vorhanden sind.



Die Darstellung der ersten Zeile mit den in der Datenbank eingetragenen Daten klappt einwandfrei, aber alle folgenden Zeilen werden nicht erstellt. Ich schreib mal den Code dazu, muss aber sagen, dass er noch nicht kommentiert ist... Hoffe, du kannst dank deiner Erfahrung rauslesen, was wir da machen.
default_wink.png





package Artikelarchiv;



import java.sql.ResultSet;

import java.sql.SQLException;



import javax.swing.table.AbstractTableModel;



/**

*

* @author Markus Riepe, Robert Viehmann

*

*/



public class MyTableModel extends AbstractTableModel {



static Datenbank db = new Datenbank();

String[] coulums = "Titel, Quelle, Erscheinungsdatum".split(", ");

String[] table = "autor, schlagwort".split(", ");

String sTmp = "";

String sql = "";

ResultSet rs = null;



/**

* Wird doch gar nicht benötigt?! Montag klären!!!!!!

* @param args

*/

public static void main(String[] args) {

}



private String[] createRow() {

String tmpAutor = "";

String tmpTitel = "";

String tmpQuelle = "";

String tmpSchlagworte = "";

String tmpErscheinungsdatum = "";

String werte = "";

String[] werteArray = null;

String tmp = "";

String[] idArtikel = "".split(", ");

/*

* Liest die IDs aller Datensätze der Tabelle und speichert sie in einer array

*/

ResultSet tmpRs;

try {

tmpRs = db.select("SELECT ID FROM artikel");

while (tmpRs.next()) {

tmp += tmpRs.getInt("ID") + ",";

}

idArtikel = tmp.split(",");

} catch (SQLException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}



for (int i = 0; i < 1; i++) {

try {



for (int j = 0; j < table.length; j++) {

sTmp = "";

sql = "SELECT Name FROM artikel_" + table[j] + " INNER JOIN " + table[j]

+ " ON (" + table[j] + ".ID=artikel_" + table[j] + "." + table[j]

+ "_ID) WHERE artikel_" + table[j] + ".artikel_ID=" + idArtikel;

rs = db.select(sql);




while (rs.next()) {


if (rs.getRow() != 1)


sTmp += ", ";


sTmp += rs.getString("Name");


}




if (table[j].equals("autor"))


tmpAutor = sTmp;


else if (table[j].equals("schlagwort"))


tmpSchlagworte = sTmp;




}




for (int j = 0; j < coulums.length; j++) {




sql = "SELECT " + coulums[j] + " FROM artikel WHERE ID=" + idArtikel
<em>;</em>
<em>
</em>
<em>
rs = db.select(sql);
</em>
<em>
while (rs.next()){
</em>
<em>
if (coulums[j].equals("Titel")) {
</em>
<em>
tmpTitel = rs.getString(coulums[j]);
</em>
<em>
} else if (coulums[j].equals("Quelle")) {
</em>
<em>
tmpQuelle = rs.getString(coulums[j]);
</em>
<em>
} else if (coulums[j].equals("Erscheinungsdatum")) {
</em>
<em>
tmpErscheinungsdatum = rs.getString(coulums[j]);
</em>
<em>
}
</em>
<em>
}
</em>
<em>
}
</em>
<em>
</em>
<em>
} catch (SQLException e1) {
</em>
<em>
// TODO Auto-generated catch block
</em>
<em>
e1.printStackTrace();
</em>
<em>
}
</em>
<em>
</em>
<em>
werte = idArtikel
</em><em><em> + ";:;" + tmpAutor + ";:;" + tmpTitel + ";:;" + tmpQuelle</em></em>
<em><em>
+ ";:;" + tmpSchlagworte + ";:;" + tmpErscheinungsdatum;
</em></em>
<em><em>
}
</em></em>
<em><em>
werteArray = werte.split(";:;");
</em></em>
<em><em>
</em></em>
<em><em>
</em></em>
<em><em>
return werteArray;
</em></em>
<em><em>
}
</em></em>
<em><em>
</em></em>
<em><em>
// Eine Variable vom Typ String[], der wir die Namen der Spaltenköpfe mitgeben.
</em></em>
<em><em>
private String[] columnNames = { "ID", "Autor(en)", "Titel", "Quelle", "Schlagwort(e)",
</em></em>
<em><em>
"Erscheinungsdatum" };
</em></em>
<em><em>
</em></em>
<em><em>
// Eine Variable vom Typ Objec[] [], in der wir die Zeilen erstellen.
</em></em>
<em><em>
private Object[][] data = { {createRow()[0], createRow()[1], createRow()[2], createRow()[3], createRow()[4], createRow()[5]}};
</em></em>
<em><em>
</em></em>
<em><em>
/**
</em></em>
<em><em>
* In dieser Methode lesen wir die Anzahl der Spalten aus.
</em></em>
<em><em>
*/
</em></em>
<em><em>
public int getColumnCount() {
</em></em>
<em><em>
return columnNames.length;
</em></em>
<em><em>
}
</em></em>
<em><em>
</em></em>
<em><em>
/**
</em></em>
<em><em>
* In dieser Methode lesen wir die Anzahl der Zeilen aus.
</em></em>
<em><em>
*/
</em></em>
<em><em>
public int getRowCount() {
</em></em>
<em><em>
return data.length;
</em></em>
<em><em>
}
</em></em>
<em><em>
</em></em>
<em><em>
/**
</em></em>
<em><em>
* In dieser Methode lesen wir die Spaltennamen aus.
</em></em>
<em><em>
*/
</em></em>
<em><em>
public String getColumnName(int col) {
</em></em>
<em><em>
return columnNames[col];
</em></em>
<em><em>
}
</em></em>
<em><em>
</em></em>
<em><em>
/**
</em></em>
<em><em>
* In dieser Methode lesen wir den Wert einer Zelle aus.
</em></em>
<em><em>
*/
</em></em>
<em><em>
public Object getValueAt(int row, int col) {
</em></em>
<em><em>
return data[row][col];
</em></em>
<em><em>
}
</em></em>
<em><em>
</em></em>
<em><em>
/**
</em></em>
<em><em>
* In dieser Methode legen wir fest, ob eine Zelle editierbar ist oder nicht.
</em></em>
<em><em>
*/
</em></em>
<em><em>
public boolean isCellEditable(int row, int col) {
</em></em>
<em><em>
if (col == 0) {
</em></em>
<em><em>
return false;
</em></em>
<em><em>
} else {
</em></em>
<em><em>
return false;
</em></em>
<em><em>
}
</em></em>
<em><em>
}
</em></em>
<em><em>
</em></em>
<em><em>
/**
</em></em>
<em><em>
* In dieser Methode legen wir fest, dass die Tabelle neu dargestellt werden soll,
</em></em>
<em><em>
* wenn eine Zeile ausgewählt wurde.
</em></em>
<em><em>
*/
</em></em>
<em><em>
public void setValueAt(Object value, int row, int col) {
</em></em>
<em><em>
data[row][col] = value;
</em></em>
<em><em>
fireTableCellUpdated(row, col);
</em></em>
<em><em>
}
</em></em>
<em><em>
}
</em></em>
<em><em>
</em></em>
 
Jesses, macht Ihr Sachen
default_smile.png
Könnt Ihr nicht ein ArrayList oder eine LinkedList verwenden? Und ein Select mit 2 joins reicht doch vollkommen aus. Wieso für jede Column eine Abfrage?



Im Internet gibt es tausende Beispiele wie man ein AbstractTableModel von einem resultset füllt. Da würde ich mal etwas abschreiben
default_wink.png
 
Dankeschön, dann schauen wir uns das nochmal genauer an!



Und wie funktioniert das mit der Datenbank? Wie gesagt, die ist bei mir lokal installiert (geb die Logindaten im Code mit), aber die soll ja später dann mit der .jar ausgeführt werden..

So viele Fragen und wir können unseren Ausbilder nicht mehr sehen..
default_icon_sad.gif
 
Und wie funktioniert das mit der Datenbank? Wie gesagt, die ist bei mir lokal installiert (geb die Logindaten im Code mit), aber die soll ja später dann mit der .jar ausgeführt werden..


Du meinst also der Ausbilder soll keine mysql installiert haben? Das geht mMn nicht. Oder meinst Du er hat mysql installiert und Eure Anwendung soll automatisch das DB-Schema anlegen. Das geht natürlich.



Wenn die Anwendung wirklich ohne jegliche Installation funktionieren soll, dann nutzt HSQLDB. Hier wird kein Setup benötigt, nur ein jar-File. Die DB wird dann automatisch beim 1. Start des Programms angelegt.
 
Ne, unser Ausbilder sollte uns eigentlich dabei helfen, aber da kommen wir wohl nicht mehr hin, bis Deadline ist (wohl nächsten Dienstag), weils da Probleme seitens der Personalabteilung gibt..



Das Programm erstellen wir für Klinge und ja, es soll eigentlich ohne jegliche Installation funktionieren. Aber was ist denn nun HSQLDB? Eine ganz andere Datenbank? Dafür, eine neue Datenbank anzulegen, haben wir nun keine Zeit mehr..
default_icon_sad.gif




Das heißt, Klinge müsste MySQL installieren (reicht da auch Xampp?)?

Wenn ja - wie klappt das dann mit dem Anlegen des DB-Schemas?



Sorry für die vielen Fragen!
 
am einfachsten installiert er nur mysql. Von xampp benötigt er ja nur die DB



Und dann kannst Du das Schema bei Dir mit mysqldump exportieren. Am besten auch googlen. Ist alles sehr gut beschrieben.
 
Vielen vielen lieben Dank!

Wenn das jetzt noch alles so klappt wie beschrieben, fällt mir ein großer Brocken vom Herzen..!



Fehlen nur noch die Handbücher und Dokumentationen und SQL-Updates und Suchfunktionen und öööh.. ah ja, DELETE. *g*





Hast auf jeden Fall ein Bier (oder ein Getränk deiner Wahl!
default_wink.png
) gut bei mir!
default_icon_smile.gif
 
So wie ich das sehe bleiben die Befehle bei HSQLDB ja sogar gleich... Hmmm... Ich glaub, ich versuch diese .jar einzubinden.



Wie gebe ich dem Code nun aber mit, dass er die Tabellen erstellen soll?

Oder kann ich das in dem HSQL-Manager einfach eintragen?
 
Das ist ja der Vorteil von SQL, es gibt einen Standard. Auch wenn es leider von jedem Hersteller "Dialekte" gibt, so sind doch die meistens die Grundstandards gleich.



Also entweder legst Du die Tabellen im Manager an oder Du rufst immer einen Code (als executeUpdate) auf, der die Tabellen anlegt, aber keine Exception ausgibt wenn die Tabelle schon da ist.



So z. B.




Code:
	public void createTable(final boolean pTS) {

		try {

			update("CREATE TABLE "

					+ Tabelle

					+ "(id INTEGER IDENTITY, STATUS VARCHAR(30), VERZEICHNIS VARCHAR(1000), DATEI VARCHAR(1000), GROESSE DOUBLE, LASTMODIFIED DOUBLE, ENDUNG VARCHAR(30), PFAD VARCHAR(2001))");


			update("CREATE INDEX " + Tabelle + "_INDEX1 ON " + Tabelle + " (PFAD)");

		} catch (SQLException e) {

			if (pTS) {

				e.printStackTrace();

			}

		}

	}





Code:
	public void update(String expression) throws SQLException {

		int i = st.executeUpdate(expression);


		if (i == -1) {

			System.out.println("db error : " + expression);

		}

	}



Ganz wichtig bei HSQLDB, man muss vor dem Schließen der Datenbank einen Befehlt SHUTDOWN absetzen, sonst werden die die Inserts (HSQLDB speichert alle Daten als Inserts in eine Textdatei) nicht gespeichert



Code:
	private Statement st;

.....

public void shutdown() throws SQLException {

		[B]st.execute("SHUTDOWN");[/B]

		st.close();

		conn.close();

		System.out.println("Datenbank geschlossen");

	}
 
Theoretisch reicht es dann also, wenn ich den Shutdown setze, wenn ich das EXIT_ON_CLOSE (bei mir im Hauptfenster) ausführe, oder?



Oder schreib ich das private Statement einfach in die Datenbank.java und gut ist?



Okay, dann leg ich mir jetzt mal den Manager an und trage die Tabellen direkt ein. Die erweitern sich ja zur Laufzeit zum Glück nicht.



Wenn ich den HSQLDB-Treiber lade, muss ich dann auch irgendwelche Zugangsdaten eingeben? Oder reichen da (schätz ich jetzt einfach mal) "root" und "" als Zugangsdaten?



Hab mit HSQLDB leider noch nicht gearbeitet (merkt man ja üüüüüberhaupt nicht..
default_laugh.png
).





Du bist mir wirklich eine sehr große Hilfe, ganz lieben Dank! Das nimmt mir echt einige Sorgen, die ich momentan habe!
default_smile.png
 
Oh Gott, ich bekomms nicht mal hin, in dem Manager eine Tabelle zu erstellen..
default_icon_eek.gif
*blöd fühl*



Was mach ich verkehrt?
default_icon_redface.gif





CREATE TABLE artikel (Id INTEGER PRIMARY KEY, Titel VARCHAR(255), Quelle VARCHAR(255), Erstellungsjahr BIGINT(20)) INSERT INTO artikelarchiv;


Fehlermeldung: java.sql.SQLException: unexpected token: (



Help.. x_x
 
Ich glaub, ich doofe Kuh brauche echt eine Schritt-für-Schritt-Anleitung...



Ich habe den Ordner hsqldb-1.9.0-rc6.tmp in meinem workspace liegen:



C:\Dokumente und Einstellungen\Sabi\workspace\Artikelarchiv v1.0\lib



Soooo... Dann führ ich aus dem Ordner "bin" die runManager.bat aus...

Was mach ich dort nun, um zuerst einmal festzulegen, dass artikelarchiv die Datenbank für alle Tabellen ist?



Und wie lege ich die Tabellen darin an?



Brauche folgende Tabellen:



artikel mit den Feldern Titel (VARCHAR(255)), Quelle(VARCHAR(255)), Erscheinungsjahr (BIGINT(20)) sowie dem Feld ID, was ein auto_increment braucht...



Na ja und noch weitere, aber ein Beispiel für diese Tabelle wäre schon mal gut, dann kann ich die anderen ja umschreiben.



Hilfst du mir bitte?
default_icon_redface.gif
Ist mir ehrlich gesagt schon unangenehm zu fragen.. :/
 
Code:
 CREATE TABLE `name_of_database`.`artikel` (

`id` INT( 10 ) NOT NULL AUTO_INCREMENT ,

`titel` VARCHAR( 55 ) NOT NULL ,

`quelle` VARCHAR( 55 ) NOT NULL ,

`erscheinungsjahr` BIGINT( 20 ) NOT NULL ,

PRIMARY KEY ( `id` )

) ENGINE = MYISAM
 
Das hsqldb Paket musst Du irgendwo auf der Festplatte entpacken. Aber nicht in Deinen Workspace kopieren.



Dann gehst Du in eclipse auf Dein Project - Rechte Maustaste - Properties - Java Build Path - Button "Add External JARs" und wählst dann aus dem Directory die Datei hsqldb.jar aus



Und hier ein Beispielcode




Code:
import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.PreparedStatement;

import java.sql.SQLException;

import java.sql.Savepoint;

import java.sql.Statement;


public class TestDB {


	static Connection conn;


	static Savepoint savepoint;


	private Statement st;


	public void init() {


		try {

			Class.forName("org.hsqldb.jdbcDriver");

		} catch (Exception e) {

			System.out.println("ERROR: Fehler beim Laden des Treibers: " + "org.hsqldb.jdbcDriver");

			e.printStackTrace();

			return;

		}


		try {

			conn = DriverManager.getConnection("jdbc:hsqldb:file:DB/Daten" + ";create=true", "sa",

					"");

			conn.setAutoCommit(false);

			st = conn.createStatement();

		} catch (SQLException e) {

			e.printStackTrace();

		}


	}


	public void update(String expression) throws SQLException {

		int i = st.executeUpdate(expression);


		if (i == -1) {

			System.out.println("db error : " + expression);

		}

	}


	public void createTable(final boolean pTS) {

		try {

			String sql = "CREATE TABLE artikel (id INTEGER IDENTITY, Titel VARCHAR(255), Quelle VARCHAR(255), Erscheinungsjahr INT)";

			update(sql);

		} catch (SQLException e) {

			if (pTS) {

				e.printStackTrace();

			}

		}

	}


	public void shutdown() {

		try {

			st.execute("SHUTDOWN");

			st.close();

			conn.close();

			System.out.println("Datenbank geschlossen");

		} catch (SQLException e) {

			e.printStackTrace();

		}

	}


	public void commit() {

		try {

			conn.commit();

			System.out.println("\nDatenbank Commit");

		} catch (SQLException e) {

			e.printStackTrace();

		}

	}


	public void insertArtikel(String Titel, String Quelle, int erscheinungsjahr) {


		final String Statement = "INSERT INTO artikel (Titel, Quelle, Erscheinungsjahr) VALUES(?,?,?)";


		PreparedStatement insertVerz;

		try {

			insertVerz = conn.prepareStatement(Statement);

			insertVerz.setString(1, Titel);

			insertVerz.setString(2, Quelle);

			insertVerz.setInt(3, erscheinungsjahr);


			insertVerz.executeUpdate();


			insertVerz.close();

		} catch (SQLException e) {

			e.printStackTrace();

		}


	}


	public static void main(String[] args) {

		TestDB testdb = new TestDB();


		testdb.init();

		testdb.createTable(true);

		testdb.insertArtikel("The Wall", "Amazon", 1980);

		testdb.commit();

		testdb.shutdown();

	}


}
 
Hmmm... Fehler (bei dem von blind):



unexpected token: artikelarchiv..



Ich muss dem ja erst mal klarmachen, dass er diese "DB" anlegen soll. Aber wie?
 
Das mit der Tabelle klappt nun wunderbar, allerdings haben wir noch zwei Problemchen..





Wenn wir über eine delete-Methode einen Eintrag aus der Datenbank löschen, so soll sich die Tabelle natürlich neu darstellen.



Das Darstellen an sich ist zwar kein Problem, aber wenn ich dann wieder einen Eintrag auswählen und anschließend löschen oder bearbeiten will, so wird die Selektion nicht erkannt..



Weiß jemand einen Rat?



Vielleicht sollte ich dazu erwähnen, dass wir eine Methode "deselect" geschrieben hat, die mitteilt, dass die vorherige Selektion aufgehoben werden soll.

Des Weiteren haben wir eine Methode, die "fireTableDataChanged" aufruft. Anschließend erstellen wir die Daten aus der Datenbank per "createRow" neu in der Tabelle. Das Fenster, in dem die Tabelle dargestellt wird, öffnet sich anschließend wieder und wird auch ohne den gelöschten Datensatz dargestellt.







Das andere Problem ist, dass ich zwar eine .jar erstellen (der mysqlconnector wird in der lib mitgeliefert!) und auch ausführen kann, aber wenn ich dann von meiner Startoberfläche ein Fenster öffnen will, dass mit Datenbankzugriffen arbeitet, funktioniert es leider nicht (und das, obwohl bei mir ja lokal alles drauf ist!)..



Vielleicht hat ja jemand dort auch einen Tipp für uns..? Wäre euch sehr verbunden!
 
Zurück
Oben