Avatar billede martin_schou Nybegynder
28. september 2001 - 12:30 Der er 17 kommentarer og
3 løsninger

Databasetilgang

Hvordan laver I databasetilgang?

Jeg har selv en databasepakke, som jeg er ganske godt tilfreds med, men jeg ville gerne se, hvordan andre håndterer databaser - det kan jo være, jeg kunne blive inspireret og få ideer til forbedringer af mit eget.

I _behøver_ ikke poste nogen kode, men blot en simpel gennemgang af hvordan det virker.

Ved ikke helt om 30 points er for meget eller for lidt, for jeg har en løsning, der virker, men på den anden side set synes jeg, det kunne være sjovt at se andres løsninger.   

Min løsning er som følger:

Jeg har tre klasser i en pakke kaldet Database:

DatabaseProxy - håndterer adgangen til en enkelt database (eller den samme database med forskellige logins og/eller passwords)

TabelObjekt - databærende klasse for klasser udenfor Database-pakken; laver kald ned i SQLInterface, når der skal laves søgninger.

SQLInterface - udvidet singleton-klasse (der er kun een instans per ODBCNavn+Login+Password), som snakker med databasen.

Al magien ligger for så vidt i TabelObjekt. Når DatabaseProxy startes op forbinder den med databasen (via SQLInterface) og får en oversigt over tabeller og tabellernes udseende (metadata). Disse informationer bruger DatabaseProxy til at lave en TabelObjekt-skabelon for hver tabel. Disse skabeloner er nu skrædersyet til hver tabel.

Når der søges, laves en klon af den relevante tabel (hvis der skal søges i flere tabeller, laves der en klon af hver af de relevante tabeller; disse kloner samles i et enkelt objekt, som passer \"ned over\" de relevante tabeller). Dette klon-objekt laver nu et kald til SQLInterface, som returnerer et java.sql.resultSet. Dette resultset tømmes for data, som gemmes i et to-dimensionelt array i TabelObjekt-objektet (ja - TabelObjekt er et tåbeligt navn).

Når dette er tilendebragt, returneres TabelObjekt-objektet til den forespørgende klasse, som kan hente alle relevante informationer ud af den:
Tabelfeltnavne (med de relevante tabelnavne som præfix, f.eks. \"Tabelnavn.Tabelfeltnavn\")
Tabelnavne
Tabelfeltdatatyper
En enkelt resultatrække
Hele resultatsættet (alle søgeresultater)

Den største ulempe, jeg har fundet, ved dette system, er at hvis jeg laver en join-søgning, så ender jeg ofte med flere ens resultatrækker ... det har jeg ikke lige fundet en løsning på endnu ... 
Avatar billede disky Nybegynder
28. september 2001 - 14:10 #1
den med flere af samme, brug Distinct i din sql streng
Avatar billede johanls Nybegynder
01. oktober 2001 - 20:41 #2
Hejsa jeg vil gerne komme med et lille \"design pattern\" jeg bruger til at koble mig op til en database. Det er dog således at java understøtter mange databaser. Det er sådan at jeg enten bruger en JDBC-ODBC bro eller endnu bedre hvis det findes til den database jeg vil arbejde med en specifik driver til denne database.

Brug af java.sql.*; på en interbase-db
1. Connection-objekt skabes.
a)direkt forbindelse:
final String driver =\"interbase.interclient.Driver\";
Class.forName(driver);//driver indlæses
DriverManager.getConnection(databaseURL, username, password);//lægges over i connection objekt!
b)via ODBC:
final String driver= \"sun.jdbc.odbc.JdbcOdbcDriver\";//jdbcodbc-bro
final String datbaseUrl = \"jdbc.odbc.employee\";
Class.forName(driver);
DriverManager...osv
2. lav en query:
Statement statement = connection.createStatement();
ResultSet resultSet statement.executeQuery(String query);//executeUpdate(query) for opdatering af //tabel eller tuple

Husk at lukke resultset, statement og connection med .close();

:-)
Avatar billede disky Nybegynder
02. oktober 2001 - 08:30 #3
johanls: det er ikke et design pattern, det er din implementation :))

Martin_Schou:
Hvad er det lige du vil ? VIl du se hvordan vi connecter til databaser eller hvad ?
Avatar billede martin_schou Nybegynder
02. oktober 2001 - 08:43 #4
ja, det var pointen, og det kunne måske også være en hjælp til andre brugere, som ikke kan få deres databasetilgang til at virke ordentligt, eller synes at deres tilgang er for besværligt.

som jeg skrev: \"jeg [synes], det kunne være sjovt at se andres løsninger.\"

Jeg kan godt poste al koden i min implementation, hvis I gerne vil se den ...
Avatar billede disky Nybegynder
02. oktober 2001 - 08:48 #5
du skriver også: I _behøver_ ikke poste nogen kode

Derfor har jeg ikke postet kode, du skal ikke poste din kode for min skyld, jeg har en velfungerende database klasse, som jeg bruger.

Men du må gerne se den hvis du vil
Avatar billede martin_schou Nybegynder
02. oktober 2001 - 08:54 #6
En beskrivelse af hvordan du gør, vil være godt nok ... det giver ofte bedre ideer end 10.000 linjer kode :-D

Bare for at vise min \"gode\" vilje, så smider jeg da lige koden til min database-pakke; den er stadig under udvikling, men den virker :-)

De ryger i hver deres kommentar.
Avatar billede martin_schou Nybegynder
02. oktober 2001 - 08:54 #7
package Database;

import Exceptions.CreationException;
import Exceptions.SQLStatementException;
import Exceptions.CannotCloneException;
import Exceptions.BuildSQLException;

import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.ResultSetMetaData;
import java.util.Vector;

