Client-Server Aplikation mit Java

Aus ProgrammingWiki

Wiki-Quelltext dieser Seite.

<language>Java</language>
== Client-Server Aplikation mit Java ==
Mit Hilfe des relationalen Datenbank-Management-System Apache Derby lassen sich mit Java und der Java SQL-API ,Client-Server Anwendungen  realisieren.Das Java Programm importiert das java.sql Paket,dadurch lassen sich SQl-Anweisungen in Java Programmen ausführen.Desweiteren muss bei der Arbeit mit Eclipse ,die Bibliothek derbyclient.jar im Classpath referenziert werden.
Die realisierte Applikation besteht aus drei Clients die unabhängig voneinander auf eine
Server-Datenbank des Apache-Derby Servers zugreiffen.Die verwendete
Programmiersprache ist Java und die dazugehörige Java-SQL API.Es gibt einen
Client der den Ticketverkauf als Geschäftsprozess realisiert und einen Client der
den Produktverkauf eines Kinos realisiert.Desweiteren einen Client zum
Administrieren der gesamten Datenbank der Kinokette,er realisert die Gesamte
Datenverwaltung und Auswertung für die Kinokette.Jeweils ein Kino besitzt
daher für die Umsetzung seines Geschäftsprozesses ,den Client für den
Ticketverkauf und den Client für den Produktverkauf in einfacher oder
mehrfacher Anzahl aber mit den gleichen Netzwerk und Verkaufseinstellungen.

=== Ausführen von SQL-Anweisungen ===

Mit der Java SQL API lassen sich SQL Anweisungen ausführen.
Dieses Beispiel verdeutlicht die Anweisungsfolge zum Ausführen einer SQL-Anweisung.
Es muss immer ein Statement Objekt angelegt werden,welches den SQL-Text ausführt.
Hierbei ist es '''Statement s''' 
<code>
static Statement s;

public static void DfKI(String name ){
try {
 Create (if needed) and connect to the database
conn = DriverManager.getConnection(connectionURL);		 
System.out.println("Connected to database " + dbName);
s = conn.createStatement();
s.execute("DELETE FROM Kino WHERE Name=  "+"'"+name+"'");
s.close();
conn.close();
}  catch (SQLException e)  {   
 errorPrint(e);
System.out.println(" . . . exception thrown:");
 String a=e.getMessage();
tex3.setText(a);
}
								  
}

</code>
Updates werden mit der folgenden Anweisung ausgeführt:
<code>
String d="UPDATE Vorfuehrung  SET Preis = "+quot+" WHERE FID = (SELECT FID FROM Film WHERE FID = "+film+")";
			              
s.executeUpdate(d);

</code>

==== Ausführen von SQL-Inserts ====

Durch folgende Anweisungsfolge lassen sich am besten Inserts,in bestehende Tabellen realisieren.
Die Anweisungsfolge setzt vorraus das ein Connection Objekt existiert.Beim Insert werden die jeweiligen Spalten der Tabelle direkt angesprochen,man beginnt immer mit Spalte eins.

<code>
static Connection conn = null;

public static void SetInSaal(int id,String name,int kid,int pl){
try {
 // Create (if needed) and connect to the database
 conn = DriverManager.getConnection(connectionURL);		 
 System.out.println("Connected to database " + dbName);
							            
psInsert = conn.prepareStatement("INSERT INTO Saal(SID,Name,KID,Plaetze) values (?,?,?,?)");
psInsert.setInt(1,id);
psInsert.setString(2,name);
psInsert.setInt(3,kid);
psInsert.setInt(4,pl);
psInsert.executeUpdate();
						              
conn.close();
psInsert.close();
						    
}  catch (SQLException e)  {   
errorPrint(e);				          
System.out.println(" . . . exception thrown:");
String a=e.getMessage();
tex3.setText(a);
 }
}  


</code>

=== Auswerten von SQL-Selects ===
Die Auswertung von einem Select ist zum Beispiel nötig um die ID's von Tabellen dynamisch bei jedem Insert generieren zu lassen.Man bestimmt die Anzahl der ID's und generiert anhand dessen die folgende ID für den nächsten Insert,in die Tabelle.Das folgende Beispiel zeigt wie Inserts in die Tabelle Kino gemacht werden.Dabei werden die Daten des Selects immer vorher in einem Resultset zwischengespeichert.

