Search code examples
javamysqljdbccoupling

JDBC - loosen coupling


We are currently having a school project where our application takes input from a file with a certain format, creates a table in MySQL and fills it with data. While coding this I noticed I use a lot of dependencies, which I have earlier read is a bad habit to get into. Reducing coupling has not really been a big topic yet. Searching around, I found most answers were about interfaces. I don't think they were clear enough answers for me, nor did it seem beneficial without repeating methods.

How can I loosen the coupling in my code? Any good general tips and tricks?

PS: void showTable and stringBuilderShowTable are not implemented, nor working.

public class DBService {
    DBConnection dbc;
    Connection con;
    //Statement stmt;


    public DBService()
    {
        dbc = new DBConnection();
        con = dbc.getConnection();
    }

    public void copyFile(String fileName, String tableName) throws SQLException {
        DataManager dm = new DataManager();
        dm.sortData(fileName);
        createTable(fileName, tableName, con);
        insertData(fileName, tableName, con);

    }
    public void showTable (String tableName)
    {
        try {
            Statement stmt = con.createStatement();
            ResultSet rs = stmt.executeQuery
                    ("SELECT * FROM " + tableName);
            System.out.println("id  name    job");
            while (rs.next()) {
                int id = rs.getInt("id");
                String name = rs.getString("name");
                String job = rs.getString("job");
                System.out.println(id+"   "+name+"    "+job);
            }
        }
        catch(SQLException e){
            System.out.println("SQL exception occured" + e);
        }

    }

    public void createTable(String fileName, String tableName, Connection con) throws SQLException {
        try (Statement stmt2 = (Statement) con.createStatement())
        {
            String query1 = stringBuilderMeta(fileName, tableName);
            stmt2.execute(query1);

            if (stmt2.getWarnings() == null)
            {
                System.out.println("\n### Table " + tableName + " is created");

            } else
            {
                System.out.println("### " + stmt2.getWarnings());
            }
            stmt2.close();
        }
    }

    public void insertData(String fileName, String tableName, Connection con) throws SQLException
    {
        try (Statement stmt = (Statement) con.createStatement())
        {
            String query1 = stringBuilderData(fileName, tableName);
            stmt.execute(query1);

            if (stmt.getWarnings() == null)
            {
                System.out.println("\n### Table " + tableName + " has been successfully filled");

            } else
            {
                System.out.println("### " + stmt.getWarnings());
            }
            stmt.close();
        }
    }
    public String stringBuilderMeta(String fileName, String tableName)
    {
        DataManager dm = new DataManager();
        dm.sortData(fileName);


        StringBuilder builder = new StringBuilder();
        builder.append("" + "Create table ").append(tableName).append(" (\n");

        for (int i = 0; i < dm.fileMetaData.size();i++) {
            DataFromFile d = (DataFromFile)dm.fileMetaData.get(i);
            String test = d.getName();
            String test2 = d.getDatatype();
            String test3 = d.getLimit();
            if(i < (dm.fileMetaData.size()-1))
            {
                builder.append(test).append(" ").append(test2).append(" (").append(test3).append("),\n");
            }
            else{
                builder.append(test).append(" ").append(test2).append(" (").append(test3).append(")\n");
            }

        }
        builder.append(");");




        String string = builder.toString();
        return string;
    }

    public String stringBuilderShowTable(String fileName, String tableName)
    {
        DataManager dm = new DataManager();
        dm.sortData(fileName);


        StringBuilder builder = new StringBuilder();
        //builder.append("" + "SELECT * FROM " + tableName + ""

        for (int i = 0; i < dm.fileMetaData.size();i++) {
            DataFromFile d = (DataFromFile)dm.fileMetaData.get(i);
            String test = d.getName();
            String test2 = d.getDatatype();
            String test3 = d.getLimit();
            if(i < (dm.fileMetaData.size()-1))
            {
                builder.append(test).append(" ").append(test2).append(" (").append(test3).append("),\n");
            }
            else{
                builder.append(test).append(" ").append(test2).append(" (").append(test3).append(")\n");
            }

        }
        builder.append(");");




        String string = builder.toString();
        System.out.print(string);
        return string;
    }

    public String stringBuilderData(String fileName, String tableName)
    {
        DataManager dm = new DataManager();
        dm.sortData(fileName);
        int counter = 0;
        int counter2 = dm.reader.wordsPerLine;

        StringBuilder builder = new StringBuilder();

        for(int j = 0; j < dm.boo; j++)
        {
            builder.append("" + "INSERT INTO ").append(tableName).append (" (");
            for (int i = 0; i < dm.fileMetaData.size(); i++) {
                DataFromFile d = (DataFromFile) dm.fileMetaData.get(i);
                if (i < (dm.fileMetaData.size() - 1)) {
                    builder.append(d.getName()).append(", ");
                } else {
                    builder.append(d.getName());
                }

            }
            builder.append(")\n").append("VALUES (");
            for (int i = counter; i < counter2; i++) {
                if (i < (counter2 - 1)) {
                    builder.append("'" + dm.fileData.get(i) + "'" + ",");
                } else {
                    builder.append("'" + dm.fileData.get(i) + "'");
                }
            counter++;
            }
            counter2 = counter2+dm.reader.wordsPerLine;
            builder.append(");\n");
        }
        String string = builder.toString();
        System.out.print(string);
        return string;
    }
}

Solution

  • It's a big question. A lot of what's gone into standard application architectures has to do with decoupling (and related, separation of concerns).

    You may get some ideas from the traditional OO design patterns: https://en.wikipedia.org/wiki/Design_Patterns

    Having collaborations of objects with defined roles (probably divided into architectural layers, and usually interacting through interfaces) is one technique. An application might have a presentation layer (further divided into an MVC structure) for showing things to the user, a data access layer for talking to the database, and a service layer in between... instead of one object doing all these things. A whole course could be devoted to the discipline of writing object that don't bleed across those types of architecture layers.

    You also might want to look at "inversion of control" or "dependency injection". There are several frameworks for this, but the basic idea is only this: A class needs to use an object that implements the SomeDependencyINeed interface, but instead of directly saying myVariable = new ImplementationOfSomeDependencyINeed(); it provides a way that it can be given a SomeDependencyINeed reference (a constructor argument, or a setter method). A framework like Spring provides an "inversion of control container" (or IoC container) that normally provides ("injects") the dependency instances; or without a framework you might have some sort of builder or confgurer object with that responsibility.

    The trouble is, a school project usually isn't big enough - and more importantly, usually isn't maintained for long enough - to show the benefit of these techniques. So as a student if you do them, you'll see all the cost - it takes longer to get up and running, sometimes you do things a specific way that might seem unnecessary - but you won't usually see the upside.