1

I have some test JavaFX app and the code has a lot of similar parts regard of database. Just for example:

Class.forName("com.mysql.jdbc.Driver");
    try (Connection connection = DriverManager.getConnection(Person.getURL(), Person.getDBUSERNAME(), Person.getDBPASSWORD())) {
                String sqlQuery = "INSERT INTO users (users.user_name," +
                        "users.current_balance) VALUES (?, ?)";

                PreparedStatement preparedStatement = connection.prepareStatement(sqlQuery);
                preparedStatement.setString(1, newUserName);
                preparedStatement.setBigDecimal(2, new BigDecimal(newBalance));

                preparedStatement.executeUpdate();
            } catch (SQLException e) {
                e.printStackTrace();
            }

So I want to make an abstract class SqlWorkClass with an abstract method updateDatabaseInfo.

public abstract class SqlWorkClass {
    public abstract void updateDatabaseInfo() throws ClassNotFoundException;

And 3 classes inherited of SqlWorkClass – DatabaseInsertClass, DatabaseUpdateClass and DatabaseSelectClass. But the problem is I have to use different parameters for method updateDatabaseInfo for each class.

public class DatabaseInsertClass extends SqlWorkClass {

    @Override
    public void updateDatabaseInfo(String newUserName, String newBalance) throws ClassNotFoundException{
            //some actions with code above
}

public class DatabaseUpdateClass extends SqlWorkClass {

    @Override
    public void updateDatabaseInfo(String param1, String param2, String param3) throws ClassNotFoundException{
            //some actions with code above
}

public class DatabaseSelectClass extends SqlWorkClass {

        @Override
        public void updateDatabaseInfo(String param1) throws ClassNotFoundException{
                //some actions with code above
    }

Obviously I can't do this. So how can I solve this problem? Maybe I should use interface or something else instead of abstract class? Hope for your advice guys! p.s. I use Java 7.

  • you can use an `Object []` array as super typer parameter and then you can call the supermethod in your sub classes like this: `super.updateDatabaseInfo(new Object[]{param1,param2,...})`. if the method should do the same for all 3 subclasses, why does it need different parameter then? – XtremeBaumer Sep 18 '17 at 12:11

3 Answers3

1

You can pass those parameters in constructors of DatabaseInsertClass, DatabaseUpdateClass and DatabaseSelectClass. This way you can use updateDatabaseInfo() with no parameters.
For every operation you will have to create a new instance of your classes.

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
0

If you are just wanting to update one record at a time, you could use a HashMap to store your updated values like so:

Map<String, String> data = new HashMap<>();
data.put('id', '112342');
data.put('name', 'CaveJohnson');
data.put('address', 'ApertureSciencesRoad');

And then your abstract classes method would be:

public void updateDatabaseInfo(Map<String, String> updateData) throws ClassNotFoundException;

Implementing classes would not even need to know the name of the data headers:

public void updateDatabaseInfo(Map<String, String> updateData) throws ClassNotFoundException{
     for(String key:updateData.keys()){
         //Use Prepared Statements to generate a query with `key` being your field 
         //name and `updateData.get(key)` being the value to place in that field
     }

}
CraigR8806
  • 1,584
  • 13
  • 21
0

Use a parameter object instead of a list of parameters. Your super class defines the parameter object class and uses it as parameter for the method. The sub classes then implement specific classes:

public abstract class SqlWorkClass<I extends Input>
{
    public abstract void updateDatabaseInfo(I input)
        throws ClassNotFoundException;
}
public abstract class Input {}

public class DatabaseInsertClass
    extends SqlWorkClass<InsertInput>
{
    @Override
    public void updateDatabaseInfo(InsertInput input)
        throws ClassNotFoundException
    {
        String param1 = input.newUserName;
        String param2 = input.newBalance;
    }
}
public abstract class InsertInput
    extends Input
{
    public final String newUserName, newBalance;

    public InsertInput(String newUserName, String newBalance)
    {
        this.newUserName = newUserName;
        this.newBalance = newBalance;
    }
}

The advantage here that you do not have to rely on convention to get the parameter types and names right. You have nicely defined inputs of specific types.


You would then use your classes like this:

new DatabaseInsertClass().updateDatabaseInfo(new InsertInput(param1, param2));
Malte Hartwig
  • 4,477
  • 2
  • 14
  • 30
  • Would you mind to explain a bit more, please? I use the example you give me, but what kind of parameters should i use, when I call the method `updateDatabaseInfo` ? I mean Im trying to call the method from the other class -`new DatabaseInsertClass().updateDatabaseInfo(param1, param2);` . What type of `param1` and `param2` should I use now? Looks like i can't use `String`, but have to use `InsertInput` type. How can I make `String` to `InsertInput`. – oiDistortion Sep 20 '17 at 09:47
  • @oiDistortion I have added a small example of how to use it. As I said, using those parameter object types tells you exactly what you have to pass: a database insert needs insert input. You create insert input by calling the constructor with 2 string parameters. Using good names for your parameters and/or documenting them in JavaDoc will help you understand the code if you come back to it in a while. – Malte Hartwig Sep 20 '17 at 09:54