Avatar billede jsl Nybegynder
29. juni 2005 - 21:01 Der er 19 kommentarer og
1 løsning

Brug samme instans af klasse?

Godt man har eksperten, når Google ikke giver resultat :-)

Jeg har i mit databaseprogram en tråd, der løbende skulle gemme alle ændringer i sql databasen, men det gør den ikke. Jeg tror det skyldes følgende:

I en klasse kaldet DataBaseConnSetup opretter jeg databasen, query sets og har funktionen, der opretter forbindelse til databasen. Denne klasse opretter jeg to instanser af; første gang i metoden, der requester posterne i databasen, og anden gang i tråden, kaldet savingThread, der gemmer ændringer. Jeg finder det sandsynligt, at det ikke virker, fordi metoden og tråden ikke bruger samme instans af DataBaseConnSetup. Lyder det sansynligt, selvom jeg stadig ikke er nogen stor Java haj til at beskrive sådanne situationer? Hvordan kan problemet løses?
Herunder ses DatabaseConnSetup og savingThread.

public class DatabaseConnSetup  {
    Database database1 = new Database();
    QueryDataSet queryDataSet1 = new QueryDataSet();
    QueryDataSet queryDataSet2 = new QueryDataSet();
    QueryDataSet queryDataSet3 = new QueryDataSet();
    Statement stmt;
    Connection getConn;
    ConnectionDescriptor connDescrip;

    public void dcsGetConn() throws Exception {
        try {
            Class.forName("com.borland.datastore.jdbc.DataStoreDriver");
            getConn = DriverManager.getConnection("jdbc:borland:dslocal:db.jds",
                                              "USER", "PASSWORD");
            stmt = getConn.createStatement();
        } catch (SQLException ex) {
        }
    }
}


public class savingThread extends Thread {
    DatabaseConnSetup dcs = new DatabaseConnSetup();

    public void run(){
        dcs.database1.saveChanges(dcs.queryDataSet1);
        dcs.database1.saveChanges(dcs.queryDataSet2);
        System.out.println("Save changes succeeded");

    }
}
Avatar billede arne_v Ekspert
29. juni 2005 - 21:06 #1
der er ikke nok kode til at kunne sige hvad der går galt

men prøv at erstatte

        } catch (SQLException ex) {
        }

med

        } catch (SQLException ex) {
              ex.printStackTrace();
        }

alle steder og se om du får noget at vide
Avatar billede mikkelbm Nybegynder
29. juni 2005 - 21:07 #2
Lige en ting... Din tråd kører kun én gang. Det ved jeg ikke om du er klar over?
Avatar billede jsl Nybegynder
29. juni 2005 - 21:48 #3
Jo, det er jeg klar over. Den afvikles, hver gang focus fjernes fra tabel og combobokse.
Jeg vil lige understrege, at der ikke kommer fejl, og at koden afvikles. Er problemet ikke, at det ikke er den samme instans af DatabaseConnSetup, der anvendes? I den sidste kode, som ikke er vist, opretter jeg instansen på samme på som i savingThread.
Hvordan ellers vil I lave det? Evt. links til sider på nettet er ønskelige.
Avatar billede arne_v Ekspert
29. juni 2005 - 21:49 #4
der burde umiddelbart ikke være noget galt med at have 2 instanser af den klasse

har du prøvet at printe ved SQLException ?
Avatar billede mikkelbm Nybegynder
29. juni 2005 - 21:51 #5
Hvis din database kan klare flere connections, burder der ikke være problemer i at have flere instanser.
Avatar billede macpain Nybegynder
29. juni 2005 - 22:53 #6
Det skulle ikke være fordi du ikke lave en execute(executeUpdate("bla")) når du skal gemme, altså at du bruge resultset(executeQuery("bla")) i begge tilfælde.
Avatar billede macpain Nybegynder
29. juni 2005 - 22:55 #7
Begge tilfælde = gem/hent
Avatar billede jsl Nybegynder
29. juni 2005 - 23:28 #8
Her på denne side: http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Thread.html, fandt jeg lidt inspiration til en ny måde at lave det på. Med den nye kode virker det ikke helt som om tråden kører som en tråd. Tag gerne et kig på den flg. kode, og råb op, hvis I finder fejl.
Den kaldende kode ser nu sådan ud:
    public void focusLost(FocusEvent e) {
        savingThread sat = new savingThread(queryDataSet1, queryDataSet2);
        new Thread(sat).start();
    }

og tråden:
public class savingThread implements Runnable {
    QueryDataSet qdatas1;
    QueryDataSet qdatas2;
    DatabaseConnSetup dcs = new DatabaseConnSetup();
   
