I have some legacy database with table and column names like:
XYZEMP:
- XYZCMP
- XYZUSR
- XYZNME
that could be mapped to human readable
EMPLOYEE
- COMPANY
- USERNAME
- NAME
When I use standard JOOQ code generation it creates Table object XYXEMP, XyzempRecord etc. with XYZCMP columns and respective getters and setters. Is there any way to pass mapping to the generator so it produces Table object Employee, EmployeeRecord and human readable column names as well?
My idea is to use Custom generator strategy
public class AsInDatabaseStrategy extends DefaultGeneratorStrategy {
@Override
public String getJavaClassName(Definition definition, Mode mode) {
Map<String, String> tableNamesMapping = readTableNames();
if (mode == Mode.DEFAULT){ //for table class
String readableName = tableNamesMapping.get(definition.getOutputName());
if (readableName == null){
throw new IllegalStateException("Table " + definition.getOutputName() + " lacks mapping");
}
return readableName;
} else if (mode == Mode.RECORD) { // for record
// similar logic for record
return readableName + "Record";
}
return super.getJavaClassName(definition, mode);
}
@Override
public String getJavaIdentifier(Definition definition) {
// somehow similar code for table and and column
}
@Override
public String getJavaSetterName(Definition definition, Mode mode) {
// somehow similar code for table and and column
}
@Override
public String getJavaGetterName(Definition definition, Mode mode) {
// somehow similar code for table and and column
}
private Map<String, String> readTableNames(){
//read names mapping from file
}
private Map<String, Map<String, String>> readColumnNames(){
//read names mapping from file
}
}
Mapping files could be for tables:
{
"XYZEMP" : "EMPLOYEE",
...
}
for columns
{
"XYZEMP" : {
"XYZCMP" : "COMPANY",
"XYZUSR: : "USERNAME",
"XYZNME" : "NAME"
}
...
}
Do you see smarter way for doing that? In case of my approach - how to distinguish with "Definition" object is it table or column (or any other object) and for columns which table it belongs to?
Answering your question
That looks reasonable to me. The alternative is to use the configurative "matcher strategy", where you can configure those mappings directly in the Maven/Gradle/standalone XML format. That approach would seem more verbose and repetitive than yours, I think.
Just check if
definition instanceof TableDefinitionordefinition instanceof ColumnDefinition, and use their APIs to find table/column relationships.Side effects
Please note that if you rename your column names in Java using a
GeneratorStrategy, jOOQ 3.19 won't map the database names to your renamed POJO properties automatically. E.g. when you do:The
DefaultRecordMapperwon't be aware of this renaming. It will still see theXYZNMEcolumn name, which theEmployeePOJO doesn't have any correspondence to, unless you tell jOOQ to generate annotations:This only affects the
DefaultRecordMapper