0

I am working with Spring Boot on a project. JdbcNamedTemplates are used in my DAOs to access data. I write queries in my daos and then Map some parameters at runtime to get correct data.

Now, I have to handle retrieving data from multiple identical tables depending on the request. Retrieval logic is the same except I need to use different table names. JdbcTemplate does not allow using table names as parameters. I do not want to use string formatting as I wish my queries to be final.

I could create abstract class with most of the functionality and the concrete classes that extend it to handle differences in table names (basicly, have method "getTableName()"). This works. However, it seems like I am creating a lot of classes and I would like to create less of them.

Are there better ways to do it?

I was thinking that using interfaces for specific tablenames would be nice, but I cant wrap my head around how that could work with Spring and Autowiring.

UPDATE:

Just giving a sample of what I would like to improve. So far I have couple of abstract DAOs like this. They do the database talk.

public abstract class Dao1 {
    private static final String PARAM = "p";
    private final String QUERY1 = " SELECT * FROM " + getTableName() + " WHERE something";
    //here we would also have autowired jdbcNamedTemplate and maybe some other stuff.
    public getAll() {
        //map parameters, do query return results
    }
    protected abstract String getTableName();
}

Next, I have couple of data access objects that implemenent abstract method getTableName(). So if the table was "Autumn", I woould have.

@Component
public class AutumnDao1 extends Dao1 {
    @Override
    protected String getTableName() {
        return "AUTUMN";
    }
}

So from example above you can see that for each abstract dao I would have to make couple of Concrete Daos (autumn, winter, spring, summer). This is acceptable for now, but at some point this might grow to quite sizeable collection of daos.

I would like to know if there is a way to avoid that by for instance creating just one class / interface for each "season" / name and somehow attatching it to Dao1, Dao2 etc, as needed. I only know which name is relevant when the user request arrive.

Riv
  • 347
  • 2
  • 5
  • 14
  • "I have to handle retrieving data from multiple identical tables depending on the request. Retrieval logic is the same except I need to use different table names" - can you give a sample – kuhajeyan Nov 04 '16 at 09:24
  • You can try using interfaces and inject different implementations with the bean @Qualifier. – Nano Nov 04 '16 at 10:32
  • @Nano , I am a noob with annotations. Could you please elaborate on how it could work taking into consideration my last update? – Riv Nov 04 '16 at 11:59

1 Answers1

0

With @Qualifier("nameOfBean") you can inject the instance you are looking for.

If you have, for instance:

@Component
public class AutumnDao1 extends Dao1 {
    @Override
    protected String getTableName() {
        return "AUTUMN";
    }
}

@Component
public class SummerDao1 extends Dao1 {
    @Override
    protected String getTableName() {
        return "SUMMER";
    }
}

In this case you are creating two beans that can be injected in the parent class Dao1. To inject the right one you should do:

@Autowire
@Qualifier("autumnDao1")
private Dao1 autumnDao;

@Autowire
@Qualifier("summerDao1")
private Dao1 summerDao;

Try this!

Nano
  • 814
  • 2
  • 13
  • 30
  • Thanks for the response! Is there however a way to choose Wualifier at runtime? – Riv Nov 07 '16 at 06:49
  • Hmm, I don't have any clue yet tbh. Check this question out and tell me if it is what you were looking for! http://stackoverflow.com/questions/26463393/how-to-inject-different-services-at-runtime-based-on-a-property-with-spring-with – Nano Nov 07 '16 at 08:18