Skip to content

Commit 0e2521f

Browse files
committed
Add support for schema/catalog suppliers
1 parent d748511 commit 0e2521f

File tree

8 files changed

+559
-5
lines changed

8 files changed

+559
-5
lines changed

src/main/java/org/mybatis/dynamic/sql/SqlTable.java

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2016-2018 the original author or authors.
2+
* Copyright 2016-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -17,17 +17,63 @@
1717

1818
import java.sql.JDBCType;
1919
import java.util.Objects;
20+
import java.util.Optional;
21+
import java.util.function.Supplier;
2022

2123
public class SqlTable {
22-
23-
private String name;
24+
25+
private Supplier<String> nameSupplier;
2426

2527
protected SqlTable(String name) {
26-
this.name = Objects.requireNonNull(name);
28+
Objects.requireNonNull(name);
29+
30+
this.nameSupplier = () -> name;
31+
}
32+
33+
protected SqlTable(Supplier<Optional<String>> schemaSupplier, String tableName) {
34+
Objects.requireNonNull(schemaSupplier);
35+
Objects.requireNonNull(tableName);
36+
37+
this.nameSupplier = () -> compose(schemaSupplier, tableName);
38+
}
39+
40+
protected SqlTable(Supplier<Optional<String>> catalogSupplier, Supplier<Optional<String>> schemaSupplier, String tableName) {
41+
Objects.requireNonNull(catalogSupplier);
42+
Objects.requireNonNull(schemaSupplier);
43+
Objects.requireNonNull(tableName);
44+
45+
this.nameSupplier = () -> compose(catalogSupplier, schemaSupplier, tableName);
46+
}
47+
48+
private String compose(Supplier<Optional<String>> catalogSupplier, Supplier<Optional<String>> schemaSupplier, String tableName) {
49+
return catalogSupplier.get().map(c -> compose(c, schemaSupplier, tableName))
50+
.orElse(compose(schemaSupplier, tableName));
51+
}
52+
53+
private String compose(String catalog, Supplier<Optional<String>> schemaSupplier, String tableName) {
54+
return schemaSupplier.get().map(s -> composeCatalogSchemaAndAndTable(catalog, s, tableName))
55+
.orElse(composeCatalogAndTable(catalog, tableName));
56+
}
57+
58+
private String compose(Supplier<Optional<String>> schemaSupplier, String tableName) {
59+
return schemaSupplier.get().map(s -> composeSchemaAndTable(s, tableName))
60+
.orElse(tableName);
61+
}
62+
63+
private String composeCatalogAndTable(String catalog, String tableName) {
64+
return catalog + ".." + tableName; //$NON-NLS-1$
2765
}
2866

67+
private String composeSchemaAndTable(String schema, String tableName) {
68+
return schema + "." + tableName; //$NON-NLS-1$
69+
}
70+
71+
private String composeCatalogSchemaAndAndTable(String catalog, String schema, String tableName) {
72+
return catalog + "." + schema + "." + tableName; //$NON-NLS-1$ //$NON-NLS-2$
73+
}
74+
2975
public String name() {
30-
return name;
76+
return nameSupplier.get();
3177
}
3278

3379
public <T> SqlColumn<T> allColumns() {
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/**
2+
* Copyright 2016-2019 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package examples.schema_supplier;
17+
18+
import java.util.Optional;
19+
20+
public class SchemaSupplier {
21+
public static final String schema_property = "schemaToUse";
22+
23+
public static Optional<String> schemaPropertyReader() {
24+
return Optional.ofNullable(System.getProperty(schema_property));
25+
}
26+
}
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
/**
2+
* Copyright 2016-2019 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package examples.schema_supplier;
17+
18+
import static org.assertj.core.api.Assertions.assertThat;
19+
import static org.junit.jupiter.api.Assertions.assertThrows;
20+
21+
import java.io.InputStream;
22+
import java.io.InputStreamReader;
23+
import java.sql.Connection;
24+
import java.sql.DriverManager;
25+
import java.util.List;
26+
27+
import org.apache.ibatis.datasource.unpooled.UnpooledDataSource;
28+
import org.apache.ibatis.exceptions.PersistenceException;
29+
import org.apache.ibatis.jdbc.ScriptRunner;
30+
import org.apache.ibatis.mapping.Environment;
31+
import org.apache.ibatis.session.Configuration;
32+
import org.apache.ibatis.session.SqlSession;
33+
import org.apache.ibatis.session.SqlSessionFactory;
34+
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
35+
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
36+
import org.junit.jupiter.api.BeforeEach;
37+
import org.junit.jupiter.api.Test;
38+
39+
public class SchemaSupplierTest {
40+
41+
private static final String JDBC_URL = "jdbc:hsqldb:mem:aname";
42+
private static final String JDBC_DRIVER = "org.hsqldb.jdbcDriver";
43+
44+
private SqlSessionFactory sqlSessionFactory;
45+
46+
@BeforeEach
47+
public void setup() throws Exception {
48+
Class.forName(JDBC_DRIVER);
49+
InputStream is = getClass().getResourceAsStream("/examples/schema_supplier/CreateDB.sql");
50+
try (Connection connection = DriverManager.getConnection(JDBC_URL, "sa", "")) {
51+
ScriptRunner sr = new ScriptRunner(connection);
52+
sr.setLogWriter(null);
53+
sr.runScript(new InputStreamReader(is));
54+
}
55+
56+
UnpooledDataSource ds = new UnpooledDataSource(JDBC_DRIVER, JDBC_URL, "sa", "");
57+
Environment environment = new Environment("test", new JdbcTransactionFactory(), ds);
58+
Configuration config = new Configuration(environment);
59+
config.addMapper(UserMapper.class);
60+
sqlSessionFactory = new SqlSessionFactoryBuilder().build(config);
61+
}
62+
63+
@Test
64+
public void testUnsetSchemaProperty() {
65+
System.clearProperty(SchemaSupplier.schema_property);
66+
67+
try (SqlSession session = sqlSessionFactory.openSession()) {
68+
UserMapper mapper = session.getMapper(UserMapper.class);
69+
70+
assertThrows(PersistenceException.class, () -> {
71+
User user = new User();
72+
user.setId(1);
73+
user.setName("Fred");
74+
75+
int rows = mapper.insert(user);
76+
77+
assertThat(rows).isEqualTo(1);
78+
});
79+
}
80+
}
81+
82+
@Test
83+
public void testSchemaProperty() {
84+
System.setProperty(SchemaSupplier.schema_property, "schema1");
85+
86+
try (SqlSession session = sqlSessionFactory.openSession()) {
87+
UserMapper mapper = session.getMapper(UserMapper.class);
88+
89+
insertFlintstones(mapper);
90+
91+
List<User> records = mapper.selectByExample()
92+
.build()
93+
.execute();
94+
assertThat(records.size()).isEqualTo(2);
95+
}
96+
}
97+
98+
@Test
99+
public void testSchemaSwitchingProperty() {
100+
try (SqlSession session = sqlSessionFactory.openSession()) {
101+
UserMapper mapper = session.getMapper(UserMapper.class);
102+
103+
System.setProperty(SchemaSupplier.schema_property, "schema1");
104+
insertFlintstones(mapper);
105+
106+
List<User> records = mapper.selectByExample()
107+
.build()
108+
.execute();
109+
assertThat(records.size()).isEqualTo(2);
110+
111+
112+
System.setProperty(SchemaSupplier.schema_property, "schema2");
113+
insertRubbles(mapper);
114+
115+
records = mapper.selectByExample()
116+
.build()
117+
.execute();
118+
assertThat(records.size()).isEqualTo(3);
119+
}
120+
}
121+
122+
private void insertFlintstones(UserMapper mapper) {
123+
User user = new User();
124+
user.setId(1);
125+
user.setName("Fred");
126+
int rows = mapper.insert(user);
127+
assertThat(rows).isEqualTo(1);
128+
129+
user = new User();
130+
user.setId(2);
131+
user.setName("Wilma");
132+
rows = mapper.insert(user);
133+
assertThat(rows).isEqualTo(1);
134+
}
135+
136+
private void insertRubbles(UserMapper mapper) {
137+
User user = new User();
138+
user.setId(1);
139+
user.setName("Barney");
140+
int rows = mapper.insert(user);
141+
assertThat(rows).isEqualTo(1);
142+
143+
user = new User();
144+
user.setId(2);
145+
user.setName("Betty");
146+
rows = mapper.insert(user);
147+
assertThat(rows).isEqualTo(1);
148+
149+
user = new User();
150+
user.setId(3);
151+
user.setName("Bamm Bamm");
152+
rows = mapper.insert(user);
153+
assertThat(rows).isEqualTo(1);
154+
}
155+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**
2+
* Copyright 2016-2019 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package examples.schema_supplier;
17+
18+
public class User {
19+
private int id;
20+
private String name;
21+
22+
public int getId() {
23+
return id;
24+
}
25+
26+
public void setId(int id) {
27+
this.id = id;
28+
}
29+
30+
public String getName() {
31+
return name;
32+
}
33+
34+
public void setName(String name) {
35+
this.name = name;
36+
}
37+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/**
2+
* Copyright 2016-2019 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package examples.schema_supplier;
17+
18+
import java.sql.JDBCType;
19+
20+
import org.mybatis.dynamic.sql.SqlColumn;
21+
import org.mybatis.dynamic.sql.SqlTable;
22+
23+
public class UserDynamicSqlSupport {
24+
public static final User user = new User();
25+
public static final SqlColumn<Integer> id = user.id;
26+
public static final SqlColumn<String> name = user.name;
27+
28+
public static final class User extends SqlTable {
29+
public final SqlColumn<Integer> id = column("user_id", JDBCType.INTEGER);
30+
public final SqlColumn<String> name = column("user_name", JDBCType.VARCHAR);
31+
32+
public User() {
33+
super(SchemaSupplier::schemaPropertyReader, "User");
34+
}
35+
}
36+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/**
2+
* Copyright 2016-2019 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package examples.schema_supplier;
17+
18+
import static examples.schema_supplier.UserDynamicSqlSupport.*;
19+
20+
import java.util.List;
21+
22+
import org.apache.ibatis.annotations.InsertProvider;
23+
import org.apache.ibatis.annotations.Result;
24+
import org.apache.ibatis.annotations.Results;
25+
import org.apache.ibatis.annotations.SelectProvider;
26+
import org.apache.ibatis.type.JdbcType;
27+
import org.mybatis.dynamic.sql.SqlBuilder;
28+
import org.mybatis.dynamic.sql.insert.render.InsertStatementProvider;
29+
import org.mybatis.dynamic.sql.render.RenderingStrategy;
30+
import org.mybatis.dynamic.sql.select.MyBatis3SelectModelAdapter;
31+
import org.mybatis.dynamic.sql.select.QueryExpressionDSL;
32+
import org.mybatis.dynamic.sql.select.SelectDSL;
33+
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
34+
import org.mybatis.dynamic.sql.util.SqlProviderAdapter;
35+
36+
public interface UserMapper {
37+
38+
@InsertProvider(type=SqlProviderAdapter.class, method="insert")
39+
int insert(InsertStatementProvider<User> insertStatement);
40+
41+
@SelectProvider(type=SqlProviderAdapter.class, method="select")
42+
@Results(id="UserResult", value= {
43+
@Result(column="USER_ID", property="id", jdbcType=JdbcType.INTEGER, id=true),
44+
@Result(column="USER_NAME", property="name", jdbcType=JdbcType.VARCHAR)
45+
})
46+
List<User> selectMany(SelectStatementProvider selectStatement);
47+
48+
default QueryExpressionDSL<MyBatis3SelectModelAdapter<List<User>>> selectByExample() {
49+
return SelectDSL.selectWithMapper(this::selectMany, id, name)
50+
.from(user);
51+
}
52+
53+
default int insert(User record) {
54+
return insert(SqlBuilder.insert(record)
55+
.into(user)
56+
.map(id).toProperty("id")
57+
.map(name).toProperty("name")
58+
.build()
59+
.render(RenderingStrategy.MYBATIS3));
60+
}
61+
}

0 commit comments

Comments
 (0)