Wie kopieren ich eine Spalte von einer Tabelle in eine andere Tabelle SQLite durch java code?

Bajra

Mitglied
Hallo zusammen, ich bin relative neue in Java und ich brauche eure Hilfe. wie könne ich eine Methode davon machen, den den SQLite Anfrage entspricht.

ich will von der Tabelle groupsAddPeptides die pepID in der peptides Tabelle einfügen. Beide egsitieren schon.

SQL:
UPDATE peptides SET pGroup = (SELECT pepID FROM groupsAddPeptides Where id = peptides.id)

Auf eine Antwort oder Erklärung würde ich mich sehr freuen.
 
Du baust eine JDBC-Verbindung zur Datenbank auf und hast dann ein Connection-Objekt. Mit dem kannst Du dann etwas wie
Java:
String sql = "UPDATE peptides SET pGroup = (SELECT pepID FROM groupsAddPeptides Where id = peptides.id)";
try(Statement stmt = conn.createStatement()) {
    stmt.executeUpdate(sql);
}
machen.
 
Du baust eine JDBC-Verbindung zur Datenbank auf und hast dann ein Connection-Objekt. Mit dem kannst Du dann etwas wie
Java:
String sql = "UPDATE peptides SET pGroup = (SELECT pepID FROM groupsAddPeptides Where id = peptides.id)";
try(Statement stmt = conn.createStatement()) {
    stmt.executeUpdate(sql);
}
machen.
Danke dir.
 
Noch ein Hinweis: solltest Du in die Verlegenheit kommen, eine parametrisierte Query ausführen zu müssen, bau das SQL nicht selbst zusammen. Hierfür gibt es PreparedStatement, so dass Du in den Query-String Parameter einbauen und deren Werte im Nachhinein bestimmen kannst. Alles andere ist 99,9 % der Fälle Murks.
 
Noch ein Hinweis: solltest Du in die Verlegenheit kommen, eine parametrisierte Query ausführen zu müssen, bau das SQL nicht selbst zusammen. Hierfür gibt es PreparedStatement, so dass Du in den Query-String Parameter einbauen und deren Werte im Nachhinein bestimmen kannst. Alles andere ist 99,9 % der Fälle Murks.
Ich hätte noch eine Frage. Ich habe nicht eine Idee, wie ich das TreeMap<Long, Group> child in der Datenbank speicher kann.
Ich bin da durcheinander und ich wies nicht wie ich das anders geht. Das ist die einzige Methode, wo ich eine Map habe. Ich bin seit zwei Tagen dran.

Auf eine Antwort würde ich mich sehr freuen.
Danke!



Java:
    public void updateChildIdsSqliteDB(Group groupID, TreeMap<Long, Group> child ) {

        ResultSet rs = null;
        String sql = "INSERT INTO groupsAddChild(groupID, childID) VALUES (?,?)";

        try (PreparedStatement pstmt = connection.prepareStatement(sql)) {
                    
            pstmt.setString(1, groupID.getGroupsID());

           [B] pstmt.setNString(2, child); // Das geht nicht!!![/B]

            pstmt.executeUpdate();
            connection.commit();

        } catch (Exception e) {
            e.getMessage();
        } finally {
            try {
                if (rs != null) {
                    rs.close();
                }
            } catch (SQLException e) {
                LOGGER.error(e);
            }
        }
    }
 
1612978947670.png

Das ist die XML-Ausgabe und die ist richtig Aber mir fehlt die Idee die gleiche im SQLite zu abbilden. Ich hoffe, dass es das Bild dir hilft zu verstehen.

Diese 140 wird in den Map gespeichert und Übergabe die groupID mit
 
Zuletzt bearbeitet:
So blick ich da nicht durch, daher einfach mal ins Blaue hinein:

