I have a single table called Tags
that stores a "Tag" as a row, regardless of what specific subclass they represent. Some rows represent modbus tags, some snmp, some other protocols. All classes inheriting from Tag store their data in this one table, and unused columns simply contain null values.
At the moment, I have DAO methods like, getAllModBusTags()
which contains an instruction mapToBean(ModBusTag.class)
. Eventually all of the subclasses of Tag are fetched from the database (one fetch per protocol) and then added to an ArrayList of the supertype Tag.
My question is, is there a simple means with Jdbi to perform conditional mapping of rows so that if a row contains a specific value, it is mapped to ModBusTag.class but if a row contains a different value it is mapped to SNMPTag.class, and so on and so forth?
My end goal is to have a single select statement that fetches every tag from the database, automaps to the correct bean on a row by row basis and then stores all of these subclass beans in a List of the supertype Tag.
Example Method for Single Type:
@Override
public List<SNMPTag> getSNMPTags(){
try(Handle handle = daoFactory.getDataSourceController().open()) {
return handle.createQuery("SELECT * FROM dbo.Tags WHERE Active = 1 AND Protocol = 'SNMP'")
.mapToBean(SNMPTag.class)
.list();
}
catch(Exception e){
if(sysconfig.getVerbose()){ e.printStackTrace(); }
}
return null;
}
Some bad pseudocode to indicate what I want to do:
@Override
public List<Tag> getAllTags(){
try(Handle handle = daoFactory.getDataSourceController().open()) {
return handle.createQuery("SELECT * FROM dbo.Tags WHERE Active = 1")
.mapRows(row -> row.Protocol.equals("SNMP").mapToBean(SNMPTag.class)
.mapRows(row -> row.Protocol.equals("ModBus").mapToBean(ModBusTag.class)
//etc
.list();
}
catch(Exception e){
if(sysconfig.getVerbose()){ e.printStackTrace(); }
}
return null;
}
You can use
RowMapper
with some amount of custom code to achieve what you need, we successfully use such approach in our project. Here is simplified general example of this technique: