0

I have a set of data objects, which correspond to rows in RDMS table, as in ClassA -> Rows of TableA ClassB -> Rows of TableB . . . ClassZ -> Rows of TableZ I am fetching these records using JDBC and creating objects from the result set(Please note that the result set can be huge) I have custom parsers for each class i.e parseClassA(), parseClassB()....parseClassZ(), currently i am having a function with a huge switch statement which determines the type of the class like switch(classType) and gives me an object of the corresponding class, i want to eliminate this switch statement, which is the optimal way to do this?

9
  • First, I'd say "optimal" might be the wrong word since there probably are multiple ways to do it. Those might have different tradeoffs so you'd need to better define "optimal". Second it also would depend on your code, requirements etc. but one way to do it might be a Map<Class, Parser>. Then you'd just try to get the parser out of that map and if you got one you call some method (e.g. something like parse(ResultSet)). Commented Jul 3, 2017 at 12:22
  • 2
    I think that what you are searching for is here. Maybe a dublicate subject? stackoverflow.com/a/6094602/3543153 Commented Jul 3, 2017 at 12:23
  • @Thomas how would you construct the map? do you want me to construct the map everytime i query the database ? Commented Jul 3, 2017 at 12:24
  • Possible duplicate of Creating an instance using the class name and calling constructor Commented Jul 3, 2017 at 12:24
  • 2
    Another option (and maybe a better one) would be to use an ORM (or at least look into what they are doing) such as Hibernate, EclipseLink etc. - In fact, what you describe is what ORMs are meant to do: map relational data to objects. Although you could write one yourself you might want to save yourself some headaches and just use one of the frameworks that already solved 80% of the problems for you (those 80% being the most common cases). Commented Jul 3, 2017 at 12:25

2 Answers 2

2

This is called an ORM - hibernate is far-and-away the most widely adopted. Or, you could opt for a DSL. However, since we are on the subject, and we might want to have a functional looking approach here are the outlines:

Stream.of(resultSet).flatMap(r -> someHowMakThisAStream(r))

But, you're lookup map should be of type

Map<String,Function<Map<String,Object>,T> lookup...
lookup.put("SomeTable", SomeClass::new);

You will want each class to take a Map of column names to values (normalizing) and not the resultset directly so that each instantiation can't accidentally forward the resultset too far.

Then you can, in psuedo functional, do: stream.of(results).flatMap().map(valMap -> lookup.get(tableName).apply(valMap))

Sign up to request clarification or add additional context in comments.

Comments

1

You could use a map structure that associates the class to create to the parser to create it :

Map<Class<?> clazz, Supplier<Parser>>

You could initialize the map with all required mappings :

 static{
    parserByClass = new HashMap<>();
    parserByClass.put(MyClass.class, MyParserMyClass::new);
    parserByClass.put(MyOtherClass.class, MyOtherParserMyClass::new);
    ...
 }

When you need to create a specific class, you could use the map to retrieve the parser of this class:

Parser<MyClass> parser = parserByClass.get(MyClass.class).get();

You can so call the parse() method of the parser :

ResultSet resultSet = ...;
MyClass parse = parser.parse(resultSet);

Ideally, you should have a Parser interface to define the parse() method and to allow to define the returned type :

 public interface Parser<T> {   
   T parse(ResultSet resultSet);    
 }

Please note that it is a untested code.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.