You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Enhancements in version 1.1.2 make it easier to code complex queries. The Select DSL is implemented as a set of related objects. As the select statement is built, intermediate objects of various types are returned from the various methods that implement the DSL. The select statement can be completed by calling the `build()` method many of the intermediate objects. Prior to version 1.1.2, it was necessary to call `build()` on the **last** intermediate object. This restriction has been removed, and it is now possible to call `build()` on **any** intermediate object. This, along with several other enhancements, has simplified the coding of complex queries.
2
+
Enhancements in version 1.1.2 make it easier to code complex queries. The Select DSL is implemented as a set of related
3
+
objects. As the select statement is built, intermediate objects of various types are returned from the various methods
4
+
that implement the DSL. The select statement can be completed by calling the `build()` method many of the intermediate
5
+
objects. Prior to version 1.1.2, it was necessary to call `build()` on the **last** intermediate object. This
6
+
restriction has been removed, and it is now possible to call `build()` on **any** intermediate object. This, along with
7
+
several other enhancements, has simplified the coding of complex queries.
3
8
4
-
For example, suppose you want to code a complex search on a Person table. The search parameters are id, first name, and last name. The rules are:
9
+
For example, suppose you want to code a complex search on a Person table. The search parameters are id, first name,
10
+
and last name. The rules are:
5
11
6
12
1. If an id is entered, use the id and ignore the other search parameters
7
13
1. If an id is not entered, then do a fuzzy search based on the other parameters
@@ -37,11 +43,21 @@ public String addWildcards(String s) {
37
43
38
44
Notes:
39
45
40
-
1. Note the use of the `var` keyword here. If you are using an older version of Java, the actual type is `QueryExpressionDSL<SelectModel>.QueryExpressionWhereBuilder`
41
-
1. Here we are calling `where()` with no parameters. This sets up the builder to accept conditions further along in the code. If no conditions are added, then the where clause will not be rendered
42
-
1. This `if` statement implements the rules of the search. If an ID is entered , use it. Otherwise, do a fuzzy search based on first name and last name.
43
-
1. The `then` statement on this line allows you to change the parameter value before it is placed in the parameter Map. In this case we are adding SQL wildcards to the start and end of the search String - but only if the search String is not null. If the search String is null, the lambda will not be called and the condition will not render
44
-
1. This shows using a method reference instead of a lambda on the `then`. Method references allow you to more clearly express intent. Note also the use of the `isLikeWhenPresent` condition which is a built in condition that checks for nulls
45
-
1. It is a good idea to limit the number of rows returned from a search. The library now supports `fetch first` syntax for limiting rows
46
-
1. Note that we are calling the `build` method from the intermediate object retrieved in step 1. It is no longer necessary to call `build` on the last object returned from a select builder
46
+
1. Note the use of the `var` keyword here. If you are using an older version of Java, the actual type is
@@ -96,20 +148,22 @@ table lists the optional conditions and shows how to use them:
96
148
97
149
| Condition | Example | Rendering Rules |
98
150
|-----------|---------|-----------------|
99
-
| Between| where(foo, isBetween(x).and(y).when(BiPredicate)) | The library will pass x and y to the BiPredicate's test method. The condition will render if BiPredicate.test(x, y) returns true |
100
-
| Equals | where(foo, isEqualTo(x).when(Predicate)) | The library will pass x to the Predicate's test method. The condition will render if Predicate.test(x) returns true |
101
-
| Greater Than | where(id, isGreaterThan(x).when(Predicate)) | The library will pass x to the Predicate's test method. The condition will render if Predicate.test(x) returns true |
102
-
| Greater Than or Equals | where(id, isGreaterThanOrEqualTo(x).when(Predicate)) | The library will pass x to the Predicate's test method. The condition will render if Predicate.test(x) returns true |
103
-
| Less Than | where(id, isLessThan(x).when(Predicate)) | The library will pass x to the Predicate's test method. The condition will render if Predicate.test(x) returns true |
104
-
| Less Than or Equals | where(id, isLessThanOrEqualTo(x).when(Predicate)) | The library will pass x to the Predicate's test method. The condition will render if Predicate.test(x) returns true |
105
-
| Like | where(id, isLike(x).when(Predicate)) | The library will pass x to the Predicate's test method. The condition will render if Predicate.test(x) returns true |
106
-
| Like Case Insensitive | where(id, isLikeCaseInsensitive(x).when(Predicate<String>)) | The library will pass x to the Predicate's test method. The condition will render if Predicate.test(x) returns true |
107
-
| Not Between | where(id, isNotBetween(x).and(y).when(BiPredicate)) | The library will pass x and y to the BiPredicate's test method. The condition will render if BiPredicate.test(x, y) returns true |
108
-
| Not Equals | where(id, isNotEqualTo(x).when(Predicate)) | The library will pass x to the Predicate's test method. The condition will render if Predicate.test(x) returns true |
109
-
| Not Like | where(id, isNotLike(x).when(Predicate)) | The library will pass x to the Predicate's test method. The condition will render if Predicate.test(x) returns true |
110
-
| Not Like Case Insensitive | where(id, isNotLikeCaseInsensitive(x).when(Predicate<String>)) | The library will pass x to the Predicate's test method. The condition will render if Predicate.test(x) returns true |
111
-
| Not Null | where(id, isNotNull().when(BooleanSupplier) | The condition will render if BooleanSupplier.getAsBoolean() returns true |
112
-
| Null | where(id, isNull().when(BooleanSupplier) | The condition will render if BooleanSupplier.getAsBoolean() returns true |
151
+
| Between| where(foo, isBetween(x).and(y).filter(BiPredicate)) | The library will pass x and y to the BiPredicate's test method. The condition will render if BiPredicate.test(x, y) returns true |
152
+
| Between| where(foo, isBetween(x).and(y).filter(Predicate)) | The library will invoke the Predicate's test method twice - once with x, once with y. The condition will render if both function calls return true |
153
+
| Equals | where(foo, isEqualTo(x).filter(Predicate)) | The library will pass x to the Predicate's test method. The condition will render if Predicate.test(x) returns true |
154
+
| Greater Than | where(id, isGreaterThan(x).filter(Predicate)) | The library will pass x to the Predicate's test method. The condition will render if Predicate.test(x) returns true |
155
+
| Greater Than or Equals | where(id, isGreaterThanOrEqualTo(x).filter(Predicate)) | The library will pass x to the Predicate's test method. The condition will render if Predicate.test(x) returns true |
156
+
| Less Than | where(id, isLessThan(x).filter(Predicate)) | The library will pass x to the Predicate's test method. The condition will render if Predicate.test(x) returns true |
157
+
| Less Than or Equals | where(id, isLessThanOrEqualTo(x).filter(Predicate)) | The library will pass x to the Predicate's test method. The condition will render if Predicate.test(x) returns true |
158
+
| Like | where(id, isLike(x).filter(Predicate)) | The library will pass x to the Predicate's test method. The condition will render if Predicate.test(x) returns true |
159
+
| Like Case Insensitive | where(id, isLikeCaseInsensitive(x).filter(Predicate<String>)) | The library will pass x to the Predicate's test method. The condition will render if Predicate.test(x) returns true |
160
+
| Not Between | where(id, isNotBetween(x).and(y).filter(BiPredicate)) | The library will pass x and y to the BiPredicate's test method. The condition will render if BiPredicate.test(x, y) returns true |
161
+
| Not Between| where(foo, isNotBetween(x).and(y).filter(Predicate)) | The library will invoke the Predicate's test method twice - once with x, once with y. The condition will render if both function calls return true |
162
+
| Not Equals | where(id, isNotEqualTo(x).filter(Predicate)) | The library will pass x to the Predicate's test method. The condition will render if Predicate.test(x) returns true |
163
+
| Not Like | where(id, isNotLike(x).filter(Predicate)) | The library will pass x to the Predicate's test method. The condition will render if Predicate.test(x) returns true |
164
+
| Not Like Case Insensitive | where(id, isNotLikeCaseInsensitive(x).filter(Predicate<String>)) | The library will pass x to the Predicate's test method. The condition will render if Predicate.test(x) returns true |
165
+
| Not Null | where(id, isNotNull().filter(BooleanSupplier) | The condition will render if BooleanSupplier.getAsBoolean() returns true |
166
+
| Null | where(id, isNull().filter(BooleanSupplier) | The condition will render if BooleanSupplier.getAsBoolean() returns true |
113
167
114
168
### "When Present" Condition Builders
115
169
The library supplies several methods that supply conditions to be used in the common case of checking for null
Copy file name to clipboardExpand all lines: src/site/markdown/docs/databaseObjects.md
+58-28Lines changed: 58 additions & 28 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -3,19 +3,23 @@ MyBatis Dynamic SQL works with Java objects that represent relational tables or
3
3
4
4
## Table or View Representation
5
5
6
-
The class `org.mybatis.dynamic.sql.SqlTable` is used to represent a table or view in a database. An `SqlTable` holds a name, and a collection of `SqlColumn` objects that represent the columns in a table or view.
6
+
The class `org.mybatis.dynamic.sql.SqlTable` is used to represent a table or view in a database. An `SqlTable` holds a
7
+
name, and a collection of `SqlColumn` objects that represent the columns in a table or view.
7
8
8
9
A table or view name in SQL has three parts:
9
10
10
-
1. The catalog - which is optional and is rarely used outside of Microsoft SQL Server. If unspecified the default catalog will be used - and many databases only have one catalog
11
-
1. The schema - which is optional but is very often specified. If unspecified the default schema will be used
11
+
1. The catalog - which is optional and is rarely used outside of Microsoft SQL Server. If unspecified the default
12
+
catalog will be used - and many databases only have one catalog
13
+
1. The schema - which is optional but is very often specified. If unspecified, the default schema will be used
12
14
1. The table name - which is required
13
15
14
16
Typical examples of names are as follows:
15
17
16
18
-`"dbo..bar"` - a name with a catalog (dbo) and a table name (bar). This is typical for SQL Server
17
-
-`"foo.bar"` - a name with a schema (foo) and a table name (bar). This is typical in many databases when you want to access tables that are not in the default schema
18
-
-`"bar"` - a name with just a table name (bar). This will access a table or view in the default catalog and schema for a connection
19
+
-`"foo.bar"` - a name with a schema (foo) and a table name (bar). This is typical in many databases when you want to
20
+
access tables that are not in the default schema
21
+
-`"bar"` - a name with just a table name (bar). This will access a table or view in the default catalog and schema for
22
+
a connection
19
23
20
24
In MyBatis Dynamic SQL, the table or view name can be specified in different ways:
21
25
@@ -46,9 +50,13 @@ public class MyTable extends SqlTable {
46
50
```
47
51
48
52
### Dynamic Catalog and/or Schema Names
49
-
MyBatis Dynamic SQL allows you to dynamically specify a catalog and/or schema. This is useful for applications where the schema may change for different users or environments, or if you are using different schemas to shard the database. Dynamic names are used when you use a `SqlTable` constructor that accepts one or more `java.util.function.Supplier` arguments.
53
+
MyBatis Dynamic SQL allows you to dynamically specify a catalog and/or schema. This is useful for applications where
54
+
the schema may change for different users or environments, or if you are using different schemas to shard the database.
55
+
Dynamic names are used when you use a `SqlTable` constructor that accepts one or more `java.util.function.Supplier`
56
+
arguments.
50
57
51
-
For example, suppose you wanted to change the schema based on the value of a system property. You could write a class like this:
58
+
For example, suppose you wanted to change the schema based on the value of a system property. You could write a class
59
+
like this:
52
60
53
61
```java
54
62
publicclassSchemaSupplier {
@@ -60,7 +68,8 @@ public class SchemaSupplier {
60
68
}
61
69
```
62
70
63
-
This class has a static method `schemaPropertyReader` that will return an `Optional<String>` containing the value of a system property. You could then reference this method in the constructor of the `SqlTable` like this:
71
+
This class has a static method `schemaPropertyReader` that will return an `Optional<String>` containing the value of a
72
+
system property. You could then reference this method in the constructor of the `SqlTable` like this:
64
73
65
74
```java
66
75
publicstaticfinalclassUserextendsSqlTable {
@@ -70,14 +79,18 @@ public static final class User extends SqlTable {
70
79
}
71
80
```
72
81
73
-
Whenever the table is referenced for rendering SQL, the name will be calculated based on the current value of the system property.
82
+
Whenever the table is referenced for rendering SQL, the name will be calculated based on the current value of the
83
+
system property.
74
84
75
85
There are two constructors that can be used for dynamic names:
76
86
77
-
1. A constructor that accepts `Supplier<Optional<String>>` for the schema, and `String` for the name. This constructor assumes that the catalog is always empty or not used
78
-
1. A constructor that accepts `Supplier<Optional<String>>` for the catalog, `Supplier<Optional<String>>` for the schema, and `String` for the name
87
+
1. A constructor that accepts `Supplier<Optional<String>>` for the schema, and `String` for the name. This constructor
88
+
assumes that the catalog is always empty or not used
89
+
1. A constructor that accepts `Supplier<Optional<String>>` for the catalog, `Supplier<Optional<String>>` for the schema,
90
+
and `String` for the name
79
91
80
-
If you are using Microsoft SQL Server and want to use a dynamic catalog name and ignore the schema, then you should use the second constructor like this:
92
+
If you are using Microsoft SQL Server and want to use a dynamic catalog name and ignore the schema, then you should use
93
+
the second constructor like this:
81
94
82
95
```java
83
96
publicstaticfinalclassUserextendsSqlTable {
@@ -98,11 +111,12 @@ Catalog Supplier Value | Schema Supplier Value | Name | Fully Qualified Name
98
111
99
112
100
113
### Fully Dynamic Names
101
-
MyBatis Dynamic SQL allows you to dynamically specify a full table name. This is useful for applications where the database is sharded with different tables representing different shards of the whole. Dynamic names are used when you use a `SqlTable` constructor that accepts a single `java.util.function.Supplier` argument.
102
-
103
-
Note that this functionality should only be used for tables that have different names, but are otherwise identical.
114
+
MyBatis Dynamic SQL allows you to dynamically specify a full table name. This is useful for applications where the
115
+
database is sharded with different tables representing different shards of the whole. Dynamic names are used when you
116
+
use a `SqlTable` constructor that accepts a single `java.util.function.Supplier` argument.
104
117
105
-
For example, suppose you wanted to change the name based on the value of a system property. You could write a class like this:
118
+
For example, suppose you wanted to change the name based on the value of a system property. You could write a class
119
+
like this:
106
120
107
121
```java
108
122
publicclassNameSupplier {
@@ -114,7 +128,8 @@ public class NameSupplier {
114
128
}
115
129
```
116
130
117
-
This class has a static method `namePropertyReader` that will return an `String` containing the value of a system property. You could then reference this method in the constructor of the `SqlTable` like this:
131
+
This class has a static method `namePropertyReader` that will return an `String` containing the value of a system
132
+
property. You could then reference this method in the constructor of the `SqlTable` like this:
118
133
119
134
```java
120
135
publicstaticfinalclassUserextendsSqlTable {
@@ -126,23 +141,38 @@ public static final class User extends SqlTable {
126
141
127
142
Whenever the table is referenced for rendering SQL, the name will be calculated based on the current value of the system property.
128
143
129
-
130
-
131
144
## Column Representation
132
145
133
-
The class `org.mybatis.dynamic.sql.SqlColumn` is used to represent a column in a table or view. An `SqlColumn` is always associated with a `SqlTable`. In its most basic form, the `SqlColumn` class holds a name and a reference to the `SqlTable` it is associated with. The table reference is required so that table aliases can be applied to columns in the rendering phase.
146
+
The class `org.mybatis.dynamic.sql.SqlColumn` is used to represent a column in a table or view. An `SqlColumn` is always
147
+
associated with a `SqlTable`. In its most basic form, the `SqlColumn` class holds a name and a reference to the
148
+
`SqlTable` it is associated with. The table reference is required so that table aliases can be applied to columns in the
149
+
rendering phase.
134
150
135
-
The `SqlColumn` will be rendered in SQL based on the `RenderingStrategy` applied to the SQL statement. Typically the rendering strategy generates a string that represents a parameter marker in whatever SQL engine you are using. For example, MyBatis3 parameter markers are formatted as "#{some_attribute}". By default, all columns are rendered with the same strategy. The library supplies rendering strategies that are appropriate for several SQL execution engines including MyBatis3 and Spring JDBC template.
151
+
The `SqlColumn` will be rendered in SQL based on the `RenderingStrategy` applied to the SQL statement. Typically the
152
+
rendering strategy generates a string that represents a parameter marker in whatever SQL engine you are using. For
153
+
example, MyBatis3 parameter markers are formatted as "#{some_attribute}". By default, all columns are rendered with the
154
+
same strategy. The library supplies rendering strategies that are appropriate for several SQL execution engines
155
+
including MyBatis3 and Spring JDBC template.
136
156
137
-
In some cases it is necessary to override the rendering strategy for a particular column - so the `SqlColumn` class supports specifying a rendering strategy for a column that will override the rendering strategy applied to a statement. A good example of this use case is with PostgreSQL. In that database it is required to add the string "::jsonb" to a prepared statement parameter marker when inserting or updating JSON fields, but not for other fields. A column based rendering strategy enables this.
157
+
In some cases it is necessary to override the rendering strategy for a particular column - so the `SqlColumn` class
158
+
supports specifying a rendering strategy for a column that will override the rendering strategy applied to a statement.
159
+
A good example of this use case is with PostgreSQL. In that database it is required to add the string "::jsonb" to a
160
+
prepared statement parameter marker when inserting or updating JSON fields, but not for other fields. A column based
161
+
rendering strategy enables this.
138
162
139
-
The `SqlColumn` class has additional optional attributes that are useful for SQL rendering - especially in MyBatis3. These include:
163
+
The `SqlColumn` class has additional optional attributes that are useful for SQL rendering - especially in MyBatis3.
164
+
These include:
140
165
141
-
* The `java.sql.JDBCType` of the column. This will be rendered into the MyBatis3 compatible parameter marker - which helps with picking type handlers and also inserting or updating null capable fields
142
-
* A String containing a type handler - either a type handler alias or the fully qualified type of a type handler. This will be rendered into the MyBatis3 compatible parameter marker
166
+
* The `java.sql.JDBCType` of the column. This will be rendered into the MyBatis3 compatible parameter marker - which
167
+
helps with picking type handlers and also inserting or updating null capable fields
168
+
* A String containing a type handler - either a type handler alias or the fully qualified type of a type handler. This
169
+
will be rendered into the MyBatis3 compatible parameter marker
143
170
144
-
If you are not using MyBatis3, then you will not need to specify the JDBC Type or type handler as those attributes are ignored by other rendering strategies.
171
+
If you are not using MyBatis3, then you do not need to specify the JDBC Type or type handler as those attributes are
172
+
ignored by other rendering strategies.
145
173
146
-
Finally, the `SqlColumn` class has methods to designate a column alias or sort order for use in different SQL statements.
174
+
Finally, the `SqlColumn` class has methods to designate a column alias or sort order for use in different SQL
175
+
statements.
147
176
148
-
We recommend a usage pattern for creating table and column objects that provides quite a bit of flexibility for usage. See the [Quick Start](quickStart.html) page for a complete example.
177
+
We recommend a usage pattern for creating table and column objects that provides quite a bit of flexibility for usage.
178
+
See the [Quick Start](quickStart.html) page for a complete example.
We do not recommend using an XML mapper for delete statements, but if you want to do so the DeleteStatementProvider object can be used as a parameter to a MyBatis mapper method directly.
40
+
We do not recommend using an XML mapper for delete statements, but if you want to do so, the DeleteStatementProvider
41
+
object can be used as a parameter to a MyBatis mapper method directly.
41
42
42
43
If you are using an XML mapper, the delete method should look like this in the Java interface:
0 commit comments