Skip to content

Commit 239e891

Browse files
committed
Documenation for updated function support
1 parent c341978 commit 239e891

File tree

3 files changed

+109
-33
lines changed

3 files changed

+109
-33
lines changed

src/site/markdown/docs/extending.md

Lines changed: 82 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ A calculated column can be used anywhere in a SELECT statement. If you don't ne
2121
```java
2222
public class CountAll implements BasicColumn {
2323

24-
private Optional<String> alias = Optional.empty();
24+
private String alias;
2525

2626
public CountAll() {
2727
super();
@@ -34,13 +34,13 @@ public class CountAll implements BasicColumn {
3434

3535
@Override
3636
public Optional<String> alias() {
37-
return alias;
37+
return Optional.ofNullable(alias);
3838
}
3939

4040
@Override
4141
public CountAll as(String alias) {
4242
CountAll copy = new CountAll();
43-
copy.alias = Optional.of(alias);
43+
copy.alias = alias;
4444
return copy;
4545
}
4646
}
@@ -52,64 +52,113 @@ This class is used to implement the `count(*)` function in a SELECT list. There
5252
2. `as` - this method can be called by the user to add an alias to the column expression. In the method you should return a new instance of the object, with the alias passed by the user.
5353
3. `alias` - this method is called by the default renderer to obtain the column alias for the select list. If there is no alias, then returning Optional.empty() will disable setting a column alias.
5454

55-
### Writing a Custom Where Condition
55+
## Writing Custom Functions
5656

57-
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:
57+
Relational database vendors provide hundreds of functions in their SQL dialects to aid with queries and offload processing to the database servers. This library does not try to implement every function that exists. This library also does not provide any abstraction over the different functions on different databases. For example, bitwise operator support is non-standard and it would be difficult to provide a function in this library that worked on every database. So we take the approach of supplying examples for a few very common functions, and making it relatively easy to write your own functions.
58+
59+
The supplied functions are all in the `org.mybatis.dynamic.sql.select.function` package. They are all implemented as `BindableColumn` - meaning that they can appear in a select list or a where clause.
60+
61+
We provide some base classes that you can easily extend to write functions of your own. Those classes are as follows:
62+
63+
Note: the base classes are all in the `org.mybatis.dynamic.sql.select.function` package.
64+
65+
| Interface | Purpose|
66+
|-----------|--------|
67+
| `o.m.d.s.s.f.AbstractTypeConvertingFunction` | Extend this class if you want to build a function that changes a column data type. For example, using a database function to calculate the Base64 String for a binary field. |
68+
| `o.m.d.s.s.f.AbstractUniTypeFunction` | Extend this class if you want to build a function that does not change a column data type. For example UPPER(), LOWER(), etc. |
69+
| `o.m.d.s.s.f.OperatorFunction` | Extend this class if you want to build a function the implements an operator. For example column1 + column2. |
70+
71+
### AbstractTypeConvertingFunction Example
72+
73+
The following function uses HSQLDB's `TO_BASE64` function to calculate the BASE64 string for a binary field. Note that the function changes the data type from `byte[]` to `String`.
5874

5975
```java
60-
public class Add<T extends Number> implements BindableColumn<T> {
61-
62-
private Optional<String> alias = Optional.empty();
63-
private BindableColumn<T> column1;
64-
private BindableColumn<T> column2;
65-
66-
private Add(BindableColumn<T> column1, BindableColumn<T> column2) {
67-
this.column1 = Objects.requireNonNull(column1);
68-
this.column2 = Objects.requireNonNull(column2);
76+
public class ToBase64 extends AbstractTypeConvertingFunction<byte[], String, ToBase64> {
77+
78+
protected ToBase64(BindableColumn<byte[]> column) {
79+
super(column);
6980
}
7081

7182
@Override
72-
public Optional<String> alias() {
73-
return alias;
83+
public Optional<JDBCType> jdbcType() {
84+
return Optional.of(JDBCType.VARCHAR);
85+
}
86+
87+
@Override
88+
public Optional<String> typeHandler() {
89+
return Optional.empty();
7490
}
7591

7692
@Override
7793
public String renderWithTableAlias(TableAliasCalculator tableAliasCalculator) {
78-
return column1.applyTableAliasToName(tableAliasCalculator)
79-
+ " + " //$NON-NLS-1$
80-
+ column2.applyTableAliasToName(tableAliasCalculator);
94+
return "TO_BASE64(" //$NON-NLS-1$
95+
+ column.renderWithTableAlias(tableAliasCalculator)
96+
+ ")"; //$NON-NLS-1$
8197
}
8298

8399
@Override
84-
public BindableColumn<T> as(String alias) {
85-
Add<T> newColumn = new Add<>(column1, column2);
86-
newColumn.alias = Optional.of(alias);
87-
return newColumn;
100+
protected ToBase64 copy() {
101+
return new ToBase64(column);
102+
}
103+
104+
public static ToBase64 toBase64(BindableColumn<byte[]> column) {
105+
return new ToBase64(column);
106+
}
107+
}
108+
```
109+
110+
### AbstractUniTypeFunction Example
111+
112+
The following function implements the common database `UPPER()` function.
113+
114+
```java
115+
public class Upper extends AbstractUniTypeFunction<String, Upper> {
116+
117+
private Upper(BindableColumn<String> column) {
118+
super(column);
88119
}
89120

90121
@Override
91-
public JDBCType jdbcType() {
92-
return column1.jdbcType();
122+
public String renderWithTableAlias(TableAliasCalculator tableAliasCalculator) {
123+
return "upper(" //$NON-NLS-1$
124+
+ column.renderWithTableAlias(tableAliasCalculator)
125+
+ ")"; //$NON-NLS-1$
93126
}
94127

95128
@Override
96-
public Optional<String> typeHandler() {
97-
return column1.typeHandler();
129+
protected Upper copy() {
130+
return new Upper(column);
98131
}
99132

100-
public static <T extends Number> Add<T> of(BindableColumn<T> column1, BindableColumn<T> column2) {
101-
return new Add<>(column1, column2);
133+
public static Upper of(BindableColumn<String> column) {
134+
return new Upper(column);
102135
}
103136
}
104137
```
105138

106-
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.
139+
### OperatorFunction Example
107140

108-
The two additional methods are:
141+
The following function implements the concatenate operator. Note that the operator can be applied to list of columns of arbitrary length:
109142

110-
1. `jdbcType` - returns the JDBC Type of the column for the WHERE clause. This is used by the MyBatis3 rendering strategy to render a full MyBatis parameter expression.
111-
2. `typeHandler` - returns a type handler if specified by the user. Again, this is used by the MyBatis3 rendering strategy to render a full MyBatis parameter expression.
143+
```java
144+
public class Concatenate<T> extends OperatorFunction<T> {
145+
146+
protected Concatenate(BindableColumn<T> firstColumn, BasicColumn secondColumn,
147+
List<BasicColumn> subsequentColumns) {
148+
super("||", firstColumn, secondColumn, subsequentColumns); //$NON-NLS-1$
149+
}
112150

151+
@Override
152+
protected Concatenate<T> copy() {
153+
return new Concatenate<>(column, secondColumn, subsequentColumns);
154+
}
155+
156+
public static <T> Concatenate<T> concatenate(BindableColumn<T> firstColumn, BasicColumn secondColumn,
157+
BasicColumn... subsequentColumns) {
158+
return new Concatenate<>(firstColumn, secondColumn, Arrays.asList(subsequentColumns));
159+
}
160+
}
161+
```
113162

114163
## Writing Custom Rendering Strategies
115164

src/site/markdown/docs/functions.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Database Functions
2+
3+
The library supplies implementations for several common database functions. We do not try to implement a large set of functions. Rather we supply some common functions as examples and make it relatively easy to write your own implementations of functions you might want to use that are not supplied by the library. See the page "Extending the Library" for informtion about how to write your own functions.
4+
5+
The supplied functions are all in the `org.mybatis.dynamic.sql.select.function` package. In addition, there are static methods in the `SqlBuilder` to access all functions.
6+
7+
In the following table...
8+
9+
- "Function Class" is implementing class in the `org.mybatis.dynamic.sql.select.function` package
10+
- "Example" shows the static method from the `SqlBuilder` class
11+
- "Rendered Result" shows the rendered SQL fragment generated by the function
12+
13+
14+
| Function Class | Example | Rendered Result |
15+
|----------|---------|--------|
16+
| Add | add(column1, column2, constant(55)) | column1 + column2 + 55 |
17+
| Concatenate | concatenate(stringConstant("Name: ", column1) | 'Name: ' \|\| column1 |
18+
| Divide | divide(column1, column2, constant(55)) | column1 / column2 / 55 |
19+
| Lower | lower(column1) | lower(column1) |
20+
| Multiply | multiply(column1, column2, constant(55)) | column1 * column2 * 55 |
21+
| OperatorFunction | applyOperator("^", column1, column2) | column1 ^ column2 |
22+
| Substring | substring(column1, 5, 7) | substring(column1, 5, 7) |
23+
| Subtract | subtract(column1, column2, constant(55)) | column1 - column2 - 55 |
24+
| Upper | upper(column1) | upper(column1) |
25+
26+
Note especially the `OperatorFunction` - you can use this function to easily implement operators supported by your database. For example, MySQL supports a number of bitwise operators that can be easily implemented with this function.

src/site/site.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
<item href="docs/delete.html" name="DELETE Statements" />
4848
<item href="docs/insert.html" name="INSERT Statements" />
4949
<item href="docs/update.html" name="UPDATE Statements" />
50+
<item href="docs/functions.html" name="Database Functions" />
5051
<item href="docs/mybatis3.html" name="MyBatis3 Support" />
5152
<item href="docs/kotlinMyBatis3.html" name="Kotlin Support for MyBatis3" />
5253
<item href="docs/spring.html" name="Spring Support" />

0 commit comments

Comments
 (0)