0

I'm trying to design a class to instantiate connection objects to my database that calls: "GenericConnection" and another class to instantiate custom ResultSet objects that calls: "GenericResultSet".

I leave a link of the project files that I create in NetBeans:

https://filebin.net/qxx01g0hdyndvpez

Its a < 2MB 7zip file.

And the code in the end of the post.

I am doing my tests with:

  • javac 11.0.12
  • NetBeans 12.6
  • jaybird-full-4.0.4.java11.jar; I leave a copy on \src\Drivers, and it's on: \dist\lib\ too of course.
  • Firebird 2.5.2.26540 (because that is the version of Firebird that uses a POS software to which I intend to extend functions.)

The database file I'm testing with is called: "DB.FDB" and it's in the \src\DB\ folder of the NetBeans project.

I am not asking you to program for me, but any guidance would be greatly appreciated.

With the connection class I have no problems, but with the "GenericResultSet" class I have the following drawbacks:

First, and although it works for the moment, I think that the way I am using the Connection variable is not correct. Since I didn't know how to send my "Connection" variable through a setter to my "GenericResultSet" class; what I ended up doing was declaring public the "Connection" variable of my "GenericConnection" class and I referenced it directly from the "GenericResultSet" class. If you see the code and suggest a way to improve that, would be the first thing that I would appreciate very much.

What I was trying to do in the class: "GenericResultSet" was to simplify the process of instantiating the RecordSet in the rest of the classes of the program.

I thought that when importing the class: "java.sql.ResultSet" into my class: "GenericResultSet", the Resulset methods would be available in the object instances of "GenericResultSet".

I am very confused, I don't even know if I am making some small mistake or if the design of what I am doing is completely meaningless.

I've been RTFM among other sources for a long time, and I thought I was ready to start a real project. But it seems that I was wrong.

I really appreciate any comments that help me understand the flaws in my understanding of the language.

The full code:

package Main;

import DBHandler.Display;

public class Main {

    public static void main(String[] args) {
        Display.DisplayData();
    }

}
package DBHandler;

public class Display {

    public static void DisplayData() {
        GenericConnection LinkTest = new GenericConnection();

        System.out.println("Valor de path justo despues de inicializar la conexion: " + LinkTest.getPath());

        //LinkTest.setPath("D:\DATASTORE\Desarrollo\Java\Addons\src\DB\DB.FDB"); // You may use this setter b4 open the connection for testing it.
        LinkTest.OpenLink();

        GenericResultSet RStest = new GenericResultSet(LinkTest.Link, "SELECT * FROM PRODUCTOS;");

        RStest.Next();

        System.out.println(RStest.GetString("nombre"));

        /*
        ↓↓↓↓↓↓↓↓↓↓ THIS IS WHAT I WAS TRYING TO DO ↓↓↓↓↓↓↓↓↓↓
        while (RStest.next()){ // But when I tried to use the "next" method of the ResultSet class I realized that NetBeans reproached me that such a method did not exist in my own class: "GenericResultSet". I thought that importing "java.sql.ResultSet" into "GenericResultSet" would have its methods available as well. I'm very confused. SOS Please. 
            System.out.println(RStest.GetString("nombre"));
        }
         */
        RStest.Close();

        LinkTest.CloseLink();

        System.gc();

    }

}
package DBHandler;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

import static IO_ITF.GenericDialogs.*;

/**
 * Manage the connection to the Firebird database. It is designed with the
 * intention of managing multiple Connection Objects (Multiple instances).
 * Includes opening and closing connection methods. And Getters and Setters
 * methods to update the connection string parameters of the connection open
 * method.
 */
public class GenericConnection {

    public Connection Link = null;

    private String usr = "SYSDBA";
    private String pwd = "masterkey";
    private String host = "localhost";
    private String port = "3050";
    private String path = System.getProperty("user.dir") + "\\src\\DB\\DB.FDB";
    private String drv = "org.firebirdsql.jdbc.FBDriver";

    /**
     * Open the connection to the database.
     */
    public void OpenLink() {
        try {
            Class.forName(this.drv);
            Link = DriverManager.getConnection("jdbc:firebirdsql:" + host + "/" + port + ":" + path, this.usr, this.pwd);
        } catch (ClassNotFoundException | SQLException e) {
            DlgError("Error de Base de Datos.", "Abrir la conexion produjo: " + e.getMessage());
        }

    }

    /**
     * Close the connection to the database.
     */
    public void CloseLink() {
        if (Link != null) {
            try {
                this.Link.close();
            } catch (SQLException e) {
                DlgError("Error de Base de Datos.", "Cerrar la conexion produjo: " + e.getMessage());
            }
        }
    }

    // COMIENZO DE GETTERS Y SETTERS
    public String getUsr() {
        return usr;
    }

    public void setUsr(String usr) {
        this.usr = usr;
    }

    public String getPwd() {
        return pwd;
    }

    public void setPwd(String pwd) {
        this.pwd = pwd;
    }

    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public String getPort() {
        return port;
    }

    public void setPort(String port) {
        this.port = port;
    }

    public String getPath() {
        return path;
    }

    public void setPath(String path) {
        this.path = path;
    }

