Skip to content

Commit 8d82cfc

Browse files
committed
Documentation
1 parent db5479c commit 8d82cfc

File tree

2 files changed

+132
-8
lines changed

2 files changed

+132
-8
lines changed

src/main/java/org/mybatis/dynamic/sql/SqlColumn.java

Lines changed: 131 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,48 @@
2525
import org.mybatis.dynamic.sql.util.FragmentAndParameters;
2626
import org.mybatis.dynamic.sql.util.StringUtilities;
2727

28+
/**
29+
* This class represents the definition of a column in a table.
30+
*
31+
* <p>The class contains many attributes that are helpful for use in MyBatis and Spring runtime
32+
* environments, but the only required attributes are the name of the column and a reference to
33+
* the SqlTable the column is a part of.
34+
*
35+
* <p>The class can be extended if you wish to associate additional attributes with a column for your
36+
* own purposes. Extending the class involves the following activities:
37+
* <ol>
38+
* <li>Create a class that extends {@link SqlColumn}</li>
39+
* <li>In your extended class, create a static builder class that extends {@link SqlColumn.AbstractBuilder}</li>
40+
* <li>Add your desired attributes to the class and the builder</li>
41+
* <li>You MUST override the following methods. These methods are used with regular operations in the library.
42+
* If you do not override these methods, it is likely that your extended attributes will be lost during
43+
* regular usage. For example, if a user calls the {@code as} method to apply an alias, the base
44+
* {@code SqlColumn} class will create a new instance of {@code SqlColumn}, NOT your extended class.
45+
* <ul>
46+
* <li>{@link SqlColumn#as(String)}</li>
47+
* <li>{@link SqlColumn#asCamelCase()}</li>
48+
* <li>{@link SqlColumn#descending()}</li>
49+
* <li>{@link SqlColumn#qualifiedWith(String)}</li>
50+
* </ul>
51+
* </li>
52+
* <li>You SHOULD override the following methods. These methods can be used to add additional attributes to a
53+
* column by creating a new instance with a specified attribute set. These methods are used during the
54+
* construction of columns. If you do not override these methods, and a user calls them, then a new
55+
* {@code SqlColumn} will be created that does not contain your extended attributes.
56+
* <ul>
57+
* <li>{@link SqlColumn#withJavaProperty(String)}</li>
58+
* <li>{@link SqlColumn#withRenderingStrategy(RenderingStrategy)}</li>
59+
* <li>{@link SqlColumn#withTypeHandler(String)}</li>
60+
* <li>{@link SqlColumn#withJavaType(Class)}</li>
61+
* <li>{@link SqlColumn#withParameterTypeConverter(ParameterTypeConverter)}</li>
62+
* </ul>
63+
* </li>
64+
* </ol>
65+
*
66+
* <p>The test code for this library contains an example of a proper extension of this class.
67+
*
68+
* @param <T> the Java type associated with the column
69+
*/
2870
public class SqlColumn<T> implements BindableColumn<T>, SortSpecification {
2971

3072
protected final String name;
@@ -90,11 +132,24 @@ public Optional<String> javaProperty() {
90132
return value == null ? null : parameterTypeConverter.convert(value);
91133
}
92134

135+
/**
136+
* Create a new column instance that will render as descending when used in an order by phrase.
137+
*
138+
* @return a new column instance that will render as descending when used in an order by phrase
139+
*/
93140
@Override
94141
public SqlColumn<T> descending() {
95142
return copyBuilder().withDescendingPhrase(" DESC").build(); //$NON-NLS-1$
96143
}
97144

145+
/**
146+
* Create a new column instance with the specified alias that will render as "as alias" in a column list.
147+
*
148+
* @param alias
149+
* the column alias to set
150+
*
151+
* @return a new column instance with the specified alias
152+
*/
98153
@Override
99154
public SqlColumn<T> as(String alias) {
100155
return copyBuilder().withAlias(alias).build();
@@ -112,11 +167,11 @@ public SqlColumn<T> qualifiedWith(String tableQualifier) {
112167
}
113168

114169
/**
115-
* Set an alias with a camel cased string based on the column name. This can be useful for queries using
170+
* Set an alias with a camel-cased string based on the column name. This can be useful for queries using
116171
* the {@link org.mybatis.dynamic.sql.util.mybatis3.CommonSelectMapper} where the columns are placed into
117172
* a map based on the column name returned from the database.
118173
*
119-
* <p>A camel case string is mixed case, and most databases do not support unquoted mixed case strings
174+
* <p>A camel case string is a mixed case string, and most databases do not support unquoted mixed case strings
120175
* as identifiers. Therefore, the generated alias will be surrounded by double quotes thereby making it a
121176
* quoted identifier. Most databases will respect quoted mixed case identifiers.
122177
*
@@ -146,24 +201,93 @@ public Optional<RenderingStrategy> renderingStrategy() {
146201
return Optional.ofNullable(renderingStrategy);
147202
}
148203

204+
/**
205+
* Create a new column instance with the specified type handler.
206+
*
207+
* <p>This method uses a different type (S). This allows it to be chained with the other
208+
* with* methods. Using new types forces the compiler to delay type inference until the end of a call chain.
209+
* Without this different type (for example, if we used T), the compiler would erase the type after the call
210+
* and method chaining would not work. This is a workaround for Java's lack of reification.
211+
*
212+
* @param typeHandler the type handler to set
213+
* @return a new column instance with the specified type handler
214+
* @param <S> the type of the new column (will be the same as T)
215+
*/
149216
public <S> SqlColumn<S> withTypeHandler(String typeHandler) {
150217
return cast(copyBuilder().withTypeHandler(typeHandler).build());
151218
}
152219

220+
/**
221+
* Create a new column instance with the specified rendering strategy.
222+
*
223+
* <p>This method uses a different type (S). This allows it to be chained with the other
224+
* with* methods. Using new types forces the compiler to delay type inference until the end of a call chain.
225+
* Without this different type (for example, if we used T), the compiler would erase the type after the call
226+
* and method chaining would not work. This is a workaround for Java's lack of reification.
227+
*
228+
* @param renderingStrategy the rendering strategy to set
229+
* @return a new column instance with the specified type handler
230+
* @param <S> the type of the new column (will be the same as T)
231+
*/
153232
public <S> SqlColumn<S> withRenderingStrategy(RenderingStrategy renderingStrategy) {
154233
return cast(copyBuilder().withRenderingStrategy(renderingStrategy).build());
155234
}
156235

236+
/**
237+
* Create a new column instance with the specified parameter type converter.
238+
*
239+
* <p>Parameter type converters are useful with Spring JDBC. Typically, they are not needed for MyBatis.
240+
*
241+
* <p>This method uses a different type (S). This allows it to be chained with the other
242+
* with* methods. Using new types forces the compiler to delay type inference until the end of a call chain.
243+
* Without this different type (for example, if we used T), the compiler would erase the type after the call
244+
* and method chaining would not work. This is a workaround for Java's lack of reification.
245+
*
246+
* @param parameterTypeConverter the parameter type converter to set
247+
* @return a new column instance with the specified type handler
248+
* @param <S> the type of the new column (will be the same as T)
249+
*/
157250
@SuppressWarnings("unchecked")
158251
public <S> SqlColumn<S> withParameterTypeConverter(ParameterTypeConverter<S, ?> parameterTypeConverter) {
159-
return cast(copyBuilder().withParameterTypeConverter((ParameterTypeConverter<T, ?>) parameterTypeConverter).build());
252+
return cast(copyBuilder().withParameterTypeConverter((ParameterTypeConverter<T, ?>) parameterTypeConverter)
253+
.build());
160254
}
161255

256+
/**
257+
* Create a new column instance with the specified Java type.
258+
*
259+
* <p>Specifying a Java type will force rendering of the Java type for MyBatis parameters. This can be useful
260+
* with some MyBatis type handlers.
261+
*
262+
* <p>This method uses a different type (S). This allows it to be chained with the other
263+
* with* methods. Using new types forces the compiler to delay type inference until the end of a call chain.
264+
* Without this different type (for example, if we used T), the compiler would erase the type after the call
265+
* and method chaining would not work. This is a workaround for Java's lack of reification.
266+
*
267+
* @param javaType the Java type to set
268+
* @return a new column instance with the specified type handler
269+
* @param <S> the type of the new column (will be the same as T)
270+
*/
162271
@SuppressWarnings("unchecked")
163272
public <S> SqlColumn<S> withJavaType(Class<S> javaType) {
164273
return cast(copyBuilder().withJavaType((Class<T>) javaType).build());
165274
}
166275

276+
/**
277+
* Create a new column instance with the specified Java property.
278+
*
279+
* <p>Specifying a Java property in the column will allow usage of the column as a "mapped column" in record-based
280+
* insert statements.
281+
*
282+
* <p>This method uses a different type (S). This allows it to be chained with the other
283+
* with* methods. Using new types forces the compiler to delay type inference until the end of a call chain.
284+
* Without this different type (for example, if we used T), the compiler would erase the type after the call
285+
* and method chaining would not work. This is a workaround for Java's lack of reification.
286+
*
287+
* @param javaProperty the Java property to set
288+
* @return a new column instance with the specified type handler
289+
* @param <S> the type of the new column (will be the same as T)
290+
*/
167291
public <S> SqlColumn<S> withJavaProperty(String javaProperty) {
168292
return cast(copyBuilder().withJavaProperty(javaProperty).build());
169293
}
@@ -178,10 +302,10 @@ protected <S extends SqlColumn<?>> S cast(SqlColumn<?> column) {
178302
}
179303

180304
/**
181-
* This method helps us tell a bit of fiction to the Java compiler. Java, for better or worse,
182-
* does not carry generic type information through chained methods. We want to enable method
183-
* chaining in the "with" methods. With this bit of fiction, we force the compiler to delay type
184-
* inference to the last method in the chain.
305+
* This method will add all current attributes to the specified builder. It is useful when creating
306+
* new class instances that only change one attribute - we set all current attributes, then
307+
* change the one attribute. This utility can be used with the with* methods and other methods that
308+
* create new instances.
185309
*
186310
* @param <B> the concrete builder type
187311
* @return the populated builder

src/test/java/examples/simple/PrimaryKeyColumn.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ public <S> PrimaryKeyColumn<S> withJavaProperty(String javaProperty) {
6666
}
6767

6868
private Builder<T> copyBuilder() {
69-
return populateBaseBuilder(new Builder<>());
69+
return populateBaseBuilder(new Builder<>()).isPrimaryKeyColumn(isPrimaryKeyColumn);
7070
}
7171

7272
public static class Builder<T> extends AbstractBuilder<T, Builder<T>> {

0 commit comments

Comments
 (0)