Java:
   private static final String INSERT_GROUP_CHILD =
           "INSERT INTO groupsAddChild(groupID, childID) VALUES (?,?)";

   public void updateChildIdsSqliteDB(Group groupID, Map<Long, Group> children ) {
        try (PreparedStatement pstmt = connection.prepareStatement(INSERT_GROUP_CHILD)) {
            for (Long childId : children.keySet()) {
                pstmt.setString(1, groupID.getGroupsID());
                pstmt.setLong(2, childId);
                pstmt.addBatch(); // Satz von Parametern hinzufuegen
            }
            pstmt.executeBatch(); // alles auf einmal ausfuehren -> schnell
            connection.commit();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
Den finally-Block brauchst Du nicht. Da wir hier try-with-resources verwenden, wird das Statement automatisch geschlossen.
 
Zuletzt bearbeitet:
So blick ich da nicht durch, daher einfach mal ins Blaue hinein:

Java:
   private static final String INSERT_GROUP_CHILD =
           "INSERT INTO groupsAddChild(groupID, childID) VALUES (?,?)";

   public void updateChildIdsSqliteDB(Group groupID, Map<Long, Group> children ) {
        try (PreparedStatement pstmt = connection.prepareStatement(INSERT_GROUP_CHILD)) {
            for (Long childId : children.keySet()) {
                pstmt.setString(1, groupID.getGroupsID());
                pstmt.setLong(2, childId);
                pstmt.addBatch(); // Satz von Parametern hinzufuegen
            }
            pstmt.executeBatch(); // alles auf einmal ausfuehren -> schnell
            connection.commit();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
Den finally-Block brauchst Du nicht. Da wir hier try-with-resources verwenden, wird das Statement automatisch geschlossen.
Moin und noch mal viele lieben danke dafür. Es hat mir super geholfen und danke für den Tipp. Es ist auch schneller beim Schrieben jetzt. Was könnte man machen, dass es beim Lesen schneller wird? Ich schick dir meine Implementierung was ich für die gleiche Funktion gemacht habe.
Java:
@Override
    public Map<Long, Group> getChildren(Group groupID) {
        String sqlGetChildrensID = "SELECT childID FROM groupsAddChild WHERE groupID = ?";

        Map<Long, Group> children = new TreeMap<>();
        try (PreparedStatement pstmt = connection.prepareStatement(sqlGetChildrensID)) {
            pstmt.setString(1, groupID.getGroupsUniqueID());
            try (ResultSet rs = pstmt.executeQuery()) {
                while (rs.next()) {
                    long childID = rs.getLong("childID");

                    children.put(childID, groupID);
                }

            }

        } catch (SQLException e) {
            e.printStackTrace();
            LOGGER.error(e);
            
        }
        return children;
    }
 
Was könnte man machen, dass es beim Lesen schneller wird?
Wichtig ist, dass die betreffenden Sätze von der DB schnell gefunden werden, was man durch Primärschlüssel bzw. Indizes erreicht. Ich gehe mal davon aus, dass (groupId, childId) einen Primärschlüssel bildet, insofern sollte die Suche kein Problem darstellen.
 
So ist das bei der Maps implementiert worden. Ich will die gleiche beim SQLite Implementierung haben. Versucht habe ich auch, aber ich kriege NullPointerException. Unten ist die Implementierung was ich versucht habe


Java:
  private Map<String, Map<String, Accession>> accessions;

    this.accessions = new HashMap<>();


    // mit der Methode wird in der Datenbanke eingefügt 
    @Override
    public void groupsAddAccession(Group group, Accession accession) {

        Map<String, Accession> acc = accessions.get(group.getGroupsUniqueID());

        if (acc == null) {
            acc = new HashMap<String, Accession>();
        }

        acc.put(accession.getAccession(), accession);
        accessions.put(group.getGroupsUniqueID(), acc);
    }


    // hier wird es gelesen
@Override
    public Map<String, Accession> getAccessions(Group group) {
        
        Map<String, Accession> acc = accessions.get(group.getGroupsUniqueID());
        if(acc ==  null) {
            acc = new HashMap<>();
        }
        
        accessions.put(group.getGroupsUniqueID(), acc);
        return acc;
    }
Java:
private Map<String, Map<String, Accession>> accessions;

//Im Konstruktor
this.accessions = new HashMap<>();

@Override
    public void groupsAddParent(Group currenGroup, Group parent) {
        TreeMap<Long, Group> parentsMap = parents.get(currenGroup.getGroupsUniqueID());
        if(parentsMap == null) {
            parentsMap = new TreeMap<>();
        }
        parentsMap.put(parent.getID(), parent);
        parents.put(currenGroup.getGroupsUniqueID(), parentsMap);

    }
    
  private Map<String, Map<String, Accession>> accessions;
    @Override
    public Map<String, Accession> getAccessions(Group group) {
        
        Map<String, Accession> acc = accessions.get(group.getGroupsUniqueID());
        if(acc ==  null) {
            acc = new HashMap<>();
        }
        
        accessions.put(group.getGroupsUniqueID(), acc);
        return acc;
    }



// Für die SQLite
@Override
    public void groupsAddAccession(Group group, Accession acc) {
         /** SQL for inserting new addPeptides in the groups */
         String sqlNewGroupsAddAccession = "INSERT INTO groupsAddAccessions(groupID, accId, accessions) VALUES (?,?,?)";
        try (PreparedStatement pstmt = connection.prepareStatement(sqlNewGroupsAddAccession)) {
            pstmt.setString(1, group.getGroupsUniqueID());
            pstmt.setLong(2, acc.getID());
            pstmt.setString(3, acc.getAccession());

            pstmt.addBatch();
            pstmt.executeBatch();
            connection.commit();
        
                        
        } catch (Exception e) {
            e.getMessage();
        
        }
        
    }
    //TODO


    @Override
    public Map<String, Accession> getAccessions(Group groupID) {
        String sqlGetAccessionsID = "SELECT accId, accessions FROM groupsAddAccessions WHERE groupID = ?";
        Map<String, Map<String, Accession>> a = new ConcurrentHashMap<String, Map<String,Accession>>();
        
        Map<String, Accession> acc = a.get(groupID.getGroupsUniqueID());
    
        try (PreparedStatement pstmt = connection.prepareStatement(sqlGetAccessionsID)) {
            pstmt.setString(1, groupID.getGroupsUniqueID());
            try (ResultSet rs = pstmt.executeQuery()) {
                while (rs.next()) {
                    long accId = rs.getLong("accId");
                    String accession = rs.getString("accessions");
                    
                    acc.put(accession, new Accession(accId, this));
                    a.put(groupID.getGroupsUniqueID(), acc);
                }
            }
        } catch (SQLException e) {
            LOGGER.error(e);
        }
        return acc;
    }
 
Vergiss mal Deinen Code und versuche zu erklären, was Du eigentlich machen willst (nicht die Lösung oder Teile davon, sondern das Problem beschreiben). Das scheint ja irgendwas mit Zugriffs(rechten) und Gruppen zu tun zu haben, die irgendwie miteinander zusammenhängen.
 
Vergiss mal Deinen Code und versuche zu erklären, was Du eigentlich machen willst (nicht die Lösung oder Teile davon, sondern das Problem beschreiben). Das scheint ja irgendwas mit Zugriffs(rechten) und Gruppen zu tun zu haben, die irgendwie miteinander zusammenhängen.
Ja. In dem ersten Teil wird ja bei der groupsAddAccession Methode eine ID (Das ist UUID von der Java Klasse als String) und das Accession Objekt übergeben. Dort wird das Id zum referenzieren in der Map mit übergeben. Dann wird das durch diese ID geholt und zurück in der Group klasse. Der Teil läuft richtig. Der untere Teil ist aber falsch, der soll das Gleiche tun, was das oberen tut. Außer hier soll von der Datenbank geschrieben und zurückgeliefert. Ich will halt von Maps loswerden, deswegen speicher ich in der Datenbank.
 
Das Problem bei der Gruppe klasse ist, dass die Gruppe durch Threads erstellt werden. Die bekommen Accession(Protein) und Peptide (genau gleiche wie die Obere Methoden) und die zusammen erstellen eine Gruppe. Es ist halt schwierig bei der Klasse, weil es keine Feste Id gibt und deswegen habe ich das UUID benutzt. Habe es mit zähler probieret, wieder kommische Zahelen in der Datenbank bekommen. Mit der UUID klappt es bessere aber es fällt mir jetzt schwirig diese Implementierung von Mpas gleiche auch bei der SQLite Klasse zu haben.
 
Das einzige, was ich jetzt problembezogenes gelesen habe, ist, dass eine Gruppe aus Accession und Peptide besteht. Das wäre eine simple 1:n-Beziehung zwischen Gruppe und Accession bzw. Peptide.
 
Das einzige, was ich jetzt problembezogenes gelesen habe, ist, dass eine Gruppe aus Accession und Peptide besteht. Das wäre eine simple 1:n-Beziehung zwischen Gruppe und Accession bzw. Peptide.
Ja genau, mindesten 1 Peptide und 1 Accession muss eine Gruppe haben. Es gibt fälle wo es mehr peptide oder Accession in einer Grupper vorkommen.
 
OK, wenn ich es richtig verstehe, dann hätte ich mal drei Tabellen für Grupe, Peptide und Accession:

Gruppe: ID, Name
Peptide: ID, Name
Accession: ID, Name

und zwei Tabellen, mit denen die Beziehungen dargestellt werden:

Gruppe_Peptide: Gruppe_ID, Peptide_ID
Gruppe_Accession: Gruppe_ID, Accession_ID

Mir ist nur nicht klar, was Du mit den Maps willst.
 
Ich meinte nicht in einer Gruppe, sondern über mehrere Gruppen hinweg.

Beispiel: eine Rechnungsposition gehört zu einer Rechnung und kann nur in dieser einen Rechnung auftauchen.
Tabellen: Rechnung (ID, ...) und Rechnungsposition (Rechnung_ID, Positionsnr, ...) - typische 1:n-Beziehung

Gegenbeispiel: es gibt Kochrezepte mit der Zutat "Sahne". Die Sahne kann aber in mehreren Kochrezepten auftauchen.
Tabellen: Rezept (ID, ...), Zutat (ID, Name) und Rezept_Zutat (Rezept_ID, Zutat_ID, Menge, ...)
 
OK, wenn ich es richtig verstehe, dann hätte ich mal drei Tabellen für Grupe, Peptide und Accession:

Gruppe: ID, Name
Peptide: ID, Name
Accession: ID, Name

und zwei Tabellen, mit denen die Beziehungen dargestellt werden:

Gruppe_Peptide: Gruppe_ID, Peptide_ID
Gruppe_Accession: Gruppe_ID, Accession_ID

Mir ist nur nicht klar, was Du mit den Maps willst.
Maps waren in der Gruppe Klasse deklariert. Dafür sind dort Funktionen geschrieben. Idee dahinter war die Maps in eine andere Klasse zu schieben und in der Gruppe klasse durch eine Variable ersetzen. Diese Maps sollen jetzt in der Datenbank gespeichert. die return Methode soll gleich aussehen wir in der Gruppe klasse. Aber die Daten sollen von der Datenbanke aufgerufen. Die wollte ich in den Map einfügen und zurückgeben in der Gruppe Klasse.
 
Gut, wenn ich nach den Daten des XML gehe, dann brauchst Du ja nur:

Gruppe: ID, Name
Peptide: ID, Gruppe_ID, Name
Accession: ID, Gruppe_ID, Name

Gruppe enthält dann zwei Listen für Peptide und Accession. Beim Speichern können zuerst alle Peptide (Accessions) der Gruppe gelöscht und dann neu eingefügt werden.
 
Hallo, ich bin nochmal und jetzt habe ein Problem mit der Rekursion. Dabei wird keine Abbruchbedingung stattfinden und sobald die dem Wert hat, geht zu Endlosschleife und verursacht somit eine Error "StackOverflowError".

ich wollte eine if bauen und sagen, gehe nur ein mal da rein und ruf sich nur ein mal die Methoden auf. Oder geht es auch anderes?

Ich hole die Daten von getChildren(). aus der Datenbank. Die taucht da auf und hören es nicht mehr auf


Java:
  public Map<Long, Group> getAllPeptideChildren(){
      
      //zwei Map Variablen
        Map<Long, Group> allChildren = new HashMap<>();
        Map<Long, Group> childChildren;
        
        for (Map.Entry<Long, Group> cIt :getChildren().entrySet()) {
            
                        // sobald er hier hereingeht, wiederholt sich unendlich.
                       // aber es geht nicht unten zu der for schleifen
            childChildren = cIt.getValue().getAllPeptideChildren();

                    
            for (Map.Entry<Long, Group> ccIt : childChildren.entrySet()) {
                allChildren.put(ccIt.getKey(), ccIt.getValue());
            }

            if ((cIt.getValue().getPeptides() != null) && (cIt.getValue().getPeptides().size() > 0)) {
                allChildren.put(cIt.getKey(), cIt.getValue());
            }
        }

        return allChildren;
    }
 

Zurück
Oben