Avatar billede mikkelbm Nybegynder
13. maj 2003 - 12:39 Der er 12 kommentarer og
1 løsning

Singleton Database tilgang

Vi har en Acces database, som vi gerne vil oprette en forbindelse til via et singleton objekt.

Vi har lavet denne kode. Men vi ved ikke hvordan vi udnytter den mht sql-forspørgsler fra eksempelvis en main...

import java.sql.*;

public final class DBadgang
{
    private static DBadgang dbadgang;
    private Statement s;
   
    private DBadgang()
    {
        try
        {
            Class.forName ("sun.jdbc.odbc.JdbcOdbcDriver");
        }
        catch (ClassNotFoundException cnfe)
        {
            System.err.println ("JDBC-ODBC driver kunne ikke findes.");
            System.exit(1);
        }

        try
        {
            Connection c = DriverManager.getConnection ("jdbc:odbc:itedderkoppen");
            s = c.createStatement();
        }
        catch (SQLException se)
        {
            System.err.println ("Forespørgslen kunne ikke udføres.");
            System.exit(2);
        }
    }
   
    public static DBadgang getDBadgang()
    {
        if (dbadgang == null)
            dbadgang = new DBadgang();
        return dbadgang;
    }
}
Avatar billede fsconsult.dk Nybegynder
13. maj 2003 - 12:45 #1
Hmmm... er ikke meget for at have "Access" og "database" i samme sætning :-)

Fra en anden klasse skal I blot benytte: DBadgang.getDBadgang()
Avatar billede mikkelbm Nybegynder
13. maj 2003 - 12:51 #2
Det er det vi gør, men vi kan ikke finde ud af at kalde "databasen".
Dvs sql-statements.
Avatar billede mikkelbm Nybegynder
13. maj 2003 - 12:55 #3
Det er eksempelvis fra en klasse som denne vi vil lave kaldende fra.

public class VareKatalog
{
    private DBadgang database;
    public VareKatalog()
    {
        database.getDBadgang();
    }
   
    public int getVareNr(int Nr)
    {
        // Her skal vi lave sql-sætningen...
    }
   
    public String getBeskrivelse(int Nr)
    {
       
    }
}
Avatar billede fsconsult.dk Nybegynder
13. maj 2003 - 12:56 #4
I mangler nogle metoder i DBadgang til at håndtere jeres SQL kald (I har jo en connection at gå ud fra).

Jeg ville nok gemme Connection objektet fremfor Statement objektet.
Avatar billede halden Nybegynder
13. maj 2003 - 12:58 #5
Prøv denne her:

import java.sql.*;

public class DatabaseConnection {
   
    // variabler
    private String username = "";  // brugerid
    private String password = "";  // kodeord for brugeren
    private Connection con;
   
   
    // *************************************************************
    //  konstruktør - skabe adgang til databasen
    // *************************************************************
    public DatabaseConnection(String input) {
        try {
            String url = "jdbc:odbc:" + input;                          // forbindel gennem denne.
            Class.forName( "sun.jdbc.odbc.JdbcOdbcDriver" );
            con = DriverManager.getConnection(url, username, password); // Log ind i database
            con.setAutoCommit(true);                                    // autogem - funktion
        }
        catch (Exception e) {
            System.out.println("Kunne ikke initialisere JDBC connection. " + e);
        }
   
    }// end DBconnection
   
    // *************************************************************
    //  funktion til at lukke databasen!
    // *************************************************************
    public void closeDB() {
        try {
            con.close();
        }
        catch (SQLException e) {
            System.out.println("Kunne ikke lukke connection. " + e);
        }
               
    }// end closeDB   
   
    // *************************************************************
    //  funktion at lave insert, update og delete i database.
    //    Den bruges fordi der ikke kommer et output ud fra DB igen.
    //
    // *************************************************************
    public int exeUpdate(String sqlstring) {
        int tal = 0;
                try {
            Statement stmt = con.createStatement(); // byg et nyt statement
            tal = stmt.executeUpdate(sqlstring);    // eksekvere update i databasen
            con.commit();                          // sikre commit
        }
        catch (SQLException e) {
            System.out.println("Kunne ikke opdatere i DB. " + e);
        }
                return tal;
               
    }// end exeUpdate
   
    // *************************************************************
    //  Funktion at lave select statements i database.
    //    Der kommer et resultset tilbage fra funktionen.
    //
    // *************************************************************
    public ResultSet exeQuery(String sqlstring) {
        ResultSet rs = null;
        try {
            Statement stmt = con.createStatement(); // byg et nyt statement
            rs = stmt.executeQuery(sqlstring);      // flytter data fra tabel over i resultset   
            con.commit();                          // sikre commit
        }
        catch (SQLException e) {
            System.out.println("Kunne ikke udtage data fra DB. " + e);
        }
        return rs;
               
    } // end exeQuery
       
}// class DatabaseConnection
Avatar billede fsconsult.dk Nybegynder
13. maj 2003 - 12:58 #6
I kunne måske nøjes med at lave en "getConnection" metode.



Det er eksempelvis fra en klasse som denne vi vil lave kaldende fra.

public class VareKatalog
{
    private DBadgang database;
    public VareKatalog()
    {
        database = DBadgang.getDBadgang();
    }
   
    public int getVareNr(int Nr)
    {
        Connection conn = database.getConnection();
        // Her skal vi lave sql-sætningen...     
    }
   
    public String getBeskrivelse(int Nr)
    {
       
    }
}
Avatar billede mikkelbm Nybegynder
13. maj 2003 - 13:07 #7
Vi har fået det til at virke med inspiration fra jer begge - tak for det.
Vi bibeholder vores Singleton og laver så nogle get-metoder dertil.
Avatar billede arne_v Ekspert
13. maj 2003 - 19:05 #8
Overvej *meget* grundigt hvordan jeres klasse vil virke
i et multi-threaded environment.

En connection pool er en oplagt singleton.

Men hverken connection eller statement er særligt
egnede som singletons.
Avatar billede mikkelbm Nybegynder
13. maj 2003 - 21:07 #9
Du skriver at en connection pool er en oplagt singleton.
Hvordan fungerer den?
Har du evt. et eksempel?
Avatar billede arne_v Ekspert
13. maj 2003 - 22:56 #10
En singleton i et multi-threaded environment vil have multiple
threads som samtidigt bruger det samme objekt.

Med Connection og Statement så kan det gå grueligt galt.

Med en connection pool som har N connections som threads kan
acquire og release igen, så er singleton lige det man skal bruge.

Eller er det en connection pool implementation I leder efter ?
Avatar billede mikkelbm Nybegynder
13. maj 2003 - 23:43 #11
Jeg må indrømme, at jeg ikke er så meget inde i brugen at patterns og de klasser der hører til. Så du bliver nok nødt til at uddybe dig lidt nærmere.
Det skal måske lige siges, at det er et simpelt system med kun én bruger.
Jeg ved ikke om det gør nogen forskel mht. connection pool???
Avatar billede arne_v Ekspert
13. maj 2003 - 23:46 #12
Hvis der kun er en bruger og database kun skal bruges i en tråd, så
har I næppe brug for en connection pool, og I får ikke problemer
med jeres klasse.
Avatar billede mikkelbm Nybegynder
13. maj 2003 - 23:50 #13
Fint. Det andet med flere tråde er vist et niveau for højt endnu.
Men tak fordi du gjorde os opmærksom på 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