Skip to content

Commit ffb2a02

Browse files
committed
Documentation for changing table names
1 parent 031502c commit ffb2a02

File tree

2 files changed

+27
-99
lines changed

2 files changed

+27
-99
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ The pull request for this change is ([#550](https://github.com/mybatis/mybatis-d
4646
3. Refactored the common insert mapper support for MyBatis3 by adding a CommonGeneralInsertMapper that can be used
4747
without a class that matches the table row. It includes methods for general insert and insert select.
4848
([#570](https://github.com/mybatis/mybatis-dynamic-sql/pull/570))
49+
4. Added the ability to change a table name on AliasableSqlTable - this creates a new instance of the object with a new
50+
name. This is useful in sharded databases where the name of the table is calculated based on some sharding
51+
algorithm. Also deprecated the constructors on SqlTable that accept Suppliers for table name - this creates an
52+
effectively mutable object and goes against the principles of immutability that we strive for in the library.
4953

5054

5155

src/site/markdown/docs/databaseObjects.md

+23-99
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,16 @@ MyBatis Dynamic SQL works with Java objects that represent relational tables or
44
## Table or View Representation
55

66
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+
name, and a collection of `SqlColumn` objects that represent the columns in a table or view. A subclass of `SqlTable` -
8+
`AliasableSqlTable` should be used in cases where you want to specify a table alias that should be used in all cases,
9+
or if you need to change the table name at runtime.
810

911
A table or view name in SQL has three parts:
1012

1113
1. The catalog - which is optional and is rarely used outside of Microsoft SQL Server. If unspecified the default
1214
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
14-
1. The table name - which is required
15+
2. The schema - which is optional but is very often specified. If unspecified, the default schema will be used
16+
3. The table name - which is required
1517

1618
Typical examples of names are as follows:
1719

@@ -21,126 +23,48 @@ Typical examples of names are as follows:
2123
- `"bar"` - a name with just a table name (bar). This will access a table or view in the default catalog and schema for
2224
a connection
2325

24-
In MyBatis Dynamic SQL, the table or view name can be specified in different ways:
26+
In MyBatis Dynamic SQL, the full name of the table should be supplied on the constructor of the table object.
27+
If a table name needs to change at runtime (say for sharding support), then use the `withName` method on
28+
`AliasableSqlTable` to create an instance with the new name.
2529

26-
1. The name can be a constant String
27-
1. The name can be calculated at runtime based on a catalog and/or schema supplier functions and a constant table name
28-
1. The name can be calculated at runtime with a name supplier function
30+
We recommend using the base class `AliasableSqlTable` in all cases as it provides the most flexibility. The
31+
`SqlTable` class remains in the library for compatibility with older code only.
2932

30-
### Constant Names
31-
32-
Constant names are used when you use the `SqlTable` constructor with a single String argument. For example:
33+
For example:
3334

3435
```java
35-
public class MyTable extends SqlTable {
36+
import org.mybatis.dynamic.sql.AliasableSqlTable;
37+
38+
public class MyTable extends AliasableSqlTable<MyTable> {
3639
public MyTable() {
37-
super("MyTable");
40+
super("MyTable", MyTable::new);
3841
}
3942
}
4043
```
4144

4245
Or
4346

4447
```java
45-
public class MyTable extends SqlTable {
48+
public class MyTable extends AliasableSqlTable<MyTable> {
4649
public MyTable() {
47-
super("MySchema.MyTable");
48-
}
49-
}
50-
```
51-
52-
### Dynamic Catalog and/or Schema Names
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.
57-
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:
60-
61-
```java
62-
public class SchemaSupplier {
63-
public static final String schema_property = "schemaToUse";
64-
65-
public static Optional<String> schemaPropertyReader() {
66-
return Optional.ofNullable(System.getProperty(schema_property));
50+
super("MySchema.MyTable", MyTable::new);
6751
}
6852
}
6953
```
7054

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:
73-
74-
```java
75-
public static final class User extends SqlTable {
76-
public User() {
77-
super(SchemaSupplier::schemaPropertyReader, "User");
78-
}
79-
}
80-
```
81-
82-
Whenever the table is referenced for rendering SQL, the name will be calculated based on the current value of the
83-
system property.
84-
85-
There are two constructors that can be used for dynamic names:
86-
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
91-
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:
55+
You can change a table name:
9456

9557
```java
96-
public static final class User extends SqlTable {
97-
public User() {
98-
super(CatalogSupplier::catalogPropertyReader, Optional::empty, "User");
99-
}
100-
}
101-
```
102-
103-
The following table shows how the name is calculated in all combinations of suppliers:
104-
105-
Catalog Supplier Value | Schema Supplier Value | Name | Fully Qualified Name
106-
---|---|---|---
107-
"MyCatalog" | "MySchema" | "MyTable" | "MyCatalog.MySchema.MyTable"
108-
&lt;empty&gt; | "MySchema" | "MyTable" | "MySchema.MyTable"
109-
"MyCatalog" | &lt;empty&gt; | "MyTable" | "MyCatalog..MyTable"
110-
&lt;empty&gt; | &lt;empty&gt; | "MyTable" | "MyTable"
111-
112-
113-
### Fully Dynamic Names
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.
117-
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:
120-
121-
```java
122-
public class NameSupplier {
123-
public static final String name_property = "nameToUse";
124-
125-
public static String namePropertyReader() {
126-
return System.getProperty(name_property);
58+
public class MyTable extends AliasableSqlTable<MyTable> {
59+
public MyTable() {
60+
super("Schema1.MyTable", MyTable::new);
12761
}
12862
}
129-
```
130-
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:
13363

134-
```java
135-
public static final class User extends SqlTable {
136-
public User() {
137-
super(NameSupplier::namePropertyReader);
138-
}
139-
}
64+
MyTable schema1Table = new MyTable();
65+
MyTable schema2Table = schema1Table.withName("Schema2.MyTable");
14066
```
14167

142-
Whenever the table is referenced for rendering SQL, the name will be calculated based on the current value of the system property.
143-
14468
## Aliased Tables
14569

14670
In join queries, it is usually a good practice to specify table aliases. The `select` statement includes

0 commit comments

Comments
 (0)