I have some legacy database with table and column names like:
XYZEMP:
that could be mapped to human readable
EMPLOYEE
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?
Do you see smarter way for doing that?
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.
how to distinguish with "Definition" object is it table or column (or any other object) and for columns which table it belongs to?
Just check if definition instanceof TableDefinition
or definition instanceof ColumnDefinition
, and use their APIs to find table/column relationships.
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:
ctx.select(EMPLOYEE.NAME)
.from(EMPLOYEE)
.fetchInto(Employee.class);
The DefaultRecordMapper
won't be aware of this renaming. It will still see the XYZNME
column name, which the Employee
POJO doesn't have any correspondence to, unless you tell jOOQ to generate annotations:
public class Employee {
@Column("XYZNME")
String name;
}
This only affects the DefaultRecordMapper