    savingThread(QueryDataSet qds1, QueryDataSet qds2) {
        this.qdatas1 = qds1;
        this.qdatas2 = qds2;
    }
   
    public void run() {
        dcs.database1.saveChanges(qdatas1);
        dcs.database1.saveChanges(qdatas2);
        System.out.println("Save changes succeeded");
    }

}
Avatar billede mikkelbm Nybegynder
29. juni 2005 - 23:33 #9
Jeg tvivler stadig på, at det er din tråd den er galt med.
Hvad mener du med: "Med den nye kode virker det ikke helt som om tråden kører som en tråd" ?

Det er det samme du gør. Blot kodet lidt forskelligt.
Avatar billede jsl Nybegynder
30. juni 2005 - 14:35 #10
Jeg overfører datasettene som argumenter til tråden. Det gjorde jeg ikke før. Jeg mener at programflowet afbrydes når tråden kører - ligesom hvis det var sekventielt. Det virker når tråden er i samme klasse som den kaldende kode.
Avatar billede mikkelbm Nybegynder
30. juni 2005 - 17:07 #11
Hvad hvis du gør følgende:

public void focusLost(FocusEvent e)
{
    new Thread ()
    {
        public void run ()
        {
            dcs.database1.saveChanges (queryDataSet1);
            dcs.database1.saveChanges (queryDataSet2);
        }
    }.start();
}
Avatar billede mikkelbm Nybegynder
30. juni 2005 - 17:09 #12
Det er faktisk det samme, men så er du fri for at have en ny klasse til det. Og ovenstående burde ikke have indflydelse på f.eks. gui.
Avatar billede jsl Nybegynder
01. juli 2005 - 16:37 #13
Nu opgav jeg at bruge saveChanges, og valgte istedet at lave et SQL udtryk. Her ses et uddrag af udtrykket:
Object FORNAVN = jdbTable2.getModel().getValueAt(jdbTable2.getSelectedRow(),1);
dcs.stmt.executeUpdate("UPDATE TBL_SAM_ELEV SET FORNAVN = '"+FORNAVN+"')

I forlægelse af dette spørgsmål har jeg et andet lille spørgsmål. Når jeg i en jdbTable er færdig med at redigere en celle, skal jeg enten trykke på en ny celle, eller tykke på enter. Det er også fint nok, men bare ikke hvis man ikke husker at gøre det. Jeg kunne istedet godt tænke mig en metode i min fouceslistener, der gør det i stedet for, man selv selv skal afslutte redigeringen. Hvordan laver man det? Jeg har allerede set på de forskellige metoder, der hører til jdbTable, men har endnu ikke kunne finde noget brugbart. Jeg forestiller mig noget i retningen af:
if (e.getSource() == jdbTable2) {
  if (jdbTable2.isEditing()) {
      //Et eller andet.
    }
}
Avatar billede mikkelbm Nybegynder
01. juli 2005 - 16:51 #14
Du er godt klar over, at din UPDATE opdaterer alle rækker i databasen? Mangler du ikke en WHERE ?
Avatar billede mikkelbm Nybegynder
01. juli 2005 - 16:54 #15
Og mht fokus, kan du så ikke bare give en anden komponent fokus? Selvom jeg ikke ser det som et problem, at man skal skifte celle eller trykke på enter. Sådan fungerer mange ting der bruger en tabel. I Excel skal man også trykke enter eller vælge en anden celle.
Avatar billede jsl Nybegynder
01. juli 2005 - 17:20 #16
Jo, jeg har ikke fået where med i uddraget, men jeg har det i koden :-)
Poblemet, hvis brugeren af programmet glemmer at trykke på enter, er at de sidste ændringer ikke bliver gemt. Hvis jeg selv skal bruge programmet - ja, så er jeg enig med dig mikkelbm. Måske skal jeg lave det sådan, at alt andet i programmet, såsom combobox'e og tekstbokse er disablet indtil bruger afslutter redigeringen korrekt med enter....
Avatar billede mikkelbm Nybegynder
01. juli 2005 - 18:49 #17
Hvis du har en knap, du vil bruge når du gemmer, kan du gøre følgende:

JButton save = new JButton ("Gem");
save.addActionListener( new ActionListener()
{
    public void actionPerformed (ActionEvent e)
    {
            DefaultCellEditor editor = (DefaultCellEditor)table.getCellEditor();
          if (editor != null)
                  editor.stopCellEditing();

    }
});
Avatar billede mikkelbm Nybegynder
01. juli 2005 - 18:49 #18
Det samme kan du jo gøre med en fokus listener.
Avatar billede mikkelbm Nybegynder
07. juli 2005 - 21:41 #19
Brugbart ?
Avatar billede jsl Nybegynder
08. juli 2005 - 17:51 #20
Ja, det er det. Tak for det.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester