2
\$\begingroup\$

I am studying computer science and recently I developed an application in Java (it is a minecraft mod) that connects a MySQL database and queries to fetch, update or insert data. My DatabaseHandler class is the one that initialize the connection to the database and performs all the necessary queries my application needs.

DatabaseHandler class:

public class DatabaseHandler {


private static DatabaseHandler instance = null;
/** MySQL port to connect. */
private static final int port = 3306; //Default is port 3306
/** The url of the database we wat to connect. */
private static String url = "j******************" + port +"/";
/** The username to connect to database. */
private static final String dbUser = "*******";
/** The password to connecto to database */
private static final String dbPassword = "**********";
/** The name of the database we want to query */
private static final String dbName = "**********";

private static Connection connect = null;
private  Statement statement = null;
private PreparedStatement preparedStatement = null;
private  ResultSet resultSet = null;

/** Constructor load the MySQL Driver */
public DatabaseHandler()
{
    try{
        // Load the MySQL Driver
        Class.forName("com.mysql.jdbc.Driver");
    }catch(ClassNotFoundException e)
    {
        System.out.println("MySQL Driver could not loaded!");
        e.printStackTrace();
    }  
}

/**
 * Returns a list with the houses coordinates needed from the {@link GroundBuilder#buildMissingGround(World, int)} to spawn the ground.
 * @param rowID the ID of the row we want the coordinates
 */
public List<MissingGroundCoordinates> getMissingGroundCoordinates(int rowID)
{
    List<MissingGroundCoordinates> missingGroundCoordinates = new ArrayList<MissingGroundCoordinates>();

    try
    {
        statement = connect.createStatement();
        resultSet = statement.executeQuery("SELECT startBuildingPosX, startBuildingPosY, startBuildingPosZ, blocksInX, blocksInZ FROM houses_coordinates WHERE rowID = " + rowID);

        while (resultSet.next())
        {
            MissingGroundCoordinates mGroundCoordinates = new MissingGroundCoordinates();

            mGroundCoordinates.setStartBuildingPosX(resultSet.getInt("startBuildingPosX"));
            mGroundCoordinates.setStartBuildingPosY(resultSet.getInt("startBuildingPosY"));
            mGroundCoordinates.setStartBuildingPosZ(resultSet.getInt("startBuildingPosZ"));
            mGroundCoordinates.setBlocksInX(resultSet.getInt("blocksInX"));
            mGroundCoordinates.setBlocksInZ(resultSet.getInt("blocksInZ"));

            missingGroundCoordinates.add(mGroundCoordinates);

            //System.out.println(mGroundCoordinates); // DEBUG
        }
        return missingGroundCoordinates;
    }
    catch(SQLException e)
    {
        System.out.println("There is been a problem in DatabaseHandler.getMissingGroundCoordinates.Try block caught an sql exception and the method returns a null valued list.");
        return null;
    }
    finally
    {
        close();
    }
}

/**
 * Query the database to get maxBlocksInZ value for a row.
 * @param rowID id of the row needed the maxBlocksInZ
 * @return the maxBlocksInZ for the row it passed as arguement
 */
public int getMaxBlocksInZForARow(int rowID)
{
    int maxBlocksInZ = 0;
    try
    {
        statement = connect.createStatement();
        resultSet = statement.executeQuery("SELECT maxBlocksInZ FROM houses_rows WHERE rowID = " + rowID);

        while(resultSet.next())
        {
            maxBlocksInZ = resultSet.getInt("maxBlocksInZ");
        }
        return maxBlocksInZ;
    }
    catch(SQLException e)
    {
        System.out.println("SQL Exception occured. getMaxBlocksInZForARow returns 0");
        return 0;
    }
    finally
    {
        close();
    }


}

/** 
 * Query the database to fetch the color of the block used to build the under construction house.
 * @return the name of the color
 */
public String getBlockColor() 
{
    String color = null;
    try
    {
        statement = connect.createStatement();
        resultSet = statement.executeQuery("SELECT blockColor FROM tc_coordinates");

        while(resultSet.next())
        {
            color = resultSet.getString("blockColor");
        }
        //System.out.println(color); // DEBUG
        return color;
    }
    catch(SQLException e)
    {
        return null;
    }
    finally
    {
        close();
    }
}

/** 
 * This method is called when a block from our city is clicked. It queries the database searching the ID 
 * that matches the coordinates of the block it was clicked. Then we use that ID to fetch the tweet data.
 * @param x the x coordinate of the block that was clicked
 * @param y the y coordinate of the block that was clicked
 * @param z the z coordinate of the block that was clicked
 * @return a {@link Tweet} instance with its fields setted.
 */
public Tweet getTweet(int x,int y, int z)
{
    int id = 0;
    Tweet tweet = null;

    try {
        preparedStatement = connect.prepareStatement("SELECT ID FROM spawned_blocks WHERE posX LIKE ? AND posY LIKE ? AND posZ LIKE ?");

        preparedStatement.setInt(1,x);
        preparedStatement.setInt(2,y);
        preparedStatement.setInt(3,z);
        resultSet = preparedStatement.executeQuery();

        while(resultSet.next())
        {
            id = resultSet.getInt("ID");
        }

        if(id > 0){
            statement = connect.createStatement();
            resultSet = statement.executeQuery("SELECT * FROM tweets WHERE ID LIKE " + id);

            while (resultSet.next())
            {
                tweet = new Tweet();

                tweet.setID(resultSet.getInt("ID"));
                tweet.setUsername(resultSet.getString("user_name"));
                tweet.setTweetText(resultSet.getString("tweet_text"));
                tweet.setTweetDate(resultSet.getString("tweet_date"));
            }
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }finally{
        close();
    }
    return tweet;
}

/**
 * We fetch the latest ID in the table we define.
 * @param tableName the name of the table we need the latest id from
 * @return the latest ID from the table we gave as parameter
 */
public int getLatestID(String tableName)
{
    int latestID = 0;   
    try 
    {
        String columnName = "";
        statement = connect.createStatement();

        // If the table name is houses_coordinates we need the latest houseID
        if (tableName.equals("houses_coordinates"))
        {
            columnName = "houseID";
        }
        else{
            columnName = "ID";
        }
        resultSet = statement.executeQuery("SELECT " + columnName + " FROM " + tableName + " ORDER BY " + columnName + " DESC LIMIT 1");

        while(resultSet.next())
        {
            latestID = resultSet.getInt(columnName);
        }
    } 
    catch (SQLException e) 
    {
        e.printStackTrace();
    }
    finally
    {
        close();
    }

    return latestID;
}

/**
 * Spawns the blocks need to be spawned.
 * @param world the world object
 * @param latestBuildedBlockIDInWorld the last block's id that was builded in this world
 */
public void spawnUnspawnedBlocks(World world, int latestBuildedBlockIDInWorld)
{
    try
    {
        statement = connect.createStatement();

        resultSet = statement.executeQuery("SELECT * FROM spawned_blocks WHERE ID > " + latestBuildedBlockIDInWorld);

        while (resultSet.next()) {
            // System.out.println("To id einai: " + resultSet.getInt("ID") + ", to posX einai: " +
            // resultSet.getInt("posX") +", to posY einai: " + resultSet.getInt("posY") +", to posZ einai: " + resultSet.getInt("posZ"));
            world.setBlock(resultSet.getInt("posX"), resultSet.getInt("posY"), resultSet.getInt("posZ"), BlockPicker.getBlockByColor(resultSet.getString("blockColor")));               
        }

    }
    catch(SQLException e)
    {
        e.printStackTrace();
    }
    finally
    {
        close();
    }
}

/**
 * Spawns the floor,stairs,doors or/and roof where is necessary.
 * @param world the world object
 * @param currentlyConstructingHouseIDInThisWorld the houses ID that is currently under construction in this world.
 */
public void spawnUnspawnedFloorStairsDoorsRoof(World world, int currentlyConstructingHouseIDInThisWorld)
{
    try
    {
        int i = 1;
        statement = connect.createStatement();

        resultSet = statement.executeQuery("SELECT * FROM houses_coordinates WHERE houseID >= " + currentlyConstructingHouseIDInThisWorld);

        while(resultSet.next())
        {
            if(resultSet.getBoolean("finishedBuilding"))
            {
                //Build the roof
                RoofBuilder.buildRoof(world, resultSet.getInt("startBuildingPosX"), resultSet.getInt("boundsY"), 
                                        resultSet.getInt("startBuildingPosZ"), resultSet.getInt("blocksInX"), resultSet.getInt("blocksInZ"));

                //Build door and Stairs
                DoorAndStairsBuilder.buildDoorAndStairs(world, resultSet.getInt("startBuildingPosX"), resultSet.getInt("startBuildingPosY"),
                                        resultSet.getInt("startBuildingPosZ"), resultSet.getInt("blocksInZ"));

                //If the houseID is the first result we got we skip building ground because it is already builded
                if (resultSet.getInt("houseID") != currentlyConstructingHouseIDInThisWorld)
                {

                    GroundBuilder.buildGround(world, resultSet.getInt("startBuildingPosX"), resultSet.getInt("startBuildingPosY"), 
                            resultSet.getInt("startBuildingPosZ"),  resultSet.getInt("blocksInX"),  resultSet.getInt("blocksInZ"));
                }
            }
            else
            {
                GroundBuilder.buildGround(world, resultSet.getInt("startBuildingPosX"), resultSet.getInt("startBuildingPosY"), 
                        resultSet.getInt("startBuildingPosZ"),  resultSet.getInt("blocksInX"),  resultSet.getInt("blocksInZ"));
            }
        }

        int rowIDForCurrentlyConstructingHouse = 0;
        resultSet = statement.executeQuery("SELECT rowID FROM houses_coordinates WHERE houseID = " + currentlyConstructingHouseIDInThisWorld);
        while(resultSet.next())
        {
            rowIDForCurrentlyConstructingHouse = resultSet.getInt("rowID");
        }

        resultSet = statement.executeQuery("SELECT rowID FROM houses_rows WHERE rowID >= " + rowIDForCurrentlyConstructingHouse);

        //If result.next() returns false then the resultSet is empty
        if (resultSet.next())
        {
            resultSet.last();
            int[] rowIDs = new int[resultSet.getRow()];
            resultSet.beforeFirst();

            int loopCounter = 0;
            while(resultSet.next())
            {
                rowIDs[loopCounter] = resultSet.getInt("rowID");
                loopCounter++;
            }

            for (int l = 0; l < rowIDs.length; l++)
            {
                GroundBuilder.buildMissingGround(world, rowIDs[l]);
            }
        }

    }
    catch(SQLException e)
    {
        e.printStackTrace();
    }
    finally
    {
        close();
    }
}


/**
 * Get the values of the tc_coordinates table's fields and assign to the fields of the data object class {@link Coordinates}
 */
public void coordinatesInitialization()
{
    try
    {
        statement = connect.createStatement();
        resultSet = statement.executeQuery("SELECT * FROM tc_coordinates");
        while(resultSet.next())
        {

            Coordinates.getInstance().buildedHouses = resultSet.getInt("buildedHouses");
            Coordinates.getInstance().maxBuildedHousesInXAxis = resultSet.getInt("maxBuildedHousesInXAxis");

            Coordinates.getInstance().startBuildingPosX = resultSet.getInt("startBuildingPosX");
            Coordinates.getInstance().startBuildingPosY = resultSet.getInt("startBuildingPosY");
            Coordinates.getInstance().startBuildingPosZ = resultSet.getInt("startBuildingPosZ");

            Coordinates.getInstance().blocksInX = resultSet.getInt("blocksInX");
            Coordinates.getInstance().blocksInY = resultSet.getInt("blocksInY");
            Coordinates.getInstance().blocksInZ = resultSet.getInt("blocksInZ");

            Coordinates.getInstance().boundsX = resultSet.getInt("boundsX");
            Coordinates.getInstance().boundsY = resultSet.getInt("boundsY");
            Coordinates.getInstance().boundsZ = resultSet.getInt("boundsZ");

            Coordinates.getInstance().nextPosX = resultSet.getInt("nextPosX");
            Coordinates.getInstance().nextPosY = resultSet.getInt("nextPosY");
            Coordinates.getInstance().nextPosZ = resultSet.getInt("nextPosZ");

            Coordinates.getInstance().currentRowID = resultSet.getInt("currentRowID");
            Coordinates.getInstance().buildedHousesInCurrentRow = resultSet.getInt("buildedHousesInCurrentRow");
            Coordinates.getInstance().maxBlocksInZForCurrentRow = resultSet.getInt("maxBlocksInZForCurrentRow");
        }       
    } 
    catch(SQLException e)
    {
        e.printStackTrace();
    }
    finally
    {
        close();
    }       
}


/**
 * Update the table tc_coordinates with values' of the fields from the data object class {@link Coordinates}
 */
public void updateCoordinates()
{
    Coordinates coords = Coordinates.getInstance();

    try
    {
        preparedStatement = connect.prepareStatement("UPDATE tc_coordinates SET " 
                                                    + "buildedHouses = ?, maxBuildedHousesInXAxis = ?, startBuildingPosX = ?, startBuildingPosY = ?, startBuildingPosZ = ?, " 
                                                    + "blocksInX = ?, blocksInY = ?, blocksInZ = ?, boundsX = ?, boundsY = ?, boundsZ = ?, " 
                                                    + "nextPosX = ?, nextPosY = ?, nextPosZ = ?, currentRowID = ?, buildedHousesInCurrentRow =?, maxBlocksInZForCurrentRow = ?");

        preparedStatement.setInt(1, coords.buildedHouses);
        preparedStatement.setInt(2, coords.maxBuildedHousesInXAxis);
        preparedStatement.setInt(3, coords.startBuildingPosX);
        preparedStatement.setInt(4, coords.startBuildingPosY);
        preparedStatement.setInt(5, coords.startBuildingPosZ);
        preparedStatement.setInt(6, coords.blocksInX);
        preparedStatement.setInt(7, coords.blocksInY);
        preparedStatement.setInt(8, coords.blocksInZ);
        preparedStatement.setInt(9, coords.boundsX);
        preparedStatement.setInt(10, coords.boundsY);
        preparedStatement.setInt(11, coords.boundsZ);
        preparedStatement.setInt(12, coords.nextPosX);
        preparedStatement.setInt(13, coords.nextPosY);
        preparedStatement.setInt(14, coords.nextPosZ);
        preparedStatement.setInt(15, coords.currentRowID);
        preparedStatement.setInt(16, coords.buildedHousesInCurrentRow);
        preparedStatement.setInt(17, coords.maxBlocksInZForCurrentRow);

        preparedStatement.execute();

    }
    catch(SQLException e)
    {
        e.printStackTrace();
    }
    finally
    {
        close();
    }
}

/**
 * Update the column blockColor in the table tc_coordinates with the color of the block the under construction house is building.
 * @param color the color of the block we need to update
 */
public void updateBlockColor(String color) 
{
    try
    {
        statement = connect.createStatement();
        statement.executeUpdate("UPDATE tc_coordinates SET blockColor = " + "\"" + color + "\"");
    }
    catch(SQLException e)
    {
        e.printStackTrace();
    }
    finally
    {
        close();
    }
}

/**
 * Called when the current under construction building finishes and sets the finishedBuilding value to 1 (true)
 */
public void updateFinishedBuildingValue() 
{
    try
    {
        int houseID = 0;
        statement = connect.createStatement();
        resultSet = statement.executeQuery("SELECT MAX(houseID) FROM houses_coordinates");
        while(resultSet.next())
        {
            houseID = resultSet.getInt("MAX(houseID)");
        }

        statement.executeUpdate("UPDATE houses_coordinates SET finishedBuilding = 1 WHERE houseID = " + houseID);
    }
    catch(SQLException e)
    {
        e.printStackTrace();
    }
    finally
    {
        close();
    }
}

/**
 * When a row is finished we add in the houses_rows table
 * @param buildedHousesInCurrentRow how many houses are builded to the row
 * @param maxBlocksInZForCurrentRow what is the maxBlocksInZ for the row
 */
public void addNewRowInHousesRowsTable(int buildedHousesInCurrentRow, int maxBlocksInZForCurrentRow)
{
    try 
    {
        preparedStatement = connect.prepareStatement("INSERT INTO houses_rows (buildedHousesInRow, maxBlocksInZ) VALUES (?, ?)");

        preparedStatement.setInt(1, buildedHousesInCurrentRow);
        preparedStatement.setInt(2, maxBlocksInZForCurrentRow);

        preparedStatement.execute();
    } 
    catch (SQLException e) 
    {
        e.printStackTrace();
    }
    finally
    {
        close();
    }
}

/**
 * Adds a spawned block's coordinates in the spawned_blocks table
 * @param x x coordinate of the block
 * @param y y coordinate of the block
 * @param z z coordinate of the block
 * @param blockColor the block's color
 */
public void addSpawnedBlock(int x, int y, int z, String blockColor)
{
    try 
    {
        preparedStatement = connect.prepareStatement("INSERT INTO spawned_blocks (posX, posY, posZ, blockColor) VALUES (?, ?, ?, ?)");

        preparedStatement.setInt(1, x);
        preparedStatement.setInt(2, y);
        preparedStatement.setInt(3, z);
        preparedStatement.setString(4, blockColor);

        preparedStatement.execute();

    } 
    catch (SQLException e) 
    {
        e.printStackTrace();
    }
    finally
    {
        close();
    }
}

/**
 * Called when a house finished constructing to add the next's house ,that is going to be builded, coordinates.
 */
public void addNextConstructingHouseInHousesCoordinatesTable() 
{
    Coordinates coords = Coordinates.getInstance();

    try 
    {
        preparedStatement = connect.prepareStatement("INSERT INTO houses_coordinates (rowID, startBuildingPosX, startBuildingPosY, startBuildingPosZ," 
                                            + " blocksInX, blocksInY, blocksInZ, boundsX, boundsY, boundsZ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");

        preparedStatement.setInt(1, coords.currentRowID);
        preparedStatement.setInt(2, coords.startBuildingPosX);
        preparedStatement.setInt(3, coords.startBuildingPosY);
        preparedStatement.setInt(4, coords.startBuildingPosZ);
        preparedStatement.setInt(5, coords.blocksInX);
        preparedStatement.setInt(6, coords.blocksInY);
        preparedStatement.setInt(7, coords.blocksInZ);
        preparedStatement.setInt(8, coords.boundsX);
        preparedStatement.setInt(9, coords.boundsY);
        preparedStatement.setInt(10, coords.boundsZ);

        preparedStatement.execute();
    } 
    catch (SQLException e) 
    {
        e.printStackTrace();
    }
    finally
    {
        close();
    }
}

/**
 * Closes the resultSet, statement and connect objects.
 */
public void close() {
  try 
  {
      if (resultSet != null) 
      {
          resultSet.close();
      }

      if (statement != null) 
      {
          statement.close();
      }

      if (connect != null)
      {
          connect.close();
      }
  } 
  catch (Exception e) 
  {
      System.out.println("There is been a problem while closing the MySQL ResultSet, Statement or Connection!");
  }
}

/**
 * Singleton Pattern so it cannot exist more than one instance of this class.
 * If there is no instance of this class we create one.
 * Every time this method is called we check if the connection is OK and
 * if is not we try to initialize it.
 */
public static DatabaseHandler getInstance ()
{
    if(instance  == null)
    {
        instance = new DatabaseHandler();
    } 

    if (connect != null)
    {
        try {               
            if(connect.isClosed())
            {
                connect = DriverManager.getConnection(url + dbName + "?user=" + dbUser + "&password=" + dbPassword);
            }
        } catch (SQLException e) {

            //e.printStackTrace();
        }
    }
    else
    {
         try {
            connect = DriverManager.getConnection(url  + dbName + "?user=" + dbUser + "&password=" + dbPassword);
        } catch (SQLException e) {
            e.printStackTrace();
        }    
    }
    return instance;
}

/**
 * This method issues a lightweight query to the database in order determine if the connection with the database is fine.
 * @return true if the query where succesfully executed to the database
 */
public boolean isConnected()
{
    String PING_MARKER = "/* ping */ SELECT 1"; 

   /*
    * If (connect != null) is true means we had a connection with MySQL before and we need to CHECK if it 
    *  is still OK.
    */
    if(connect != null)
    {
        /*
         * If an excpetion get caught that means the query did not execute.
         * If not, our connection is OK and we return true
         */
        try
        {   
                statement = connect.createStatement();
                resultSet = statement.executeQuery(PING_MARKER);
                return true;
        }   
        catch(SQLException e)
        {
            return false;
        }
        finally
        {
            close();
        }
    }
    //If (connect == null) means we never had a connection with the MySQL database
    else
    {
        return false;
    }
}
}

Although the above code works great, there is a lot code duplication, the class is huge so it is not easy to maintain. I would like your opinions on how to make this piece of code more maintainable and what is the best practice for writing code that queries a database?

\$\endgroup\$
  • \$\begingroup\$ You might want to separate your code block into a bunch of smaller code blocks. It would be more readable that way. (Say every three related methods in a code block or something.) Nice first question, btw. \$\endgroup\$ – asibahi Sep 24 '16 at 18:48
1
\$\begingroup\$

This class is doing too much. Think of separate classes for things like:

  • database object instantiation/management/vending (i.e. singleton)
  • a house
  • house collection utilities - search, paginate, etc. to return collection of houses
  • house construction (perhaps factory and/or decorator patterns would be useful here)
  • blocks
  • rows

Don't use SELECT *. It can make your application fragile to DB schema changes and can result in unnecessary data being transferred between DB and application.


Your code can become hard to read at times due to long line lengths. You should strive to keep lines under 80 characters. Break your code across lines as necessary.


Don't hard code credentials into classes. This should be moved to application configuration (and ideally made injectable by administrative process).

Also, don't hard code DB connection information. This needs to be configurable to allow application to point at various endpoints as needed based on the environment in which the application is being run.


Your singleton is implemented improperly. The constructor must be private to prevent object instantiation from outside the static instantiation method.


    System.out.println("MySQL Driver could not loaded!");
    e.printStackTrace();

Should this throw? Right now you just sort of silently fail and swallow underlying exception. There is no visibility to this error up the call stack.


You may want to think about overall class organization. Beside the thought that this class is doing to much, you should think about grouping your methods in a more approachable manner. By that, I mean methods related to class instantiation (i.e. constructor and static instantiation method) would best be located right next to each other. Here you have to scroll quite far down in code to realize that this whole class is trying to implement singleton pattern.


public List<MissingGroundCoordinates> getMissingGroundCoordinates(int rowID)

public int getMaxBlocksInZForARow(int rowID)

public void addNewRowInHousesRowsTable(int buildedHousesInCurrentRow, int maxBlocksInZForCurrentRow)

Move to row or row management class?

public int getLatestID(String tableName)

Why is this in "database handler" class? You should have knowledge on model or helper class for each type of object you are modelling to get the latest id.

public String getBlockColor()

public void spawnUnspawnedBlocks(World world, int latestBuildedBlockIDInWorld)

public void updateBlockColor(String color)

public void addSpawnedBlock(int x, int y, int z, String blockColor)

Move to block or related helper classes.

public Tweet getTweet(int x,int y, int z)

Should be in Tweet or related helper class.

public void spawnUnspawnedFloorStairsDoorsRoof(World world, int
    currentlyConstructingHouseIDInThisWorld)

public void updateFinishedBuildingValue()

public void addNextConstructingHouseInHousesCoordinatesTable()

Move to house or related helper class

