|
| 1 | +# Database Object Representation |
| 2 | +MyBatis Dynamic SQL works with Java objects that represent relational tables or views. |
| 3 | + |
| 4 | +## Table or View Representation |
| 5 | + |
| 6 | +The class `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. |
| 7 | + |
| 8 | +A fully qualified name has three parts: |
| 9 | + |
| 10 | +1. The catalog - which is rarely used outside of Microsoft SQL Server |
| 11 | +1. The schema - which is often specified, but may be left blank if you are operating on tables in the default schema |
| 12 | +1. The name - which is required |
| 13 | + |
| 14 | +Typical examples of fully qualified names are as follows: |
| 15 | + |
| 16 | +- `"dbo..bar"` - a fully qualified name with a catalog (dbo) and a name (bar). This is typical for SQL Server |
| 17 | +- `"foo.bar"` - a fully qualified name with a schema (foo) and a name (bar). This is typical in many databases when you want to access tables that are not in the default schema |
| 18 | +- `"bar"` - a fully qualified name with just a name (bar). This will access a table or view in the default catalog and schema for a connection |
| 19 | + |
| 20 | + |
| 21 | +In MyBatis Dynamic SQL, the fully qualified name can be specified in different ways: |
| 22 | + |
| 23 | +1. The fully qualified table name can be a constant String |
| 24 | +1. The fully qualified table name can be calculated at runtime based on a dynamic catalog and/or schema and a constant table name |
| 25 | + |
| 26 | +### Constant Names |
| 27 | + |
| 28 | +Constant names are used when you use the `SqlTable` constructor with a single String argument. For example: |
| 29 | + |
| 30 | +```java |
| 31 | +public class MyTable extends SqlTable { |
| 32 | + public MyTable() { |
| 33 | + super("MyTable"); |
| 34 | + } |
| 35 | +} |
| 36 | +``` |
| 37 | + |
| 38 | +Or |
| 39 | + |
| 40 | +```java |
| 41 | +public class MyTable extends SqlTable { |
| 42 | + public MyTable() { |
| 43 | + super("MySchema.MyTable"); |
| 44 | + } |
| 45 | +} |
| 46 | +``` |
| 47 | + |
| 48 | + |
| 49 | +### Dynamic Names |
| 50 | +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. |
| 51 | + |
| 52 | +For example, suppose you wanted to change the schema based on the value of a system property. You could write a class like this: |
| 53 | + |
| 54 | +```java |
| 55 | +public class SchemaSupplier { |
| 56 | + public static final String schema_property = "schemaToUse"; |
| 57 | + |
| 58 | + public static Optional<String> schemaPropertyReader() { |
| 59 | + return Optional.ofNullable(System.getProperty(schema_property)); |
| 60 | + } |
| 61 | +} |
| 62 | +``` |
| 63 | + |
| 64 | +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: |
| 65 | + |
| 66 | +```java |
| 67 | +public static final class User extends SqlTable { |
| 68 | + public User() { |
| 69 | + super(SchemaSupplier::schemaPropertyReader, "User"); |
| 70 | + } |
| 71 | +} |
| 72 | +``` |
| 73 | + |
| 74 | +Whenever the table is referenced for rendering SQL, the name will be calculated based on the current value of the system property. |
| 75 | + |
| 76 | +There are two constructors that can be used for dynamic names: |
| 77 | + |
| 78 | +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 |
| 79 | +1. A constructor that accepts `Supplier<Optional<String>>` for the catalog, `Supplier<Optional<String>>` for the schema, and `String` for the name |
| 80 | + |
| 81 | +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: |
| 82 | + |
| 83 | +```java |
| 84 | +public static final class User extends SqlTable { |
| 85 | + public User() { |
| 86 | + super(CatalogSupplier::catalogPropertyReader, Optional::empty, "User"); |
| 87 | + } |
| 88 | +} |
| 89 | +``` |
| 90 | + |
| 91 | +The following table shows how the name is calculated in all combinations of suppliers: |
| 92 | + |
| 93 | +Catalog Supplier Value | Schema Supplier Value | Name | Fully Qualified Name |
| 94 | +---|---|---|--- |
| 95 | +"MyCatalog" | "MySchema" | "MyTable" | "MyCatalog.MySchema.MyTable" |
| 96 | +<empty> | "MySchema" | "MyTable" | "MySchema.MyTable" |
| 97 | +"MyCatalog" | <empty> | "MyTable" | "MyCatalog..MyTable" |
| 98 | +<empty> | <empty> | "MyTable" | "MyTable" |
| 99 | + |
| 100 | + |
| 101 | + |
| 102 | +## Column Representation |
0 commit comments