<code>
static ResultSet dateidk;

 public static void Kino(String name){
						    	
 try {
 // Create (if needed) and connect to the database
conn = DriverManager.getConnection(connectionURL);		 
System.out.println("Connected to database " + dbName);
						            
s = conn.createStatement();

String d="SELECT COUNT(KID) FROM KINO";
int kidi=0;
dateidk=s.executeQuery(d);
					              
while (dateidk.next())
{
kidi=dateidk.getInt(1);
kidi=kidi+1;
SetInKino(kidi,name);
					              
}
s.close();
conn.close();
					    
}  catch (SQLException e)  {   
 errorPrint(e);
/*       Catch all exceptions and pass them to 
**       the exception reporting method             */
System.out.println(" . . . exception thrown:");
 String a=e.getMessage();
	}
}


</code>

== Geschäftsprozess ==
Das Geschäftsprozessmodell verdeutlicht den gesamten Geschäftsprozess einer
Kinokette als Datenbankverwaltung.Dieser besteht aus der Verwaltungsplanung
und dem Auswerten der Daten .Zur Verwaltungsplanung gehört es die
bestehenden Kinodaten erstmal nacheinader mit gegenseitigem Bezug
einzutragen ,in die angelegte Datenbank.Zur Auswertung der Daten gehören die
Prozesse der Datenerfassung,Datenauswertung und Datenänderung .Die
Datenerfassung erfolgt durch die Clients Ticketverkauf und Produktverkauf
Parallel .Die Datenauswertung erfolgt anhand der erfassten Daten und liefert
dem Administrator bzw. dem Manager Daten als Anschaugsobjekte in
Tabellenform.Die Datenänderung erfolgt optional für die vom Administrator
oder Manager ausgewählten und erfassten Datenobjekte.

[[Bild:Siiggeig_GeschaftsPrzs.PNG]]



=== Use Cases ===
==== USE-Cases für den Client Ticketverkauf ====
Der Ticketverkauf umfasst das Erfassen der Besucherdaten den Verbindunsaufbau
zum Datenbankserver,das Ausstellen der Tickets durch den Verkeufer und
den Verkaufstransfer der Daten zum Datenbankserver ,wobei nebenbei eine Belegausgabe
der Tickets für den Besucher erfolgt.Desweiteren ermöglicht der Client
eine Rückgabe der Tickets ,anhand erfasster Besucherdaten.


[[Bild:Siiggeig_UsecTverk.PNG]]

==== USE-Cases für den Client Produktverkauf  ====

Der Produktverkauf umfasst das Erfassen der Besucherdaten und Datenbankeinstellungen
zur jeweiligen Vorführung,durch den Produktverkeufer.Der Produktverkeufer
initiiert den Produktverkauf an den Besucher und den Verkaufsdatentransfer
an die Datenbank sowie die Belegausgabe an den jeweiligen Besucher.

[[Bild:Siiggeig_PVUSE.PNG]]


==== USE-Cases für den Client Administrator  ====

Der Administrator Verwaltet und legt die Datenbank an.Er verwaltet alle dem
Datenbankschema entsprechenden Datentabellen.Und wertet die Daten nach bestimmten
Kriterien aus indem er sich ausgewälte Daten anzeigen lassen kann
bzw. löschen kann.

[[Bild:Siiggeig_Mu.PNG]]



== Das Datenbankschema der Datenbank auf dem Server ==

Die Clients Administrator,Ticketverkauf und Produktverkauf bauen zur
folgenden Datenbank eine Verbindung während des Geschäftsprozesses auf.




[[Bild:Siiggeig_Sck.png]]


Folgende Verbindungseinstellungen werden dabei von den Clients verwendet:


<code>

static String driver = "org.apache.derby.jdbc.ClientDriver";
static String dbName="Kino";
static String connectionURL = "jdbc:derby://localhost:1527/
"+dbName+";create=true";

</code>

Das Datenbankschema besteht aus mehreren Tabellen,diese werden innerhalb
des Clients Administrator, beim Aufruf erzeugt.Wenn aber schon eine
Datenbank auf dem Server besteht,so wird diese nicht nochmal erzeugt.Sondern
es wird die erzeugte Datenbank mit den gespeicherten Daten verwendet.Die
SQL -Anweisungen zur erzeugung sind als Stringvariablen im Client
Administrator folgendermassen de�niert:


<code>

