sql query in methode mit rückgabetyp

dvdlly

Aktives Mitglied
Hallo,
Ich möchte ein Kochrezept Empfehlungssystem programmieren. Ich habe eine Methode getRecommendation, die den ältesten Eintrag aus der Tabelle Recipes wählt, dann alle Ingredients auswählt, die in der Tabelle RecipesIngredients zu diesem Rezept gehören und dann ein Recipe objekt erzeugt, das Ingredient objekte enthält, die gemäß der Tabelle zu dem Rezept korrepsondieren.
Das Problem: ich möchte das Recipe objekt zurückgeben, aber die sql query muss ja im try block erfolgen. Gebe ich das Recipe objekt in dem try block zurück, dann kompiliert der code nicht. Gebe ich ein Recipe objekt am Ende der Methode getRecommendation zurück, dann enthält das objekt nicht die informationen aus dem try block.
[CODE lang="java" title="getRecommendation"]public Recipe getRecommendation() {
String url = "jdbc:mysql://localhost/Cooking_Recipes";
try {
Connection conn = DriverManager.getConnection(url,"root","");
Statement statement = conn.createStatement();
ResultSet ingredients = statement.executeQuery("select RI.Name,I.Name from ((select * from Recipes order by LastCooked asc limit 1) R right join RecipesIngredients RI on R.\n" +
"ID = RI.RecipeID) right join Ingredients I on RI.IngredientID = I.ID ;");
ingredients.next();
Recipe recipe = new Recipe(ingredients.getString(1));
LinkedList<Ingredient> all_ingredients = new LinkedList<>();
do {
Ingredient ingredient = new Ingredient(ingredients.getString(2));
all_ingredients.add(ingredient);
} while (ingredients.next());
recipe.addIngredients(all_ingredients);
return recipe;
}
catch (Exception e) {
e.printStackTrace();
}
// HERE NEEDS TO BE A RETURN STATEMENT
}[/CODE]
 

mihe7

Top Contributor
Wenn das das einzige Problem wäre...

Aber zu Deiner Frage: das ist auch völlig richtig so. Wenn das Rezept zusammengestellt werden konnte, wir das Rezept zurückgegeben (try-Block). Tritt ein Fehler auf, musst Du Dir Überlegen, was Du tun willst:

a) ein Objekt zurückgeben? Wenn ja, welches? Ein Dummy-Rezept? Macht das Sinn? Evtl. ein Optional<Rezept>?
b) null zurückgeben, um anzuzeigen, dass kein (passendes) Rezept gefunden wurde?
c) eine Exception auslösen?
 
G

Gelöschtes Mitglied 65838

Gast
prepared statements...
try with ressources...


das letzte return musst du machen weil du theroetisch in die exception kommst und dann keinen return mehr hast
das kannst du auch umgehen indem du eine Runtime Exception wirfst oder eine eigene exception wirfst
 

dvdlly

Aktives Mitglied
Ich habe jetzt einfach ein Recipe objekt vor dem try block instanziiert, das ich danach ausgebe. Ich verstehe nicht so ganz, was du mit "prepared statements..." und "try with ressources..." sagen willst
 
G

Gelöschtes Mitglied 65838

Gast
deine Verbindung wird nicht geschlossen dh wenn du die methode zum zweiten mal aufrufst wird ein fehler kommen da die verbindung bereits offen ist bzw kann zu problemen führen
ein try with ressource schließt dir automatisch die verbindung


die query die du hast ist nicht sicher, kann ganz einfach mit "sql injection" ( findest du ganz viel im internet) verändert werden... deswegen ist der "mindest" standard für alles mit datenbanken dass man mindestens prepared statements benutzt



eine lösung ( ist bei weitem NICHT die beste ) wäre das
Java:
public Recipe getRecommendation() {
        String url = "jdbc:mysql://localhost/Cooking_Recipes";



    Recipe recipe = null;



        try {
            Connection conn = DriverManager.getConnection(url,"root","");
            Statement statement = conn.createStatement();
            ResultSet ingredients = statement.executeQuery("select RI.Name,I.Name from ((select * from Recipes order by LastCooked asc limit 1) R right join RecipesIngredients RI on R.\n" +
                    "ID = RI.RecipeID) right join Ingredients I on RI.IngredientID = I.ID ;");
            ingredients.next();
            recipe = new Recipe(ingredients.getString(1));
            LinkedList<Ingredient> all_ingredients = new LinkedList<>();
            do {
                Ingredient ingredient = new Ingredient(ingredients.getString(2));
                all_ingredients.add(ingredient);
            } while (ingredients.next());
            recipe.addIngredients(all_ingredients);

// nicht mehr hier returnen bie dieser lösung


        }
        catch (Exception e) {
            e.printStackTrace();
        }



        return recipe;



    }