 public void coordinatesInitialization()

 public void updateCoordinates()

Move to coordinate or related helper class.


You are really only doing the minimal amount of data validation available when working with your method arguments. Perhaps consider more meaningful data validation (beyond just type hinting), especially on your public methods. You for example, when passing in table name as a parameter, you should likely validate that the string is not zero length. Some of your integer values might need better enforcement (positive values only? unsigned?). You should fail out of these methods early before doing things like trying to operate against the database, when you know you have invalid values.

\$\endgroup\$
  • \$\begingroup\$ Hello thanks for your answer, all the tips are noted. I want to keep in mind that I am student and not at all experienced with coding. Every method in the DatabaseHandler class are there because all of them needs to query the database to fetch data needed from the mod to operate correctly. Do you suggest to set geters methods for the ResultSet, Statement and PreparedStatement and then use these to execute queries in the classes you suggested I should put the methods? \$\endgroup\$ – Vpant Sep 26 '16 at 15:58
  • \$\begingroup\$ Any class that needs to interact with the database should get a database connection object passed to it as a dependency. I don't really have a problem with the way that your methods interact with the MySQL (connect) dependency. These have been given a dependency and then execute their class and method specific logic against it. I just don't think it makes sense to have such diverse sets of functionality in a single class. As a student, you should strive to understand and apply the single responsibility principle when writing your code. \$\endgroup\$ – Mike Brant Sep 26 '16 at 16:19
  • \$\begingroup\$ Oh I see what are you saying. I just googled the single responsibility principle and I will try to understand it. My first thought when I was implementing this class was to return the ResultSet object and manipulate the results in the class needs them but I failed to do that, cannot remember why, so I implemented the way I showed you in the code block I attached. \$\endgroup\$ – Vpant Sep 26 '16 at 16:30
  • \$\begingroup\$ @Vpant Passing result sets, statement objects, between classes to complete some set of functionality would generally be considered a bad idea, in that you are leaking implementation from one class to another. A class that might need to interact with the database should get a dependency on the database connection, DB abstraction object, etc. to operate with, then contain all the logic to execute the database interaction as well as handle any exceptions/errors that might arise in the process. \$\endgroup\$ – Mike Brant Sep 26 '16 at 16:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.