The library has been designed for extension from the very start of the design. We do not believe that the library covers all possible uses and we wanted to make it possible to add functionality that suits the needs of different projects.
This page details the main extension points of the library.
The SELECT support is the most complex part of the library, and also the part of the library that is most likely to be extended. There are two main interfaces involved with extending the SELECT support. Picking which interface to implement is dependent on how you want to use your extension.
Interface | Purpose |
---|---|
org.mybatis.dynamic.sql.BasicColumn | Use this interface if you want to add capabilities to a SELECT list or a GROUP BY expression. For example, creating a calculated column. |
org.mybatis.dynamic.sql.BindableColumn | Use this interface if you want to add capabilities to a WHERE clause. For example, creating a custom condition. |
See the following sections for examples.
A calculated column can be used anywhere in a SELECT statement. If you don’t need to use it in a WHERE clause, then it is easier to implement the org.mybatis.dynamic.sql.BasicColumn interface. An example from the library itself is the org.mybatis.dynamic.sql.select.aggregate.CountAll class:
public class CountAll implements BasicColumn { private Optional<String> alias = Optional.empty(); public CountAll() { super(); } @Override public String renderWithTableAlias(TableAliasCalculator tableAliasCalculator) { return "count(*)"; //$NON-NLS-1$ } @Override public Optional<String> alias() { return alias; } @Override public CountAll as(String alias) { CountAll copy = new CountAll(); copy.alias = Optional.of(alias); return copy; } }
This class is used to implement the count(*) function in a SELECT list. There are only three methods to implement:
If you want to use your calculated column in a WHERE clause in addition the select list and the GROUP BY clause, then you must implement org.mybatis.dynamic.sql.BindableColumn. This interface extends the BasicColumn interface from above and adds two methods. An example from the library is the org.mybatis.dynamic.sql.select.function.Add class:
public class Add<T extends Number> implements BindableColumn<T> { private Optional<String> alias = Optional.empty(); private BindableColumn<T> column1; private BindableColumn<T> column2; private Add(BindableColumn<T> column1, BindableColumn<T> column2) { this.column1 = Objects.requireNonNull(column1); this.column2 = Objects.requireNonNull(column2); } @Override public Optional<String> alias() { return alias; } @Override public String renderWithTableAlias(TableAliasCalculator tableAliasCalculator) { return column1.applyTableAliasToName(tableAliasCalculator) + " + " //$NON-NLS-1$ + column2.applyTableAliasToName(tableAliasCalculator); } @Override public BindableColumn<T> as(String alias) { Add<T> newColumn = new Add<>(column1, column2); newColumn.alias = Optional.of(alias); return newColumn; } @Override public JDBCType jdbcType() { return column1.jdbcType(); } @Override public Optional<String> typeHandler() { return column1.typeHandler(); } public static <T extends Number> Add<T> of(BindableColumn<T> column1, BindableColumn<T> column2) { return new Add<>(column1, column2); } }
This class implements the idea of adding two numeric columns together in a SELECT statement. This class accepts two other columns as parameters and then overrides renderWithTableAlias to render the addition. The alias and as methods work as described above.
The two additional methods are:
A RenderingStrategy is used to format the parameter placeholders in generated SQL. The library ships with two built-in rendering strategies:
You can write a custom rendering strategy if you want to use the library with some other framework. For example, if you wanted to use the library to generate SQL that could be prepared directly by JDBC, you could write a rendering strategy that simply uses the question mark (?) for all parameters.
import org.mybatis.dynamic.sql.BindableColumn; import org.mybatis.dynamic.sql.render.RenderingStrategy; public class PlainJDBCRenderingStrategy extends RenderingStrategy { @Override public String getFormattedJdbcPlaceholder(BindableColumn<?> column, String prefix, String parameterName) { return "?"; } }
The library will pass the following parameters to the getFormattedJdbcPlaceholder method:
SQL rendering is accomplished by classes that are decoupled from the SQL model classes. All the model classes have a render method that calls the built-in default renderers, but this is completely optional and you do not need to use it. You can write your own rendering support if you are dissatisfied with the SQL produced by the default renderers.
Writing a custom renderer is quite complex. If you want to undertake that task, we suggest that you take the time to understand how the default renderers work first. And feel free to ask questions about this topic on the MyBatis mailing list.