ich weis halt nicht inwiefern dich design und clean code und sichcerheit interessiert... in letzter zeit wurde ich zu oft angenörgelt dass ich zu viel input geb und deswegen werd ich jetzt auch erstmal auf "wenig input" tendieren
 

dvdlly

Aktives Mitglied
Ups, dass die connection nicht geschlossen wird war ein versehen. Hast du nicht gesagt, es müsste noch ein prepared statement benutzt werden?
 
G

Gelöschtes Mitglied 65838

Gast
ja das prepared statement ist die art und weise wie die db mit deinem statement umgeht

im moment gibst du ein "query" an deine db die ist aber anfällig... ich hab jetzt nur das "return" problem behandelt in dem code
 

mihe7

Top Contributor
Man könnte das in etwa so angehen:
Java:
class RecipeRepository {
    private final ConnectionSupplier connections;

    private static final int LAST_RECIPE_NAME = 1;
    private static final int LAST_RECIPE_INGREDIENT = 2;

    private static final String QUERY_LAST_RECIPE = 
            "select RI.Name,I.Name " +
            "from (select * from Recipes order by LastCooked asc limit 1) R" +
            "inner join RecipesIngredients RI on R.ID = RI.RecipeID) " +
            "inner join Ingredients I on RI.IngredientID = I.ID"

    public RecipeRepository(ConnectionSupplier connections) {
        this.connections = connections;
    }

    public Optional<Recipe> findRecommendation() {
        try(Connection conn = connections.get();
            PreparedStatement statement = conn.prepareStatement(QUERY_LAST_RECIPE);
            ResultSet queryResult = statement.executeQuery()) {

            if (queryResult.next()) {
                return Optional.of(loadRecipe(ingredients));
            }
        } catch (SQLException ex) {
            ex.printStackTrace();
            return Optional.empty();
        }
    }

    private Recipe loadRecipe(ResultSet queryResult) throws SQLException {
        Recipe recipe = new Recipe(queryResult.getString(LAST_RECIPE_NAME));
        recipe.addIngredients(loadIngredients(queryResult));
        return recipe;
    }

    private List<Ingredient> loadIngredients(ResultSet queryResult) throws SQLException {
        List<Ingredient> ingredients = new LinkedList<>();
        do {
            ingredients.add(new Ingredient(ingredients.getString(LAST_RECIPE_INGREDIENT)));
        } while (ingredients.next());

        return ingredients;
    }
}

ConnectionSupplier ist dabei einfach ein Interface
Java:
@FunctionalInterface
public interface ConnectionSupplier {
    Connection get() throws SQLException;
}
um unabhängig vom verwendeten "Verbindungsmechanismus" zu sein, wobei ich einen Connection-Pool empfehlen würde.

Das SQL habe ich etwas umgeschrieben, weil ich nicht glaube, dass Du alle Zutaten haben willst und dann das ggf. passende Rezept dazu. Falls doch, nimm einfach wieder Dein SQL.

Was das PreparedStatement betrifft: das wäre in diesem Fall aus Sicherheitsgründen nicht erforderlich, da Du kein SQL zusammenbaust.

Ach so: der Spaß ist nur runtergeschrieben, nicht getestet und kann Fehler enthalten.
 
G

Gelöschtes Mitglied 65838

Gast
eine "Exception e" zu werfen ist mager... wirf gezielte exceptions mit "gutem" inhalt... beste biespiel ist wenn du in javafx css lädsts da kommt die meldung
css couldnt be loaded
ja DANKE... und WARUM... WO hast du gesucht.... ach ich könnte den ganzen tag pulvern :D
 

fhoffmann

Top Contributor
Deine Methode wird so nicht fuktionieren. Das ResultSet enthält möglicherweise noch nicht alle Ergebnisse; ein Teil der Ergebnisse wird möglicherweise erst von der Datenbank abgefragt, wenn du result.next() aufrufst; das ist aber nicht mehr möglich, wenn du die Verbindung zur Datenbank bereits geschlossen hast.
 

dvdlly