public static String CKino="CREATE TABLE Kino
(KID INTEGER PRIMARY KEY,Name VARCHAR(30) UNIQUE )";
public static String CSaal="CREATE TABLE Saal
( SID INTEGER PRIMARY KEY,Name VARCHAR(30)
UNIQUE,KID INTEGER REFERENCES Kino,Plaetze INTEGER )";
public static String CFilm="CREATE TABLE Film
(FID INTEGER PRIMARY KEY,Name VARCHAR(70) UNIQUE)";
public static String CVorfuehrung="CREATE TABLE Vorfuehrung
(VID INTEGER PRIMARY KEY,Zeit TIMESTAMP ,
SID INTEGER REFERENCES Saal(SID),
FID INTEGER REFERENCES Film(FID),
UNIQUE(Zeit,SID,FID),Preis DECIMAL(10,2) )";
public static String CBesucher="CREATE TABLE Besucher
(BID INTEGER PRIMARY KEY,Name VARCHAR(100) )";
public static String CTicket="CREATE TABLE Ticket
(TID INTEGER PRIMARY KEY, Nummer VARCHAR(200) ,
VID INTEGER REFERENCES Vorfuehrung(VID),
BID INTEGER REFERENCES Besucher(BID),
Preis DECIMAL(10,2) )";
public static String CProdukt="CREATE TABLE Produkt
(PID INTEGER PRIMARY KEY, Name VARCHAR(30) UNIQUE,
Preis DECIMAL(10,2) )";
public static String CWarenkorb="CREATE TABLE Warenkorb
(WID INTEGER PRIMARY KEY, BID INTEGER REFERENCES Besucher(BID)
, KID INTEGER REFERENCES Kino(KID), Zeit TIMESTAMP)";
public static String CProdInKorb="CREATE TABLE ProdInKorb
(PID INTEGER REFERENCES Produkt(PID),
WID INTEGER REFERENCES Warenkorb(WID), Anzahl INTEGER, Preis DECIMAL(10,2))";


</code>


Zu jeder Tabelle de�niert der Client Administrator alle notwendigen SQL-Anweisungen innerhalb von Methoden.Eine Anweisungsfolge zum Einfgen von Kinos:

<code>

String d="SELECT COUNT(KID) FROM KINO";
int kidi=0;
dateidk=s.executeQuery(d);
while (dateidk.next())
{
kidi=dateidk.getInt(1);
kidi=kidi+1;
SetInKino(kidi,name);
}
s.close();
conn.close();

</code>


Löschen von Kinos mit einem bestimmten Namen:

<code>
s = conn.createStatement();
s.execute("DELETE FROM Kino WHERE Name= "+"'"+name+"'";

</code>


Eine Anweisungsfolge zum Löschen der Verkaufsdaten :

<code>
conn = DriverManager.getConnection(connectionURL);
s = conn.createStatement();
s.execute("DELETE FROM ProdInKorb");
s.close();
conn.close();
conn = DriverManager.getConnection(connectionURL);
s = conn.createStatement();
s.execute("DELETE FROM Warenkorb");
s.close();
conn.close();
conn = DriverManager.getConnection(connectionURL);
s = conn.createStatement();
s.execute("DELETE FROM Ticket");
s.close();
conn.close();
conn = DriverManager.getConnection(connectionURL);
s = conn.createStatement();
s.execute("DELETE FROM Besucher");
s.close();
conn.close();

</code>

Der Umsatz zum Warenverkauf pro Kino:

<code>
Date t,end;
" SELECT Kino.Name, SUM(ProdInKorb.Anzahl * ProdInKorb.Preis)
AS Umsatz FROM Kino , Warenkorb , ProdInKorb WHERE Kino.KID
= Warenkorb.KID AND Warenkorb.WID = ProdInKorb.WID AND
DATE(Warenkorb.Zeit) BETWEEN "+"'"+t+"'"+" AND "+" '"+
end+"'"+" GROUP BY Kino.KID,Kino.Name";

</code>


Der Gesamtumsatz pro Film:

<code>
Date t,end;
String sum=" SELECT Film.Name,(SELECT
SUM(ProdInKorb.Anzahl * ProdInKorb.Preis) AS
Umsatz FROM Warenkorb , ProdInKorb,Film,Vorfuehrung
WHERE Film.FID=Vorfuehrung.FID AND Vorfuehrung.Zeit=Warenkorb.Zeit
AND Warenkorb.WID = ProdInKorb.WID AND DATE(Warenkorb.Zeit)
BETWEEN "+"'"+t+"'"+" AND "+" '"+end+"'"+")+(SELECT SUM(Ticket.Preis)
FROM Ticket,Film,Vorfuehrung WHERE Film.FID=Vorfuehrung.FID
AND Ticket.VID=Vorfuehrung.VID AND DATE(Vorfuehrung.Zeit)
BETWEEN "+"'"+t+"'"+" AND "+" '"+end+"'"+" )FROM FILM ";
</code>

Mittlere Auslastung pro Saal:

