2525import org .mybatis .dynamic .sql .util .FragmentAndParameters ;
2626import 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+ */
2870public 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
0 commit comments