    public String getDrv() {
        return drv;
    }

    public void setDrv(String drv) {
        this.drv = drv;
    }
    // FINAL DE GETTERS Y SETTERS

}
package DBHandler;

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

import static IO_ITF.GenericDialogs.*;

/**
 * Create and manage a database cursor (ResultSet).
 */
public class GenericResultSet {

    private Statement stmt = null;
    private ResultSet rs = null;

    /**
     * Initializes the Statement and the ResultSet directly in the constructor.
     *
     * @param Link Database connection object expected to receive.
     * @param sql SQL QUERY that is supplied to the Statement..
     */
    public GenericResultSet(Connection Link, String sql) {
        try {
            stmt = Link.createStatement();
            rs = stmt.executeQuery(sql);
        } catch (SQLException e) {
            DlgError("Error de Base de Datos", "Inicializar el Statement y el Resulset produjo: " + e.getMessage());
        }
    }

    /**
     * I imagine this is an abomination. I did it for testing purposes only.
     */
    public void Close() {
        try {
            rs.close();
        } catch (SQLException e) {
            DlgError("Error de Base de Datos", "Cerrando el Resulset produjo: " + e.getMessage());
        }
    }

    /**
     * I imagine this is an abomination. I did it for testing purposes only.
     */
    public void Next() {
        try {
            rs.next();
        } catch (SQLException e) {
            DlgError("Error de Base de Datos", "Moviendo al siguiente elemento el Resulset produjo: " + e.getMessage());
        }
    }

    /**
     * I imagine this is an abomination. I did it for testing purposes only..
     * 
     * Returns the String value of an element of the tuple that was returned by
     * the QUERY.
     *
     * @param Name Name of the tuple field to which we want to extract its
     * value.
     * @return The value of the element of the tuple that is being queried.
     *
     */
    public String GetString(String Name) {
        try {
            return rs.getString(Name);
        } catch (SQLException e) {
            DlgError("Error de Base de Datos", "Consultando un elemento ''Caracter'' de la tupla se produjo: " + e.getMessage());
        }
        return (null);
    }

}
package IO_ITF;

import javax.swing.JOptionPane;
import static javax.swing.JOptionPane.*;

/**
 * Collection of the most common types of "Dialog Windows": 
 * Information, Warning, Error, Confirm, etc.
 */
public class GenericDialogs {

    /**
     * Ventana de dialogo de tipo "Informativa".
     *
     * @param title El mensaje del titulo de la ventana de dialogo.
     * @param msg El mensaje de la ventana de dialogo.
     */
    public static void DlgInfo(String title, String msg) {
        JOptionPane.showMessageDialog(null, msg, title, INFORMATION_MESSAGE);

    }

    /**
     * Ventana de dialogo de tipo "Advertencia".
     *
     * @param title El mensaje del titulo de la ventana de dialogo.
     * @param msg El mensaje de la ventana de dialogo.
     */
    public static void DlgWarn(String title, String msg) {
        JOptionPane.showMessageDialog(null, msg, title, WARNING_MESSAGE);
    }

    /**
     * Ventana de dialogo de tipo "Error".
     *
     * @param title El mensaje del titulo de la ventana de dialogo.
     * @param msg El mensaje de la ventana de dialogo.
     */
    public static void DlgError(String title, String msg) {
        JOptionPane.showMessageDialog(null, msg, title, ERROR_MESSAGE);
    }

    /**
     * Ventana de dialogo de "Seleccion Multiple".El metodo devuelve como
     * respuesta el valor entero del indice del array que se le suministro al
     * objeto "showOptionDialog". Los elementos del array "options" que se
     * suministra a la ventana de dialogo seran las opciones de la misma, y
     * devolvera el indice del array. Para utilizarlo se puede capturar su
     * respuesta en un switch o directamente en una variable entera.
     *
     * @param title El mensaje del titulo de la ventana de dialogo.
     * @param msg El mensaje de la ventana de dialogo.
     * @return Devuelve un numero entero correspondiente al indice del array que
     * se suministra a "showOptionDialog" cuyos elementos seran las opciones de
     * la ventana de dialogo.
     */
    public static int DlgQuestion(String title, String msg) {
        String[] options = {"Si", "No"};
        int choice = JOptionPane.showOptionDialog(null, msg, title, JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[1]);
        return choice;

    }

}
Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
  • Your `GenericResultSet` doesn't have a `next()` method, it has a `Next()` method. I'm not sure why you're creating those `GenericConnection` and `GenericResultSet` classes, your design doesn't make sense to me: why can't you just use `java.sql.Connection` and `java.sql.ResultSet` directly? Imports just make a class name (or static method) available in a shorter form (the simple name), instead of the fully-qualified name, they don't magically extend your class with functionality. – Mark Rotteveel Dec 19 '21 at 08:10
  • As an aside, please follow Java naming conventions, it makes your code easier to read for other Java developers. Also, your `GenericConnection` seems to be a badly written data source. Consider using a real data source implementation instead (e.g. `org.firebirdsql.ds.FBSimpleDataSource` if you don't need a connection pool) – Mark Rotteveel Dec 19 '21 at 08:15

0 Answers0