<code>

String d="SELECT Saal.Name , ( COUNT(Ticket.TID)*100 /
(Saal.Plaetze * COUNT(DISTINCT Vorfuehrung.VID))) AS
Auslastung FROM Saal , Vorfuehrung , Ticket WHERE Saal.SID
= Vorfuehrung.SID AND Vorfuehrung.VID = Ticket.VID AND
DATE(Vorfuehrung.Zeit) BETWEEN "+"'"+t+"'"+" AND "+"
'"+end+"'"+" GROUP BY Saal.Name,Saal.SID,Saal.Plaetze
ORDER BY Auslastung DESC";

</code>

Saal mit einem bestimmten Namen Löschen:


<code>
s.execute("DELETE FROM Saal WHERE Name= "+"'"+name+"'")

</code>

Einfügen eines Films:


<code>
String d="SELECT COUNT(FID) FROM Film";
int kidi=0;
dateidk=s.executeQuery(d);
while (dateidk.next())
{
kidi=dateidk.getInt(1);
kidi=kidi+1;
SetInFilm(kidi,name);
}
</code>

Löschen eines Films:


<code>
s.execute("DELETE FROM Film WHERE Name= "+"'"+name+"'");

</code>

Einfügen einer Vorführung:


<code>
s = conn.createStatement();
String d="SELECT COUNT(VID) FROM Vorfuehrung";
int kidi=0;
dateidk=s.executeQuery(d);
while (dateidk.next())
{
kidi=dateidk.getInt(1);
kidi=kidi+1;
SetInVorf(kidi,Zeit,sid,fid,pr);
}

</code>

Update des Preises für die Vorführungen eines Films:


<code>
String d="UPDATE Vorfuehrung SET Preis = "+quot+"
WHERE FID = (SELECT FID FROM Film WHERE FID = "+film+")";

</code>

Löschen einer bestimmten Vorführung:

<code>
s = conn.createStatement();
s.execute("DELETE FROM Vorfuehrung WHERE VID= "+id);
s.close();
conn.close();

</code>

Verkaufte Tickets in einem bestimmten Zeitraum:

<code>
String d="SELECT COUNT(*) FROM Ticket,Vorfuehrung
WHERE DATE(Vorfuehrung.Zeit) BETWEEN "+"'"+an+"'"+"
AND "+" '"+en+"'"+" AND Ticket.VID=Vorfuehrung.VID ";

</code>

Verkaufte Tickets pro Monat:


<code>

String d=" SELECT MONTH(Zeit)as Monat,COUNT(TID)as
Tickets FROM Vorfuehrung JOIN Ticket ON
Vorfuehrung.VID=Ticket.VID GROUP BY MONTH(Zeit) ";

</code>

Gesamtumsatz durch Ticketverkauf:

<code>
String d=" SELECT SUM(Ticket.Preis) FROM TICKET,
Vorfuehrung WHERE Ticket.VID=Vorfuehrung.VID AND
DATE(Vorfuehrung.Zeit) BETWEEN "+"'"+t+"'"+" AND "+" '"+end+"'";
</code>

Verkaufte Tickets pro Kino,Film und Monat:

<code>
String d=" SELECT Kino.Name,Film.Name,
MONTH(Vorfuehrung.Zeit)as Monat,COUNT(Ticket.TID)as
Tickets FROM Kino,Film,Saal,Vorfuehrung,Ticket WHERE
Vorfuehrung.SID=Saal.SID AND Saal.KID=Kino.KID AND
Vorfuehrung.FID=Film.FID AND Ticket.VID=Vorfuehrung.VID
GROUP BY Kino.Name,Film.Name,MONTH(Vorfuehrung.Zeit)
ORDER BY Kino.Name,Film.Name,MONTH(Vorfuehrung.Zeit)";

</code>

Einfügen eines Produktes:

<code>
String d="SELECT COUNT(PID) FROM Produkt";
int kidi=0;
dateidk=s.executeQuery(d);
while (dateidk.next())
{
kidi=dateidk.getInt(1);
kidi=kidi+1;
SetInProdkt(kidi,name,pr);
}

</code>


Löschen eines bestimmten Produktes:
<code>
s.execute("DELETE FROM Produkt WHERE Produkt.Name= "+"'"+name+"'");

</code>

Löschen von Produkten ohne Verkauf:

<code>
s.execute("DELETE FROM Produkt WHERE Produkt.PID
NOT IN((Select ProdInKorb.PID From ProdInKorb))");

</code>


=== SQL-Anweisungen des Clients Ticketverkauf  ===