Aktives Mitglied
Wie würdet ihr eine SQL query schreiben, die für ein gegebenes Recipe objekt prüft, ob Zutaten und das Rezept selbst in der DB enthalten sind und falls das nicht zutrifft (für einzelne Zutaten oder das Rezept selbst) diese in die Datenbank einfügt?
 

mihe7

Top Contributor
Wenn ich Dich richtig verstehe, willst Du ein Rezept komplett speichern, wobei die Zutaten ggf. ergänzt werden sollen. Du könntest die ID von Rezept und Zutat in die Klassen aufnehmen, dann kannst Du anhand dieser feststellen, was schon eine ID bekommen hat.

Allerdings: die Abbildung von Objekten auf RDBMS wird sehr schnell ein sehr komplexes Thema. Die Queries sind ja nur ein kleiner Teil, dazu kommt das Transaktionsmanagement oder der Wunsch, Änderungen an den Objekten automatisch nachzuverfolgen (Unit of Work) und das ganze auch noch mit etwas Effizienz (Cache). Daher würde ich Dir bei solchen Anforderungen zu einem ORM wie Hibernate oder EclipseLink raten. Da ist zwar auch einiges zu lernen/berücksichtigen aber das Gros der Arbeit nimmt Dir der ORM ab.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
G SQL-Query Methode Datenbankprogrammierung 4
Zrebna PostgreSQL-Query in eine MicrosoftSQL-Query konvertieren - chatGPT hilft nur bedingt. Datenbankprogrammierung 3
L JPA EclipseLink PostgreSQL auslesen mit Query Datenbankprogrammierung 2
T TRIM in Query Datenbankprogrammierung 3
OnDemand Mysql Query Builder Datenbankprogrammierung 1
P Herausfinden wann Query null zurück gibt? Datenbankprogrammierung 1
OnDemand SQL Query Optimierung Datenbankprogrammierung 28
Kirby.exe Verwirrung beim Query Datenbankprogrammierung 4
I Hibernate / JPA - Spaltenname von Query (Select) bekommen Datenbankprogrammierung 6
M Oracle Query umbauen (sind die Querys gleich?) Datenbankprogrammierung 5
B Frage bei einer SQL Query Datenbankprogrammierung 3
C Fehlerhafte SQL Query Datenbankprogrammierung 4
B MySQL Query (Anfängerfrage :D) Datenbankprogrammierung 3
B JPA / HQL Support bei Query - Distanzberechnung Datenbankprogrammierung 0
D JPQL- Query über mehrere Tabellen Datenbankprogrammierung 7
Thallius MySQL Was ist falsch an dem Query? Datenbankprogrammierung 2
Thallius MySQL Wo ist der Fehler in dem Query? Datenbankprogrammierung 2
OnDemand MySQL SQL Query Datenbankprogrammierung 2
X SQLite Erhalte bei Query INSERT INTO eine NullPointerException Datenbankprogrammierung 10
B Leerzeichen nach Umlaut -> Sichtbar erst nach Query! Datenbankprogrammierung 6
S sql query, um bestimten datensatz zu finden Datenbankprogrammierung 33
OnDemand SQL Query Anzahl der Werte Datenbankprogrammierung 8
H MySQL Anderer Query-Ansatz? Datenbankprogrammierung 4
P Tricky SQL Query Datenbankprogrammierung 3
P SQL Query Problem Datenbankprogrammierung 14
I Nullpointer bei einfacher Daba query Datenbankprogrammierung 12
I Query für Geburtstage Datenbankprogrammierung 6
S MYSQL: "Packet for query is too large" Datenbankprogrammierung 0
S HSQLDB PrepareStatement- Falsche query Datenbankprogrammierung 2
F Oracle The parameter name [...] in the query's selection criteria does not match any parameter name d Datenbankprogrammierung 2
J Fehler bei mySQL Query Datenbankprogrammierung 19
R MySQL berechnete Spalte im selben query weiterverwenden? Datenbankprogrammierung 4
S MySQL Hochkommata in Query Datenbankprogrammierung 7
M Problem beim Erstellen einer Query Datenbankprogrammierung 7
D SQL Update auf eine Query möglich? Datenbankprogrammierung 4
T HQL Query funktioniert nicht? Datenbankprogrammierung 8
M PostgreSQL Hibernate Query Restriction Datenbankprogrammierung 2
N Query für Derby DB mit Enterbrise Bean Datenbankprogrammierung 4
algebraiker Eclipse RCP - no persistent classes found for query class Datenbankprogrammierung 4
M List aus Hibernate Query Datenbankprogrammierung 5
M JPA-Query - nicht das komplette Objekt Datenbankprogrammierung 4
M Problem mit Hibernate und Named Query Datenbankprogrammierung 1
S DB2 Eclipselink Query Datenbankprogrammierung 2
LadyMilka Ergebnistyp HQL-Query Datenbankprogrammierung 3
M Frage zu folgender Query in EJB-QL Datenbankprogrammierung 4
Eldorado MySQL HQL Query Tag von Date Datenbankprogrammierung 6
H DB auslesen (Hibernate, Query, Parameter) Datenbankprogrammierung 8
C Split String für SQl query Datenbankprogrammierung 10
C setSelectedValue in SQL Query übergeben Datenbankprogrammierung 20
D Hibernate: Query verarbeiten Datenbankprogrammierung 11
B Hibernate, einfaches Query Ausgeben Datenbankprogrammierung 4
X Select Query auf Substring Datenbankprogrammierung 2
L Query grafisch erzeugen Datenbankprogrammierung 6
N SQL Query Browser Error Datenbankprogrammierung 6
B Suche Query um genau einen Wert einer def. Gruppe aus einer Tabelle zu erhalten. Datenbankprogrammierung 2
Chtonian Effizientes Query System für Wortnachschlagewerk Datenbankprogrammierung 9
D Hibernate, Criteria Query Datenbankprogrammierung 2
T JPQL Query für eine Tabellenansicht Datenbankprogrammierung 2
G JPQL L*KE / JPA Query Language Datenbankprogrammierung 9
O SQL-Query bringt Fehler Datenbankprogrammierung 4
D kurze Frage zu einem Query Datenbankprogrammierung 6
S Query aus Querys Datenbankprogrammierung 14
P [Hibernate] Criterion-Query in HQL übersetzen Datenbankprogrammierung 10
D Neuer Query wird nicht erkannt Datenbankprogrammierung 10
E Wie koennte die SQL Query aussehen? Datenbankprogrammierung 13
B mysql query ausführen Datenbankprogrammierung 4
N Fehler beim matchen von Strings via Query Datenbankprogrammierung 2
G How to put SQL query result into a file Datenbankprogrammierung 3
B Ein Query mit Mysql erzeugen Datenbankprogrammierung 6
G Hilfe bei Query für Spaltenansicht. Datenbankprogrammierung 20
A Fehler bei query Datenbankprogrammierung 7
M Meine Datenbank lässt sich mit meiner Methode nicht ändern Datenbankprogrammierung 1
S Variable in main soll mit der generierten Zahl aus einer Methode ausgefüllt werden Datenbankprogrammierung 3
D JPA gleiche methode funktioniert an einer Stelle, an der anderen nicht Datenbankprogrammierung 3
C Seitensystem mit seek Methode Datenbankprogrammierung 2
D Insert Methode per Servlet Datenbankprogrammierung 2
D Insert Methode per Servlet Datenbankprogrammierung 0
J Datenbank: Methode wegen doppelten User Datenbankprogrammierung 1
N tableChanged Methode - AbstractTableModel Datenbankprogrammierung 2
W Methode createStatement() Datenbankprogrammierung 14
S Hibernate und Set-Methode Datenbankprogrammierung 16
S Schnellste Methode Datei aus Datenbank herstellen Datenbankprogrammierung 7
A update methode für datenbank Datenbankprogrammierung 2
A Insert Methode Syntaxfehler Datenbankprogrammierung 2
J Methode Datenbankprogrammierung 5
R Effiziente Java-Methode zum finden eines freien PK Datenbankprogrammierung 7
K Schnelle Methode um zu testen ob Datensatz existiert Datenbankprogrammierung 9
G Effektive Methode zum durchsuchen von SQL-Datenbanken Datenbankprogrammierung 7
A Problem mit der Methode setFieldDelimiter("'"); Datenbankprogrammierung 3
L Methode, die Veränderungen in Datenbank zeigt? Datenbankprogrammierung 4
T Methode getColumnIndex(String columnName) ? Datenbankprogrammierung 6
A Blob in Oracle-DB einfügen (veraltete Methode) Datenbankprogrammierung 3
B Methode .next() - das Rätsel für Experten! URGENT Datenbankprogrammierung 2
C Rückgabetyp einer Datenbankabfrage Datenbankprogrammierung 12

Ähnliche Java Themen

Neue Themen


Oben