@@ -4,14 +4,16 @@ MyBatis Dynamic SQL works with Java objects that represent relational tables or
44## Table or View Representation
55
66The 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
911A table or view name in SQL has three parts:
1012
11131 . 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
1618Typical 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
4245Or
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- < ; empty> ; | "MySchema" | "MyTable" | "MySchema.MyTable"
109- "MyCatalog" | < ; empty> ; | "MyTable" | "MyCatalog..MyTable"
110- < ; empty> ; | < ; empty> ; | "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
14670In join queries, it is usually a good practice to specify table aliases. The `select` statement includes
0 commit comments