public class DatabaseProxy
{
  private SQLInterface DBConnection;
  private Vector SkabelonListe;
  private Vector TabelnavneListe;

 
  public DatabaseProxy(String ODBCNavn, String Login, String Password) throws CreationException
  {
    DBConnection = SQLInterface.instantiate( ODBCNavn, Login, Password );
    SkabelonListe = new Vector();
    TabelnavneListe = new Vector();
    //System.out.println( \"SOMEONE SET UP US THE DBConnection\" );
    indlæsTabelModeller(); 
  }
 
  public DatabaseProxy(String ODBCNavn) throws CreationException
  {
    this( ODBCNavn, null, null );//dirigér kaldet videre til den avancerede constructor
  }
 
  public void indlæsTabelModeller()
  {
    //try-catch skal forbedres.
    /////////////////////////////////
    // Generer ud fra DB meta-data //
    /////////////////////////////////
    try
    {
        DatabaseMetaData DBMetaData = DBConnection.getMetaData();
        ResultSet resTablesQuery = DBMetaData.getTables( null, null, null, new String[] {\"TABLE\"} );
        ResultSetMetaData resTablesQueryMeta = resTablesQuery.getMetaData();
       
        //empty resTablesQuery.TABLE_NAME into vector
        Vector templager = new Vector();
        while ( resTablesQuery.next() )
        {
                String Table_Name = resTablesQuery.getString( \"TABLE_NAME\" );
            templager.add( Table_Name );
                TabelnavneListe.add( Table_Name );
        }
        //translate vector() to String[]
        String[] Tabeller = new String[templager.size()];
        for ( int index = 0; index < Tabeller.length; index++ )
        {
            Tabeller[index] = (String) templager.elementAt( index );
        }
       
      // get Misc Data fields for Tables
        for ( int index = 0; index < Tabeller.length; index++ )
        {
            ResultSet resColumnsQuery = DBMetaData.getColumns( null, null, Tabeller[index], null );
            ResultSetMetaData resColumnsQueryMeta =  resColumnsQuery.getMetaData();
           
            //empty resColumnsQuery.COLUMN_NAME & DATA_TYPE into vector
            Vector tempLagerNavn = new Vector();
            Vector tempLagerType = new Vector();
            while ( resColumnsQuery.next() )
            {
                tempLagerNavn.add( resColumnsQuery.getString( \"COLUMN_NAME\" ) );
                tempLagerType.add( new Integer( resColumnsQuery.getInt( \"DATA_TYPE\" ) ) );
            }
            //translate vector()\'s to String[]\'s
            String[] FeltNavne = new String[tempLagerNavn.size()];
            int[] DataTyper = new int[tempLagerType.size()];
            for ( int index2 = 0; index2 < DataTyper.length; index2++ )
            {
                FeltNavne[index2] =  (String) tempLagerNavn.elementAt( index2 );
                DataTyper[index2] = ( (Integer) tempLagerType.elementAt( index2 ) ).intValue();
            }
            LavTabelObjektSkabelon( new String[] { Tabeller[index] }, FeltNavne, DataTyper, new boolean[0] );
        } // end for ( over tabeller[] )
       
    } // end try
    catch ( java.sql.SQLException e )
    {
        e.printStackTrace();
    }
  }

  public void Opret(String Tabel, String[][] opretParametre) throws SQLStatementException
  {
    try
      {
        TabelObjekt tempObjekt = getClone( Tabel );
        tempObjekt.insert( opretParametre );
      }
    catch( CannotCloneException e )
      {
        throw new SQLStatementException( \"That table does not exist in the database.\" );
      } 
    catch( BuildSQLException e )
      {
        throw new SQLStatementException( e.toString() );
      }   
  //System.out.println( \"LAUNCH EVERY \'NEW ENTRY\'\" );
  }
 
  public void Opdater(String Tabel, String[][] opdateringsParametre, String[][] Kriterier) throws SQLStatementException
  {
    try
      {
      TabelObjekt tempObjekt = getClone( Tabel );
      tempObjekt.update( opdateringsParametre, Kriterier );
      }
    catch( CannotCloneException e )
      {
        throw new SQLStatementException( \"That table does not exist in the database.\" );
      } 
    catch( BuildSQLException e )
      {
        throw new SQLStatementException( e.toString() );
      } 
    //System.out.println( \"MOVE \'ENTRY\'. FOR GREAT JUSTICE\" );
  }
 
  public void Slet(String Tabel, String[][] sletParametre) throws SQLStatementException
  {
    try
      {
        TabelObjekt tempObjekt = getClone( Tabel );
        tempObjekt.delete( sletParametre );
      }
    catch( CannotCloneException e )
      {
        throw new SQLStatementException( \"That table does not exist in the database.\" );
      }
    catch( BuildSQLException e )
      {
        throw new SQLStatementException( e.toString() );
      }
    //System.out.println( \"YOU HAVE NO CHANCE TO SURVIVE MAKE YOUR TIME\" ); 
  }
 
  public void ManuelSQLManipulation( String SQLString ) throws SQLStatementException
    {
      DBConnection.update( SQLString );
    }

  public TabelObjekt Søg(String[] Tabeller, String SQLString ) throws SQLStatementException
  {
    if( Tabeller.length == 1 ) //hvis der kun skal søges i en enkelt tabel.
      {
        try
          {
            TabelObjekt tempObjekt = getClone( Tabeller[0] );
            tempObjekt.select( SQLString );
            return tempObjekt;
          }
        catch( CannotCloneException e )
          {
            throw new SQLStatementException( \"The table  [\" + Tabeller[0] + \"] does not exist in the database.\" );
          }
      }
    else if ( Tabeller.length > 1 ) // hvis der skal søges i flere tabeller på een gang.
      {
        Vector TabelObjektListe = new Vector();
        for( int index = 0 ; index < Tabeller.length ; index++ )
          {
            try
              {
                TabelObjektListe.add( getClone( Tabeller[index] ) );
                //ingen problemer
              }
            catch( CannotCloneException e )
              {
                throw new SQLStatementException( \"That table does not exist in the database.\" );
              } 
          }
        TabelObjekt primærObjekt = (TabelObjekt) TabelObjektListe.elementAt(0);
        TabelObjekt[] sekundærObjektArray = new TabelObjekt[ TabelObjektListe.size() - 1 ];
        for( int index = 1 ; index < TabelObjektListe.size() ; index++ )
          {
            sekundærObjektArray[index - 1 ] = (TabelObjekt) TabelObjektListe.elementAt(index);
          }
        primærObjekt.join( sekundærObjektArray );
        primærObjekt.select( SQLString );

        return primærObjekt;
      } 
    else
      {
        throw new SQLStatementException( \"Please state at least one table to search.\" );
      } 
    //System.out.println(\"WE GET TabelObjekt\");
  } 
 
  public TabelObjekt Søg(String[] Tabeller, String[][] søgeParametre, String[][] joinParametre) throws SQLStatementException
  {
    if( Tabeller.length == 1 ) //hvis der kun skal søges i en enkelt tabel.
      {
        try
          {
            TabelObjekt tempObjekt = getClone( Tabeller[0] );
            tempObjekt.select( søgeParametre, joinParametre );
            return tempObjekt;
          }
        catch( CannotCloneException e )
          {
            throw new SQLStatementException( \"The table  [\" + Tabeller[0] + \"] does not exist in the database.\" );
          }
        catch( BuildSQLException e )
          {
            throw new SQLStatementException( e.toString() );
          } 
      }
    else if ( Tabeller.length > 1 ) // hvis der skal søges i flere tabeller på een gang.
      {
        Vector TabelObjektListe = new Vector();
        for( int index = 0 ; index < Tabeller.length ; index++ )
          {
            try
              {
                TabelObjektListe.add( getClone( Tabeller[index] ) );
                //ingen problemer
              }
            catch( CannotCloneException e )
              {
                throw new SQLStatementException( \"That table does not exist in the database.\" );
              } 
          }
        TabelObjekt primærObjekt = (TabelObjekt) TabelObjektListe.elementAt(0);
        TabelObjekt[] sekundærObjektArray = new TabelObjekt[ TabelObjektListe.size() - 1 ];
        for( int index = 1 ; index < TabelObjektListe.size() ; index++ )
          {
            sekundærObjektArray[index - 1 ] = (TabelObjekt) TabelObjektListe.elementAt(index);
          }
        primærObjekt.join( sekundærObjektArray );
        try
          {
            primærObjekt.select( søgeParametre, joinParametre );
          }
        catch( BuildSQLException e )
          {
            throw new SQLStatementException( e.toString() );
          } 
        return primærObjekt;
      } 
    else
      {
        throw new SQLStatementException( \"Please state at least one table to search.\" );
      } 
    //System.out.println(\"WE GET TabelObjekt\");
  }
 
  private TabelObjekt LavTabelObjektSkabelon(String[] TabelNavn, String[] FeltNavne, int[] DataType, boolean[] ErNøgle)
  {
    //System.out.println( \"TabelObjekt TURN ON!!\" ); 
    //vi behøver ikke at tjekke længden på TabelNavn, da vi VED at indholdet kun er een lang.
    //kaldet kan nemlig kun laves fra denne klasse, så hvis der laves ged i kaldet
    //så er det fordi nogle idioter har ændret koden, og så er de selv uden om det.
   
    //herfra
    String[] _TabelNavn = new String[TabelNavn.length];
    String[] _FeltNavne = new String[FeltNavne.length];
    int[] _DataType = new int[DataType.length];
    boolean[] _ErNøgle = new boolean[ErNøgle.length];

    for( int index = 0 ; index < _TabelNavn.length ; index++ )
      {
        _TabelNavn[index] = new String( TabelNavn[index] );
      }
    for( int index = 0 ; index < _FeltNavne.length ; index++ )
      {
        _FeltNavne[index] = new String( _TabelNavn[0] + \".\" + FeltNavne[index] );
      } 
    for( int index = 0 ; index < _DataType.length ; index++ )
      {
        _DataType[index] = DataType[index];
      }
    for( int index = 0 ; index < _ErNøgle.length ; index++ )
      {
        _ErNøgle[index] = ErNøgle[index] ;
      } 
    //og hertil kan muligvis erstattes af div .clone() metoder,
    //men da vi ikke er sikre på at clone() laver deepcopy,
    //har vi valgt at lave det selv.
    TabelObjekt NySkabelon = new TabelObjekt( null, _TabelNavn, _FeltNavne, _DataType, _ErNøgle ) ;

    addSkabelon( NySkabelon );
    return NySkabelon;
  }

  private void addSkabelon( TabelObjekt NySkabelon )
    {
      boolean tabelFindes = false;
      try
        {
          getClone( NySkabelon.getTabelNavn()[0] );
          tabelFindes = true;
        }
      catch( CannotCloneException e )
        {
        tabelFindes = false;
        }
       
      if(  tabelFindes )
        {
         
        }
      else
        {
        for( int index = 0 ; index < SkabelonListe.size() ; index++ )
          {
            TabelObjekt TempObjekt = (TabelObjekt) SkabelonListe.elementAt(index);
            String navnTemp = TempObjekt.getTabelNavn()[0];
            String navnNy = NySkabelon.getTabelNavn()[0];
            if ( navnTemp.equalsIgnoreCase( navnNy ) )
              {
                SkabelonListe.removeElementAt(index);
                SkabelonListe.add( NySkabelon );
                break;
              }
          }
      }
      SkabelonListe.add( NySkabelon );
    }
 
 
  private TabelObjekt getClone(String TabelNavn) throws CannotCloneException
  {
    for( int index = 0 ; index < SkabelonListe.size() ; index++ )
      {
        //skabelonerne kan aldrig repræsentere mere end een tabel.
        //derfor kan vi nøjes med at tjekke index 0
        TabelObjekt tempObjekt = (TabelObjekt) SkabelonListe.elementAt( index );
        if( TabelNavn.equalsIgnoreCase( tempObjekt.getTabelNavn()[0] ) )
          {
            return tempObjekt.clone( DBConnection );
          }
      }
    throw new CannotCloneException(\"Der findes ikke en skabelon over den tabel. Lav en ny TabelObjektSkabelon.\");
  }
 
  public Vector getTabelnavneListe()
  {
    return TabelnavneListe;
  }
}
Avatar billede martin_schou Nybegynder
02. oktober 2001 - 08:55 #8
package Database;

import Exceptions.BuildSQLException;

/**
Klasse med en masse Static metoder til at oversætte vores tabeldata til SQL-sætninger
*/
class SQLBuilder
{
 
  /***********************************************************\\
  |* DELETE DELETE DELETE DELETE DELETE DELETE DELETE DELETE *|
  \\***********************************************************/
  public String BuildDeleteSQL(String[] Tabelnavne, String[][] Kriterier) throws BuildSQLException
  {
    int antalTabeller, antalKriterier = 0;
    String OutputString = new String(\"\");
 
    try { antalTabeller = Tabelnavne.length; }
    catch ( NullPointerException E ) { return new String( \"\" ); }

    try { antalKriterier = Kriterier.length; }
    catch ( NullPointerException E ) { antalKriterier = 0; }

    if ( antalTabeller > 0 )
    {
      //Command
      OutputString = append( OutputString, \"DELETE * FROM\" );

      //source
      OutputString = append( OutputString, Tabelnavne[0] );
      for ( int index = 1; index < antalTabeller; index++ )
      {
        OutputString = append( OutputString, \", \" + Tabelnavne[index] );
      }

      //Criteria
      if ( antalKriterier > 0 )
      {
        OutputString = append( OutputString, \"WHERE (\" );
        for ( int index = 0; index < antalKriterier; index++ )
        {
          if ( index != 0 )
          {
            OutputString = append( OutputString, Kriterier[index][0] );
          }
          OutputString = append( OutputString, Kriterier[index][1] );
          OutputString = append( OutputString, Kriterier[index][2].toUpperCase() );
          OutputString = append( OutputString, Kriterier[index][3] );
        }
        OutputString = append( OutputString, \")\" );
      }
    } 
/***************************************************/
    //System.out.println( OutputString ); 
    return OutputString;
  }
 
  /***********************************************************\\
  |* INSERT INSERT INSERT INSERT INSERT INSERT INSERT INSERT *|
  \\***********************************************************/
  public String BuildInsertSQL(String Tabelnavn, String[][] Kriterier) throws BuildSQLException
  {
    int antalKriterier = 0;
    String OutputString = new String(\"\");
 
    try { antalKriterier = Kriterier.length; }
    catch ( NullPointerException E ) { antalKriterier = 0; }

    if ( antalKriterier > 0 )
      {
        OutputString = append( OutputString, \"INSERT INTO\" );
        OutputString = append( OutputString, Tabelnavn );
        OutputString = append( OutputString, \"(\" );
        for ( int index = 0 ; index < antalKriterier ; index++ )
          {
            OutputString = append( OutputString, Kriterier[index][0]  );
            if ( index < antalKriterier - 1 )
              {
                OutputString = append( OutputString, \",\" );
              }
          }
        OutputString = append( OutputString, \") VALUES (\"  );
        for (int index = 0 ; index < antalKriterier ; index++ )
          {
            OutputString = append( OutputString, Kriterier[index][1]  );
            if ( index < antalKriterier - 1 )
              {
                OutputString = append( OutputString, \",\" );
              }
          } 
        OutputString = append( OutputString, \");\"  ); 
      }
/***************************************************/
    //System.out.println( OutputString ); 
    return OutputString;
  }
 
  /***********************************************************\\
  |* SELECT SELECT SELECT SELECT SELECT SELECT SELECT SELECT *|
  \\***********************************************************/
  public String BuildSelectSQL(String[] Tabelnavne, String[][] Kriterier, String[][] JoinKriterier) throws BuildSQLException
  {
    int antalTabeller, antalKriterier, antalJoinKriterier = 0;
    String OutputString = new String(\"\");
 
    try { antalTabeller = Tabelnavne.length; }
    catch ( NullPointerException E ) { return new String( \"\" ); }

    try { antalKriterier = Kriterier.length; }
    catch ( NullPointerException E ) { antalKriterier = 0; }

    try { antalJoinKriterier = JoinKriterier.length; }
    catch ( NullPointerException E ) { antalJoinKriterier = 0; }

    if ( antalTabeller > 0 )
    {
      //Command
      OutputString = append( OutputString, \"SELECT * FROM\" );

      //source
      OutputString = append( OutputString, Tabelnavne[0] );
      if ( antalTabeller > 1 )// antalTabeller = 2
        {
          for ( int index = 1; index < antalTabeller /* antalTabeller antalTabeller = 2 */ ; index++ )
          {
            OutputString = append( OutputString, \", \" + Tabelnavne[index] );
          }
        }

      //Criteria
      if ( antalKriterier > 0 )
      {
        OutputString = append( OutputString, \"WHERE (\" );
        for ( int index = 0; index < antalKriterier; index++ )
        {
          if ( index != 0 )
          {
            OutputString = append( OutputString, Kriterier[index][0].toUpperCase() );
          }
          OutputString = append( OutputString, Kriterier[index][1] );
          OutputString = append( OutputString, Kriterier[index][2].toUpperCase() );
          OutputString = append( OutputString, Kriterier[index][3] );
          if ( Kriterier[index][4] != null )
          {
            OutputString = append( OutputString, \"AS \" + Kriterier[index][4] );
          }               
        }
        OutputString = append( OutputString, \")\" );
      }
     

      //Join Criteria
      if ( antalJoinKriterier > 0 )
      {
        if ( antalKriterier != 0 )
        {
          OutputString = append( OutputString, \"AND (\" );
        }
        for ( int index = 0; index < antalJoinKriterier; index++ )
        {
          if ( index != 0 )
          {
            OutputString = append( OutputString, JoinKriterier[index][0].toUpperCase() );
          }
          OutputString = append( OutputString, JoinKriterier[index][1] );
          OutputString = append( OutputString, \"=\" );
          OutputString = append( OutputString, JoinKriterier[index][2] );
        }
        OutputString = append( OutputString, \")\" );
      }

      //end
      OutputString = append( OutputString, \";\" );
    }
    else
    {
      return new String(\"\");
    }
/***************************************************/
    //System.out.println( OutputString ); 
    return OutputString;
  }
 
  /***********************************************************\\
  |* UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE UPDATE *|
  \\***********************************************************/
  public String BuildUpdateSQL(String Tabelnavn, String[][] Værdier, String[][] Kriterier) throws BuildSQLException
  {
    int antalKriterier, antalVærdier;
    String OutputString = new String(\"\");
   
    try { antalVærdier = Værdier.length; }
    catch ( NullPointerException E ) { return OutputString; }
   
    try { antalKriterier = Kriterier.length; }
    catch ( NullPointerException E ) { return OutputString; }
   
    OutputString = append( OutputString, \"UPDATE \" + Tabelnavn + \" SET\" );
    for ( int index = 0; index < antalVærdier; index++ )
    {
      OutputString = append( OutputString, Værdier[index][0] + \" = \" + Værdier[index][1] );
      if ( index < antalVærdier - 1 )
      {
        OutputString = append( OutputString, \",\");
      }
    }
   
    OutputString = append( OutputString, \"WHERE\");
    for ( int index = 0; index < antalKriterier; index++ )
    {
      if ( index != 0 )
      {
        OutputString = append( OutputString, Kriterier[index][0].toUpperCase() );
      }
      OutputString = append( OutputString, Kriterier[index][1] );
      OutputString = append( OutputString, Kriterier[index][2].toUpperCase() );
      OutputString = append( OutputString, Kriterier[index][3] );
    }
/***************************************************/
    //System.out.println( OutputString );
    return OutputString;
  }
 
  private String append(String OutputString, String appendedText)
  {
    return OutputString.concat( appendedText + \" \" );
  }
}
Avatar billede martin_schou Nybegynder
02. oktober 2001 - 08:55 #9
package Database;

import Exceptions.CreationException;
import Exceptions.SQLStatementException;

import java.sql.DriverManager;
import java.sql.Statement;
import java.sql.SQLException;
import java.sql.ResultSet;
import java.sql.DatabaseMetaData;
import java.sql.Connection;

import java.util.LinkedList;

class SQLInterface
{
  private String ODBCNavn;
  private String Login;
  private Connection DBConnection;
  private static LinkedList Instanser = new LinkedList();
 
  static
    {
      try
        {
          Class.forName(\"sun.jdbc.odbc.JdbcOdbcDriver\");
        }
      catch ( Exception e )
        {
          System.out.println( \"Could not load JDBC-ODBC Driver\" );
        }
    }
 
  public static SQLInterface instantiate(String ODBCNavn, String login, String password) throws CreationException
  {
    SQLInterface instans;
 
    for( int index = 0 ; index < Instanser.size() ; index++ )
      {
        instans = (SQLInterface) Instanser.get( index );
        if( ODBCNavn.equalsIgnoreCase( instans.getODBCNavn() ) ) //ODBCNavnene er ens
          {
            if ( login != null && instans.getLogin() != null )  //Der er et login angivet begge steder
              {
                if ( login.equalsIgnoreCase( instans.getLogin() ) ) //Login er det samme begge steder
                  {
                    return instans;
                  }
              } 
            else if ( login == null && instans.getLogin() == null ) //Der er ikke noget login nogen steder
              {
                return instans;
              } 
          }
      }
    instans = new SQLInterface( ODBCNavn, login, password );
    Instanser.add( instans );
    return instans; 
  }
 
  public static SQLInterface instantiate(String ODBCNavn) throws CreationException
  {
    return instantiate( ODBCNavn, null, null );
  }
 
  private SQLInterface(String _ODBCNavn, String login, String password) throws CreationException
  {
    ODBCNavn = \"jdbc:odbc:\" + _ODBCNavn;
    Login = login;
    try
      {
        if ( login != null )
          {
            DBConnection = DriverManager.getConnection( ODBCNavn, Login, password );
          }
        else
          {
            DBConnection = DriverManager.getConnection( ODBCNavn );
          } 
      }
    catch( SQLException e )
      {
        throw new CreationException( e.toString( ) );
      }
  }
 
  public DatabaseMetaData getMetaData() throws SQLException
  {
    return DBConnection.getMetaData();
  }
 
  public ResultSet select(String SQLString) throws SQLStatementException
  {
    try
      {
        Statement SQLStatement = DBConnection.createStatement();
        java.sql.ResultSet resultat = SQLStatement.executeQuery( SQLString );
        //SQLStatement.close();
        return resultat;
      }
    catch( SQLException e )
      {
        throw new SQLStatementException( e.toString() + \"\\r\\n\" + SQLString );
      } 
  }
 
  /**
Denne metode er til delete-, insert- og updatekald, da disse ikke returnerer et java.sql.ResultSet.
  */
  public void update(String SQLString) throws SQLStatementException
  {
    try
      {
        Statement SQLStatement = DBConnection.createStatement();
        SQLStatement.executeUpdate( SQLString );
        SQLStatement.close();
        DBConnection.commit();
      }
    catch( SQLException e )
      {
        throw new SQLStatementException( e.toString() + \"\\r\\n\" + SQLString );
      } 
  }
 
  public String getODBCNavn()
  {
    return ODBCNavn;
  }
 
  public String getLogin()
  {
    return Login;
  }
}
Avatar billede martin_schou Nybegynder
02. oktober 2001 - 08:55 #10
package Database;

import java.sql.Types;
import java.sql.SQLException;
import java.sql.ResultSet;

import java.util.Vector;

import Exceptions.SQLStatementException;
import Exceptions.BuildSQLException;

//import Protokol.Data;

/**
Da vi ikke kan extende java.sql.Types (den har en private constructor), har vi valgt at kopiere ale variablerne fra java.sql.Types i stedet, da det er meningen, at brugere ikke skal importere noget fra java.sql-pakken.
*/
public class TabelObjekt extends Thread
{
/**
Da vi ikke kan extende java.sql.Types (den har en private constructor), har vi valgt at kopiere ale variablerne fra java.sql.Types i stedet, da det er meningen, at brugere ikke skal importere noget fra java.sql-pakken.
*/
  //<begin public static final>
  public static final int BIT = Types.BIT;
  public static final int TINYINT = Types.TINYINT;
  public static final int BIGINT = Types.BIGINT;
  public static final int LONGVARBINARY = Types.LONGVARBINARY;
  public static final int VARBINARY = Types.VARBINARY;
  public static final int BINARY = Types.BINARY;
  public static final int LONGVARCHAR = Types.LONGVARCHAR;
  public static final int NULL = Types.NULL;
  public static final int CHAR = Types.CHAR;
  public static final int NUMERIC = Types.NUMERIC;
  public static final int DECIMAL = Types.DECIMAL;
  public static final int INTEGER = Types.INTEGER;
  public static final int SMALLINT = Types.SMALLINT;
  public static final int FLOAT = Types.FLOAT;
  public static final int REAL = Types.REAL;
  public static final int DOUBLE = Types.DOUBLE;
  public static final int VARCHAR = Types.VARCHAR;
  public static final int DATE = Types.DATE;
  public static final int TIME = Types.TIME;
  public static final int TIMESTAMP = Types.TIMESTAMP;
  public static final int OTHER = Types.OTHER;
  public static final int JAVA_OBJECT = Types.JAVA_OBJECT;
  public static final int DISTINCT = Types.DISTINCT;
  public static final int STRUCT = Types.STRUCT;
  public static final int ARRAY = Types.ARRAY;
  public static final int BLOB = Types.BLOB;
  public static final int CLOB = Types.CLOB;
  public static final int REF = Types.REF;
  //<end public static final>
 
  private String[] TabelNavn;
  private String[] TabelFeltNavne;
  private int[] TabelFeltDataType;
  private boolean[] TabelFeltErNøgle;
  private int Pointer;
  private String[][] RecordSet;
  private SQLInterface DBConnection;
 
  /**
Denne metode er protected, da den kun skal kunne bruges af klasser fra Database-package, hvilket reelt set vil sige, at den kun kan kaldes af enten TabelObjekt eller DatabaseProxy.
  @roseuid 3A9CD05A0271
  */
  protected TabelObjekt(SQLInterface _DBConnection, String[] _TabelNavn, String[] _FeltNavne, int[] _DataType, boolean[] _ErNøgle)
  {
    DBConnection = _DBConnection;
    TabelNavn = _TabelNavn;
    TabelFeltNavne = _FeltNavne;
    TabelFeltDataType = _DataType;
    TabelFeltErNøgle = _ErNøgle;
    Pointer = -1;
  }
 
 
  /**
Denne metode er protected, da den kun skal kunne bruges af klasser fra Database-package, hvilket reelt set vil sige, at den kun kan kaldes af enten TabelObjekt eller DatabaseProxy.
  @roseuid 3A9CCF1301D4
  */
  protected void select(String SQLString)
    {
      ResultSet resultat = null;
      boolean søgningGennemført = false;
      try
        {
          resultat = DBConnection.select( SQLString );
          søgningGennemført = true;
        }
      catch ( /*SQLStatement*/Exception e )
        {
          e.printStackTrace();
        } 
      if ( søgningGennemført ) 
        {
          try
            {
            Vector templager = new Vector();
            while ( resultat.next() )
              {
                String[] tempArray = new String[TabelFeltNavne.length];

                for( int indexVandret = 0 ; indexVandret < TabelFeltNavne.length ; indexVandret++ )
                  {
                    try
                      {
                        if ( TabelFeltDataType[indexVandret] != TIMESTAMP )
                          {
                            tempArray[indexVandret] = new String( \"\" + resultat.getString( indexVandret + 1 ) );
                          }
                        else
                          {
                            tempArray[indexVandret] = new String( \"\" + resultat.getTimestamp( indexVandret + 1 ) );
                            //System.out.println( tempArray[indexVandret] );
                          }
                      }
                    catch( java.sql.SQLException e )
                      {
                        System.out.println( \"Nullpointer - \" + TabelFeltNavne[indexVandret] );
                      } 
                  }

                templager.add( tempArray ); 
                try{sleep(1);}catch(InterruptedException e){};
              }
            RecordSet = new String[templager.size()][TabelFeltNavne.length];
            for( int index = 0 ; index < templager.size() ; index++ )
              {
                RecordSet[index] = (String[]) templager.elementAt(index);
              }
            //          System.out.println( \"søgningen gav [\" + RecordSet.length + \"] resulater\"  );
            resultat.close();
            }
          catch( SQLException e )
            {
              e.printStackTrace();
            } 
        }   
    }
  /**
Denne metode er protected, da den kun skal kunne bruges af klasser fra Database-package, hvilket reelt set vil sige, at den kun kan kaldes af enten TabelObjekt eller DatabaseProxy.
  @roseuid 3A9CCF1301D4
  */
  protected void select(String[][] SøgeParametre, String[][] JoinParametre) throws BuildSQLException
    {
        SQLBuilder Builder = new SQLBuilder();
        String SQLString = Builder.BuildSelectSQL( TabelNavn, SøgeParametre, JoinParametre );
        select( SQLString );
    }
 
  /**
Denne metode er protected, da den kun skal kunne bruges af klasser fra Database-package, hvilket reelt set vil sige, at den kun kan kaldes af enten TabelObjekt eller DatabaseProxy.
  @roseuid 3A9CCF2603C8
  */
  protected void insert(String[][] OpretParametre) throws BuildSQLException, SQLStatementException
  {
    SQLBuilder Builder = new SQLBuilder();
    String SQLString = Builder.BuildInsertSQL( TabelNavn[0], OpretParametre );
    DBConnection.update( SQLString );
  }
 
  /**
Denne metode er protected, da den kun skal kunne bruges af klasser fra Database-package, hvilket reelt set vil sige, at den kun kan kaldes af enten TabelObjekt eller DatabaseProxy.
  @roseuid 3A9CCF2A02BF
  */
  protected void update(String[][] OpdateringsParametre, String[][] Kriterier) throws BuildSQLException, SQLStatementException
  {
    SQLBuilder Builder = new SQLBuilder();
    String SQLString = Builder.BuildUpdateSQL( TabelNavn[0], OpdateringsParametre, Kriterier );
    DBConnection.update( SQLString );
  }
 
  /**
Denne metode er protected, da den kun skal kunne bruges af klasser fra Database-package, hvilket reelt set vil sige, at den kun kan kaldes af enten TabelObjekt eller DatabaseProxy.
  @roseuid 3A9CCF2F005D
  */
  protected void delete(String[][] SletParametre) throws BuildSQLException, SQLStatementException
  {
    SQLBuilder Builder = new SQLBuilder();
    String SQLString =  Builder.BuildDeleteSQL( TabelNavn, SletParametre );
      DBConnection.update( SQLString );
  }
 
  /**
Denne metode er protected, da den kun skal kunne bruges af klasser fra Database-package, hvilket reelt set vil sige, at den kun kan kaldes af enten TabelObjekt eller DatabaseProxy.
  @roseuid 3A9CCE8D02AF
  */
  protected TabelObjekt clone(SQLInterface _DBConnection)
  {
    String[] _TabelNavn = new String[TabelNavn.length];
    String[] _FeltNavne = new String[TabelFeltNavne.length];
    int[] _DataType = new int[TabelFeltDataType.length];
    boolean[] _ErNøgle = new boolean[TabelFeltErNøgle.length];
   
    for( int index = 0 ; index < _TabelNavn.length ; index++ )
      {
        _TabelNavn[index] = new String( TabelNavn[index] );
      }
     
    for( int index = 0 ; index < _FeltNavne.length ; index++ )
      {
        _FeltNavne[index] = new String( TabelFeltNavne[index] );
      } 
     
    for( int index = 0 ; index < _DataType.length ; index++ )
      {
        _DataType[index] = new Integer( TabelFeltDataType[index] ).intValue();
      }
     
    for( int index = 0 ; index < _ErNøgle.length ; index++ )
      {
        _ErNøgle[index] = new Boolean( TabelFeltErNøgle[index] ).booleanValue();
      }   

    return new TabelObjekt( _DBConnection, _TabelNavn, _FeltNavne, _DataType, _ErNøgle );
  }
 
  /**
Denne metode er protected, da den kun skal kunne bruges af klasser fra Database-package, hvilket reelt set vil sige, at den kun kan kaldes af enten TabelObjekt eller DatabaseProxy.
  @roseuid 3AAE141400AB
  */
  protected void join(TabelObjekt[] DeAndreObjekter)
  {
  for( int index = 0 ; index < DeAndreObjekter.length ; index++ )
    {
        //\"kopiér\" indholdet fra det andet TabelObjekt
        String[]  Andet_TabelNavn        = DeAndreObjekter[index].getTabelNavn();
        String[]  Andet_TabelFeltNavne    = DeAndreObjekter[index].getTabelFeltNavne();
        int[]      Andet_TabelFeltDataType = DeAndreObjekter[index].getTabelFeltDataType();
        boolean[]  Andet_TabelFeltErNøgle  = DeAndreObjekter[index].getNøgler();
       
        //\"kopiér\" indholdet fra dette TabelObjekt
        String[]  _TabelNavn        = TabelNavn;
        String[]  _TabelFeltNavne    = TabelFeltNavne;
        int[]    _TabelFeltDataType = TabelFeltDataType;
        boolean[] _TabelFeltErNøgle  = TabelFeltErNøgle;
       
        //flyt referencerne til indholdet af dette TabelObjekt til nye arrays
        TabelNavn        = new String  [Andet_TabelNavn.length        + _TabelNavn.length];
        TabelFeltNavne    = new String  [Andet_TabelFeltNavne.length    + _TabelFeltNavne.length];
        TabelFeltDataType = new int    [Andet_TabelFeltDataType.length + _TabelFeltDataType.length];
        TabelFeltErNøgle  = new boolean [Andet_TabelFeltErNøgle.length  + _TabelFeltErNøgle.length];
       
       
        //fyld TabelNavn-arrayet med data fra eget objekt
        int PrimærIndex = 0;
        for( int SekundærIndex = 0 ; SekundærIndex < _TabelNavn.length ; SekundærIndex++ )
          {
            TabelNavn[PrimærIndex] = new String( _TabelNavn[SekundærIndex] );
            PrimærIndex++;
          }
      //fyld TabelNavn-arrayet med data fra det andet objekt
      for( int SekundærIndex = 0 ; SekundærIndex < Andet_TabelNavn.length ; SekundærIndex++ )
          {
            TabelNavn[PrimærIndex] = new String( Andet_TabelNavn[SekundærIndex] );
            PrimærIndex++;
          }
     
      //fyld TabelFeltNavne-arrayet med data fra eget objekt 
      PrimærIndex = 0;
      for( int SekundærIndex = 0 ; SekundærIndex < _TabelFeltNavne.length ; SekundærIndex++ )
          {
            TabelFeltNavne[PrimærIndex] = new String( _TabelFeltNavne[SekundærIndex] );
            PrimærIndex++;
          }
      //fyld TabelFeltNavne-arrayet med data fra det andet objekt 
      for( int SekundærIndex = 0 ; SekundærIndex < Andet_TabelFeltNavne.length ; SekundærIndex++ )
          {
            TabelFeltNavne[PrimærIndex] = new String( Andet_TabelFeltNavne[SekundærIndex] );
            PrimærIndex++;
          } 
     
      //fyld TabelFeltDataType-arrayet med data fra eget objekt
      PrimærIndex = 0;
      for( int SekundærIndex = 0 ; SekundærIndex < _TabelFeltDataType.length ; SekundærIndex++ )
          {
            TabelFeltDataType[PrimærIndex] = _TabelFeltDataType[SekundærIndex];
            PrimærIndex++;
          }
      //fyld TabelFeltDataType-arrayet med data fra det andet objekt 
      for( int SekundærIndex = 0 ; SekundærIndex < Andet_TabelFeltDataType.length ; SekundærIndex++ )
          {
            TabelFeltDataType[PrimærIndex] = Andet_TabelFeltDataType[SekundærIndex] ;
            PrimærIndex++;
          }
     
      //fyld TabelFeltErNøgle-arrayet med data fra eget objekt
      PrimærIndex = 0;
      for( int SekundærIndex = 0 ; SekundærIndex < _TabelFeltErNøgle.length ; SekundærIndex++ )
          {
            TabelFeltErNøgle[PrimærIndex] = _TabelFeltErNøgle[SekundærIndex];
            PrimærIndex++;
          }
      //fyld TabelFeltErNøgle-arrayet med data fra eget objekt 
      for( int SekundærIndex = 0 ; SekundærIndex < Andet_TabelFeltErNøgle.length ; SekundærIndex++ )
          {
            TabelFeltErNøgle[PrimærIndex] = Andet_TabelFeltErNøgle[SekundærIndex];
            PrimærIndex++;
          } 
    }
  }
 
  /**
når denne metode kaldes, ændres følgende variabler:
SQLInterface DBConnection = null;
Derved kan objektet streames hen over netværket.
  @roseuid 3AAE12FD032C
  */
  public void setStreamable()
  {
      DBConnection = null;
  }
 
  /**
  @roseuid 3A9CCF4A0128
  */
  public String[] next()
  {
    Pointer++;
    if ( Pointer < RecordSet.length )
      {
          return RecordSet[Pointer];
      }
      return null;
  }
 
  /**
  @roseuid 3A9CCF5302DE
  */
  public boolean isDone()
  {
    return( Pointer == RecordSet.length - 1); 
  }
 
  /**
  @roseuid 3A9CCFB20167
  */
  public String[] getTabelNavn()
  {
    return TabelNavn;
  }
 
  /**
  @roseuid 3A9CCFB6038A
  */
  public String[] getTabelFeltNavne()
  {
    return TabelFeltNavne;
  }
 
  /**
  @roseuid 3A9CCFBD0196
  */
  public String[][] getRecordSet()
  {
    return RecordSet;
  }
 
  /**
  @roseuid 3AAE13D3007D
  */
  public boolean[] getNøgler()
  {
    return TabelFeltErNøgle;
  }
 
  /**
  @roseuid 3A9CCFC30138
  */
  public int[] getTabelFeltDataType()
  {
    return TabelFeltDataType;
  }
 
  /**
  Pointer = -1;
  @roseuid 3A9CCFF801B5
  */
  public void reset()
  {
    Pointer = -1;
  }
}
Avatar billede disky Nybegynder
02. oktober 2001 - 09:06 #11
Meget komplex måde du laver database adgang på.

Hvad er årsagen til du generere sql kommandoerne i software ?

Jeg har en openconnection, closeconnection, executequery,executeupdate. og det var det.

Avatar billede martin_schou Nybegynder
02. oktober 2001 - 09:15 #12
Disky - fordi jeg er en dør til SQL ... hehe ...

Hvis jeg ikke husker forkert, så har jeg opdateret tilgangen, så man kan skrive sql-sætningerne direkte.

Ud over sql-kommandoerne, hvad er det så ved det, som du mener, er komplekst?
Avatar billede disky Nybegynder
02. oktober 2001 - 09:25 #13
ikke noget, jeg synes bare det var komplext at lave det hele program mæssigt.

Men ellers ser det fint ud :)
Avatar billede martin_schou Nybegynder
02. oktober 2001 - 09:34 #14
Det er også en smule komplekst at lave sql-sætninger i software, men hvis man stiller det ordentligt op, så er det (idet mindste for mit vedkommende) nemmere at overskue på den måde. Det bliver langt fra lige så \'smarte\' sql-sætninger, som man kan lave i hånden, men det kan jo trods alt optimeres ved at ændre i SQLBuilder ...
Avatar billede disky Nybegynder
02. oktober 2001 - 09:57 #15
det er korrekt :)

Vil du også se min klasse ?
Avatar billede martin_schou Nybegynder
02. oktober 2001 - 10:03 #16
Uhm ... det lyder frækt ... er du sikker på, at det er i orden på første date?
Avatar billede disky Nybegynder
02. oktober 2001 - 10:04 #17
haha
Avatar billede johanls Nybegynder
03. oktober 2001 - 21:31 #18
Disky: alt i java har stort set designpatterns, dvs når man har et øje for dem. Jeg forstår under designpattern et designmønster, mønstre opstår når ting gentager sig, det forløb jeg har ridset op vil gentage sig utallige gange. Og er dermed også et designpattern. Designpatterns har deres betydning i genanvendligheden af sin kode, der jo passende kan lejres ind i nogle anvendlige klasser for den enkelte programmør og brugeren af klassen. ;-)
Det kommer an på hvordan man abstraherer fra de værktøjer man bruger.
Avatar billede logical Nybegynder
03. oktober 2001 - 22:34 #19
johanls>> Ja, og hvordan man abstraherer fra de litterære værker, som definerer ordet design patterns.

Hvad med en for løkke. Sådan en har jeg skrevet masser af..

Det kaldes idiomer, når det er nede i den størrelse.
Avatar billede martin_schou Nybegynder
13. oktober 2001 - 19:02 #20
Nå ja - hvad fanden, der skal jo lukkes på et tidspunkt.
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