Datenbank

pap

Mitglied
Nachdem mir SpikeE bei meiner letzten Frage den super Tip gegeben hat, das Buch "Java ist auch eine Insel" zu lesen, habe ich einiges an Erleuchtung in Bezug auf Java Programmieren bekommen. Danke auch nochmal an den erstellten Code zur letzten Frage, hat mich echt weitergebracht!
Ich bin während der Vorbereitung zu einer Klausur, die noch ein bißchen hin ist, auf eine Aufgabe gestoßen, bei der ich nicht wirklich voran komme.

In der Aufgabe geht es um eine Filmdatenbankverwaltung, in der Daten zu Filmen, Regisseurinnen (Engl. 'directors') und Schauspielern (Engl. 'actors') erfasst und gepflegt werden können.
Zum Verständnis habe ich ein Klassendiagramm als Anhang eingefügt.
Jedem Regisseurin wird eine Liste ihrer Filme (per Referenzattribut directedMovies) und jedem Film genau eine Regisseurin (per Referenzattribut director) zuordnet.
Für jede Regisseurin soll eine Liste ihrer Filme und für jeden Film eine Liste seiner Schauspieler ausgegeben werden können.

Hier schonmal mein Teilabschnitt (teilweise gegeben, teilsweise schon ausgebaut, soweit ich konnte:
Java:
import java.util.LinkedList;

/**
 * @extends Person
 * @author ...
 * @version 1.0
 */
class Director extends Person {

  /** implements the association between a director and her movies */
  LinkedList<Movie> directedMovies;

  Director( String id, String name) {
    super( id, name);  // invokes the constructor of the superclass Person
    directedMovies = new LinkedList<Movie>();
  }
 /**
   * Adds a movie to the list of movies directed by a director
   * 
   * @param movie : the movie to be added
   * @return <code>true</code> if the movie is added, otherwise   <code>false</code>.
   */
  void addMovie( Movie movie) {
    directedMovies.add( movie);
  }
  /**
   * Printing the movies of a director.
   */
  void printDirectedMovies(){
    if ( directedMovies.size() > 0 ) {
      for (Movie m : directedMovies) 
        m.printMovie();
    } 
    else 
      System.out.println("Zu " + personID + " sind keine Filme erfasst!");
  }
  /**
   * Serialize Director objects.
   *
   * @return  a string representing a Director object
   */
  String serialize() {
    return personID + MovieDB.SEPARATOR + name + "\r\n";
  }
}
Java:
/**
* The main class, which provides the user interface
*
* @author  ...
* @version 1.0 
*/
public class MDB {
  public static void main(String[] args) {
    MovieDB.readDirectorData();
    MovieDB.readMovieData();
    int choice = 0;
    while (choice != 6) {
      showOptions();
      System.out.print("Ihre Auswahl>");
      choice = MovieDB.readInt();
      switch (choice) {
      case 1:
        MovieDB.enterDirector(); break;
      case 2:
        MovieDB.enterMovie(); break;
      case 3:
        MovieDB.showMoviesByDirector(); break;
      case 4:
        MovieDB.enterActor(); break;
      case 5:
        MovieDB.showActorsByMovie(); break;
      case 6:
        MovieDB.writeDB();
        System.exit(0);
      default:
        System.out.println("Bitte eine Zahl zwischen 1 and 6 eingeben");
      }
    }
  } 
 /**
   * A method to show the main menu
   */
  static void showOptions() {
    System.out.println("--------------------------------------------");
    System.out.println("1 = Eine neue Regisseurin erfassen");
    System.out.println("2 = Einen neuen Film erfassen");
    System.out.println("3 = Die Filme einer Regisseurin auflisten");
    System.out.println("4 = Einen neuen Schauspieler erfassen");
    System.out.println("5 = Die Schauspieler eines Films auflisten");
    System.out.println("6 = END");
    System.out.println("--------------------------------------------");
  }
    
}
Java:
import java.util.LinkedList;

/**
 * @author ...
 * @version 1.0
 */
class Movie {
  String movieID; 
  String title; 
  int creationYear; 
  Director director; 

  Movie( String ID, String title, int year, Director director) {
    this.movieID = ID;
    this.title = title;
    this.creationYear = year;
    this.director = director;
  }
/** A pretty printing method for Movie objects. */
  void printMovie() {
   System.out.println("--------------------");
   System.out.println("Movie ID:      " + this.movieID);
   System.out.println("Title:         " + this.title);
   System.out.println("Creation year: " + this.creationYear);
   System.out.println("Director:      " + this.director.personID);
   System.out.println("--------------------");
  }
  /**
   * Serialize Movie objects.
   *
   * @return  a string representing a Movie object
   */
  String serialize() {
    return movieID + MovieDB.SEPARATOR + title + MovieDB.SEPARATOR + creationYear + MovieDB.SEPARATOR + director.personID + "\r\n"; 
  }
}
Java:
import java.io.*;
import java.util.*;

/**
* Klasse mit Attributen und Methoden zur Datenverwaltungs
*
* @author  ...
* @version 1.0 
*/
public class MovieDB {
  // Die Liste "persons" repraesentiert die Extension der Klasse Person
  static LinkedList<Person> persons = new LinkedList<Person>();
  // Die Liste "directors" repraesentiert die Extension der Klasse Director
  static LinkedList<Director> directors = new LinkedList<Director>();
  // Die Liste "movies" repraesentiert die Extension der Klasse Movie
  static LinkedList<Movie> movies = new LinkedList<Movie>();
 
  // Trennzeichen fuer die (De-)Serialisierung 
  static final String SEPARATOR = ","; 

//====================== DIRECTORs ===============================================
 /**
   * A method for showing the existing director IDs
   */
  static String getDirectorIDs() {
    String IDs = "";
    for (Director d : directors) {
      IDs = IDs + d.personID + " ";
    }
    return IDs;
  }
 /**
   * Erfassung von Regisseurinnen
   */
  static void enterDirector() {
    String personID, name;
    Director director;
    String choice = "j";
    while (choice.equals("j")) {
      System.out.println("Es sind " + directors.size() + " Regisseurinnen in der Datenbank:");
      if (directors.size() > 0) System.out.println( getDirectorIDs());
      System.out.println("Bitte eine Personen-Kennung fuer die zu erfassende Regisseurin eingeben:");
      personID = readString();
      System.out.println("Bitte den Namen der Regisseurin eingeben:");
      name = readString();
      director = new Director( personID, name);  // create the new director object with the constructor
      persons.add( director);  // add to the persons list
      directors.add( director);  // add to the directors list
      System.out.print("Weitere Regisseurin erfassen (j/n)?");
      choice = readString();
    }
  }
  /**
   * Read and process the text file "Directors.txt".
   */
  static void readDirectorData() {
    String fileName = "Directors.txt";
    Director director;
    BufferedReader br = null;
    boolean fileExists = true;
    try {
      File f = new File( fileName);
      br = new BufferedReader( new FileReader(f));
    }
    catch (FileNotFoundException e) {
      fileExists = false;
    }
    if (fileExists) {
      while (true) {
        try {
          String textLine = br.readLine();
          if (textLine == null) break;  // Datei-Ende
          director = deserializeDirector( textLine);
          persons.add( director);  // add to the persons list
          directors.add( director);   // add to the directors list
        }
        catch (IOException e) {
          System.out.println ("Lesefehler für " + fileName);
        }  
      }
      try { br.close();}
      catch (IOException e) {
        System.out.println ("Lesefehler für " + fileName);
      }
    }  
  }  
 /**
  * Transform a line of the text file "Directors.txt" into a Director object.
  * This is called "deserialization".
  *
  * @param textLine  a text line representing a director
  * @return  the corresponding Director object
  */  
  static Director deserializeDirector( String textLine) {
    String pID, name;
    Scanner s = new Scanner( textLine).useDelimiter( SEPARATOR);
    pID = s.next();
    name = s.next();
    return new Director( pID, name);
  }
 /**
   * Schreiben der Datei "Directors.txt".
   */
  static void writeDirectorData() {
    File f = new File("Directors.txt");
    BufferedWriter bw = null;
    try {
      bw = new BufferedWriter( new FileWriter(f));
    }
    catch (IOException ioe) {
      System.out.println ("IO exception = " + ioe);
    }  
    for (Director d : directors) {
      try {
        bw.write( d.serialize());
      }
      catch (IOException ioe) {
        System.out.println ("IO exception = " + ioe);
      }  
    }
    try { 
      bw.close();
      System.out.println("Directors.txt wurde geschrieben.");
    }
    catch (IOException ioe) {
      System.out.println ("IO exception = " + ioe);
    }  
  }
 /**
   * Finde die zu dem Personnenkennzeichen gehoerige Regisseurin.
   *
   * @param pID  das Personnenkennzeichen der gesuchten Regisseurin
   * @return  das gesuchte Director-Objekt
   */
  static Director findDirectorByID( String pID) {
    Director foundDirector = null;
    for (Director d : directors) {
      if (d.personID.equals( pID)) {
        foundDirector = d;
        break;
      }
    }
    return foundDirector;
  }
 /**
   * 
   */
  static void showMoviesByDirector() {
    System.out.println("Es sind " + directors.size() + " Regisseurinnen in der Datenbank:");
    if (directors.size() > 0) {
      System.out.println( getDirectorIDs());
      System.out.println("Bitte Personen-Kennung der Regisseurin eingeben:");
      String personID = readString();
      Director director = findDirectorByID( personID);
      if (director == null) {
        System.out.println("Es gibt keine Regisseurin mit dem Personen-Kennzeichen " + personID + "!");
      } else {
        director.printDirectedMovies();
      }
    }  
  }
//====================== MOVIEs ===============================================
 /**
   * Entering movies.
   */
  static void enterMovie() {
    String personID;
    String choice = "j";
    while (choice.equals("j")) {
      System.out.println("Es sind " + movies.size() + " Filme in der Datenbank:");
      if (movies.size() > 0) System.out.println( getMovieIDs());
      System.out.print("Neue Film-Kennung = ");
      String movieID = readString();
      System.out.print("Titel = ");
      String title = readString();
      System.out.print("Jahr = ");
      int creationYear = Integer.parseInt( readString());
      System.out.println("Eine Regisseurin aus der folgenden Liste zuordnen: ");
      System.out.println( getDirectorIDs());
      System.out.print("Kennung fuer Regisseurin = ");
      personID = readString();
      Director director = findDirectorByID( personID);
      if (director == null) {
        System.out.println("Es gibt keine Regisseurin mit dem Personen-Kennzeichen " + personID + "!");
      } else {
        Movie movie = new Movie( movieID, title, creationYear, director);
        movies.add( movie);  // add movie to the movies list
        director.addMovie( movie);  // add movie to the director's list of directed movies
        System.out.println("Neuer Film wurde erfasst.");
      }
      System.out.print("Einen weiteren Film erfassn (j/n)?");
      choice = readString();
    }
  }
 /**
   * Collect the IDs of the existing movies
   */
  static String getMovieIDs() {
    String IDs = "";
    for (Movie m : movies) {
      IDs = IDs + m.movieID + " ";
    }
    return IDs;
  }
  /**
   * Read and process the text file "Movies.txt".
   */
  static void readMovieData() {
    String fileName = "Movies.txt";
    Movie m;
    BufferedReader br = null;
    boolean fileExists = true;
    try {
      File f = new File(fileName);
      br = new BufferedReader( new FileReader(f));
    }
    catch (FileNotFoundException e) {
      fileExists = false;
    }
    if (fileExists) {
      while (true) {
        try {
          String textLine = br.readLine();
          if (textLine == null) break;  // Datei-Ende
          m = deserializeMovie( textLine);
          movies.add( m);  // Film zur movies-Liste hinzufuegen
          m.director.addMovie( m);  // Film zur directedMovies-Liste von m.director hinzufuegen
        }
        catch (IOException e) {
          System.out.println ("Lesefehler für " + fileName);
        }  
      }
      try { br.close();}
      catch (IOException e) {
        System.out.println ("Lesefehler für " + fileName);
      }
    }  
  }  
 /**
  * Umwandlung einer Zeile der Datei "Movies.txt" in ein Movie-Objekt (Deserialisierung).
  *
  * @param textLine  eine Textdateizeile, die einen Film repraesentiert
  * @return  das entsprechende Movie-Objekt
  */
  static Movie deserializeMovie( String textLine) {
    String movieID, title, directorID;
    int creationYear; 
    Director director;
    Scanner s = new Scanner( textLine).useDelimiter( SEPARATOR);
    movieID = s.next();
    title = s.next();
    creationYear = s.nextInt();
    directorID = s.next();
    director = findDirectorByID( directorID);
    if (director != null) {
      return new Movie( movieID, title, creationYear, director);
    } else {
      System.out.println("Es gibt keine Regisseurin mit der Kennung " + directorID);
      return null;
    }
  }
 /**
   * Schreiben der Datei "Movies.txt".
   */
  static void writeMovieData() {
    File f = new File("Movies.txt");
    BufferedWriter bw = null;
    try {
      bw = new BufferedWriter( new FileWriter(f));
    }
    catch (IOException ioe) {
      System.out.println ("IO exception = " + ioe);
    }  
    for (Movie m : movies) {
      try {
        bw.write( m.serialize());
      }
      catch (IOException ioe) {
        System.out.println ("IO exception = " + ioe);
      }  
    }
    try { 
	  bw.close();
      System.out.println("Movies.txt wurde geschrieben.");
	}
    catch (IOException ioe) {
      System.out.println ("IO exception = " + ioe);
    }  
  }
 /**
   * 
   */
  static void showActorsByMovie() {
  System.out.println ("Hier komm ich nicht weiter");
  // Ihr Programmcode
  // ...
}
//====================== ACTORs ===============================================
 /**
   * 
   */
  static void enterActor() {
  System.out.println ("Hier komm ich nicht weiter");
  // ...
  // ...
}
//=====================================================================
 /**
   *  Alle Dateien der Datenbank schreiben
   */
  static void writeDB() {
  writeDirectorData();
  writeMovieData();
}

//=====================================================================

  /**
   * Two methods for handling user input
   * YOU DON'T NEED TO READ AND UNDERSTAND THESE METHODS!
   */
  static String readString(){
    String str = null;
    InputStreamReader reader = new InputStreamReader( System.in);
    BufferedReader br = new BufferedReader( reader);
    try {
      str = br.readLine(); 
    }
    catch (IOException ioe) {
      System.out.println ("IO exception = " + ioe);
    }
    return str;
  }
  static int readInt(){
    int result = 0;
    InputStreamReader reader = new InputStreamReader( System.in);
    BufferedReader br = new BufferedReader( reader);
    try {
      String s = br.readLine(); // read the number as a string
      // Trim the whitespace before parsing.
      result = Integer.parseInt(s.trim()); // Convert string to int
    }
    catch (IOException ioe) {
      System.out.println ("IO exception = " + ioe);
    }
    return result;
  }
}
Java:
/**
 * @author ...
 * @version 1.0
 */
public class Person {
  String personID; 
  String name;  

  Person( String personID, String name) {
    this.personID = personID;
    this.name = name;
  }

  /**
   * A pretty printing method for Person objects.
   *
   * @return  a pretty printed string with Person data
   */
  String getPerson() {
    return name + " (" + personID + ")" ;
  }
  /**
   * Serialize Person objects.
   *
   * @return  a string representing a Person object
   */
  String serialize() {
    return personID + MovieDB.SEPARATOR + name + "\r\n";  
  }
}

In dieser Form soll der Textinhalt jeweils erfasst werden:

Directors
QT Quentin Tarantino

Movies
001 Krieg der Sterne 1977 GL

Schauspieler
...

Die Texte sollen erfasst werden, das Programm um die Klasse Actor und die beiden Zusatzfunktionen Erfassung von Schauspielern und Ausgabe aller Schauspieler eines Films erweitert werden.
Da bin ich überfordert.

Soviel weiß ich:
Die Klasse Actor in einer weiteren Java-Datei Actor.java analog zur Klasse Director soll entstehen, aber ohne ein zusätzliches Attribut und die dazugehörigen Methoden.
Die Definition der Klasse Movie soll um ein listenwertiges Attribut actors, auch im Konstruktor und in der printMovie-Methode, erweitert werden, außerdem die Definition der serialize-Methode um die Serialisierung dieses Attributs (Code).
Die Definition der Klasse MovieDB soll um ein listenwertiges Attribut actors erweitert werden.
Außerdem soll der Actor-Code-Abschnitt in MovieDB.java um folgende Methoden erweitert werden:
- getActorIDs und enterActor (analog zu getDirectorIDs und enterDirector),
- deserializeActor und readActorData (analog zu deserializeDirector und readDirectorData),
- findActorByID (analog zu findDirectorByID)
- writeActorData (analog zu writeDirectorData),

Außerdem erweitert werden soll:
- die main-Methode der MDB-Klasse um den Methodenaufruf MovieDB.readActorData() vor MovieDB.readMovieData()
- die writeDB-Methode der MovieDB-Klasse um den Methodenaufruf MovieDB.writeActorData()
- die Methode enterMovie im Movie-Code-Abschnitt in MovieDB.java um Anweisungen zur Erfassung der Schauspieler eines Films mit Hilfe von Personenkennungen.
- die Methode deserializeMovie im Movie-Code-Abschnitt in MovieDB.java um Anweisungen zur Deserialisierung des Actor-ID-LIsten-Strings.

Ich will den Code für die Methode showActorsByMovie im Movie-Code-Abschnitt in MovieDB.java (analog zu showMoviesByDirector) schreiben.

Eine Menge Probleme, aber vielleicht kann sich jemand der Herausforderung stellen, weil ich das alleine noch nicht schaffe, aber ich arbeite dran, wie man sieht.
 

Anhänge

  • MovieDB.png
    MovieDB.png
    3,3 KB · Aufrufe: 11
Zuletzt bearbeitet von einem Moderator:
Moin pap,
also erstmal : Screenshots bitte über die hier im Forum verfügbare Anhangs-Funktion reinstellen. Bei fremd Hostern haben wir immer das Problem dass nach einer gewissen Zeit die Screenshots einfach gelöscht werden. Das ist nicht schön weil man sich dann später nicht mehr drauf beziehen kann. Also bitte einfach dein Klassendiagramm noch mal als Anhang einfügen.

Zweitens : ich weis nicht ob sich serialisierte Objekte so gut eignen. Zu mal wenn sie am Stück in einer TXT stehen. Auch finde ich die serialize-Methode sehr textbasiert. Und das \r\n hat da schon mal gar nichts zu suchen.
Wenn es unbedingt text/plain sein muss würde sich hier CSV oder XML deutlich besser machen als da was selbst zusammengebasteltes.
*Natürlich würde sowas im produktiven Einsatz über eine richtige Datenbank laufen ... aber eins nach dem anderen*

Dein Ansätze sehen gut aus. Ich kann jetzt beim groben drüberfligen kein Fehler erkennen.

Aber nun zu meiner Frage : womit genau bist du denn jetzt überfordert ? Wie du es lösen kannst hast du doch schon selbst gesagt : analog der vorhandenen Methoden. Und das ist wirklich so einfach wie es klingt.

Ich werde mich nachher wenn ich mal etwas Zeit finde dran setzen und versuchen dir dabei zu helfen.
 
Hey SPIKEe,
sollte auch einfach sein, aber ich hab irgendwie ein Brett vorm Kopf.
Ich habe Probleme beim korrekten Einlesen der Movie.txt, beim Speichern der Filme inklusive aller ID´s seiner Schauspieler in einer Datei sowie bei der Ausgabe aller Schauspieler eines Filmes.
Zum zweiten Punkt müsste die serialize Methode glaube ich ungefähr so aussehen:
Java:
  /**
   * Serialize Movie objects.
   *
   * @return  a string representing a Movie object
   */
  String serialize() {
    String actorIdString = "";
    for (Actor a : actors) {
      actorIdString = actorIdString + a.personID + MovieDB.SEPARATOR;
    }
    String tail = (actorIdString.equals("")) ? "\r\n" : MovieDB.SEPARATOR + actorIdString + "\r\n";
    return movieID + MovieDB.SEPARATOR + title + MovieDB.SEPARATOR 
        + creationYear + MovieDB.SEPARATOR + director.personID + tail;
  }

Ich weiß, dass ich so kurz vorm Ziel bin, aber irgendwie will das nicht.
 
Zuletzt bearbeitet von einem Moderator:
Weil an der Stelle nur der Datensatz zurückgegeben werden sollte, wie die Daten getrennt werden bzw. wie sie überhaupt gespeichert werden, obliegt der Persistenzschicht und nicht dem Objekt selbst.
 
Oder einfacher formuliert : warum verwendest du eine eigene serialisierungs-Methode ? Überlass das doch einfach Java.
 
Ist in der Aufgabe so angegeben, dass man das soll. Ich bin schon viele Aufgaben durchgegangen, die ich, nachdem ich das Buch angefangen habe zu lesen, theoretisch anders gelöst hätte, weil es a) effizienter gewesen wäre, oder b) von Java erledigt werden hätte können.

Ich bin der Aufgabe leider alleine immer noch nicht gewachsen. Kann mir da wer vielleicht nochmal ein Tritt geben, weil ich das nicht hinbekomme?

Im Grunde wäre es also besser in Bezug auf das \r\n , die/das Zeilenende-Steuerzeichen nicht in den jeweiligen serialize-Methoden der Informationsmodell-Klassen, sondern in den writeX-Methoden der MovieDB-Klasse mit einer Fallunterscheidung zu schreiben?:
....
bw.write( d.serialize() + "\r\n");
....
 
Zuletzt bearbeitet:
...danke für die Hinweise bis hier hin SPiKEe und Akeshihiro. Ich muss wohl später nochmal an die Aufgabe anknüpfen, da ich das ohne eure Hilfe nicht schaffe. Habe gerade aufgegeben, nach 2 weiteren Tagen dransitzen ;) Die Aufgabe hats aber auch in sich.
 
Zurück