Add unit tests for dynamic-datasource-spring-boot3-starter (#552)

This commit is contained in:
Ling Hengqian 2023-08-25 11:06:24 +08:00 committed by GitHub
parent bc747fad91
commit 18b5312b68
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 869 additions and 2 deletions

67
.github/workflows/ci.yml vendored Normal file
View File

@ -0,0 +1,67 @@
name: CI
on:
push:
branches: [ master ]
paths:
- '.github/workflows/ci.yml'
- '**/pom.xml'
- '**/src/main/**'
- '**/src/test/**'
pull_request:
branches: [ master ]
paths:
- '.github/workflows/ci.yml'
- '**/pom.xml'
- '**/src/main/**'
- '**/src/test/**'
concurrency:
group: ${{ github.event_name }}-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
MAVEN_OPTS: -Dhttps.protocols=TLSv1.2 -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN -Dorg.slf4j.simpleLogger.showDateTime=true -Djava.awt.headless=true
jobs:
test-maximum-jdk-ci:
name: Test CI - JDK ${{ matrix.java-version }} on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
timeout-minutes: 60
strategy:
matrix:
os: [ ubuntu-latest ]
java-version: [ '17' ]
steps:
- uses: actions/checkout@v3
- name: Setup java
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: ${{ matrix.java-version }}
cache: 'maven'
- name: Build test with Maven
run: |
./mvnw -am -pl dynamic-datasource-spring-boot3-starter -T1C -B clean test
test-minimum-jdk-ci:
name: Test CI - JDK ${{ matrix.java-version }} on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
timeout-minutes: 60
strategy:
matrix:
os: [ ubuntu-latest ]
java-version: [ '8' ]
steps:
- uses: actions/checkout@v3
- name: Setup java
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: ${{ matrix.java-version }}
cache: 'maven'
- name: Build test with Maven
run: |
./mvnw -am -pl dynamic-datasource-creator -T1C -B clean package
./mvnw -am -pl dynamic-datasource-spring -T1C -B clean package
./mvnw -am -pl dynamic-datasource-spring-boot-common -T1C -B clean package
./mvnw -am -pl dynamic-datasource-spring-boot-starter -T1C -B clean package

View File

@ -21,7 +21,7 @@
<img src="https://img.shields.io/:license-apache-brightgreen.svg" >
</a>
<a>
<img src="https://img.shields.io/badge/JDK-1.7+-green.svg" >
<img src="https://img.shields.io/badge/JDK-8+-green.svg" >
</a>
<a>
<img src="https://img.shields.io/badge/springBoot-1.5.x__2.x.x__3.x.x-green.svg" >

View File

@ -16,7 +16,7 @@
<properties>
<java.version>11</java.version>
<java.version>17</java.version>
<spring-boot-dependencies.version>3.1.1</spring-boot-dependencies.version>
</properties>
@ -41,6 +41,17 @@
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${h2.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,68 @@
/*
* Copyright © 2018 organization baomidou
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.baomidou.dynamic.datasource.fixture;
import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import com.baomidou.dynamic.datasource.creator.DataSourceProperty;
import com.baomidou.dynamic.datasource.creator.DefaultDataSourceCreator;
import com.baomidou.dynamic.datasource.creator.hikaricp.HikariCpConfig;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.jdbc.datasource.SimpleDriverDataSource;
import javax.sql.DataSource;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
@SpringBootTest(classes = AddRemoveDatasourceApplication.class, webEnvironment = RANDOM_PORT)
public class AddRemoveDatasourceTest {
@Autowired
DataSource dataSource;
@Autowired
DefaultDataSourceCreator dataSourceCreator;
@Test
void testAddAndRemoveDataSource() {
HikariCpConfig hikariCpConfig = new HikariCpConfig();
hikariCpConfig.setConnectionTestQuery("select 1");
DataSourceProperty dataSourceProperty = new DataSourceProperty();
dataSourceProperty.setHikari(hikariCpConfig);
dataSourceProperty.setPoolName("slave_1");
dataSourceProperty.setUsername("sa");
dataSourceProperty.setPassword("");
dataSourceProperty.setType(SimpleDriverDataSource.class);
dataSourceProperty.setUrl("jdbc:h2:mem:test1;MODE=MySQL");
dataSourceProperty.setDriverClassName("org.h2.Driver");
DynamicRoutingDataSource ds = (DynamicRoutingDataSource) dataSource;
ds.addDataSource(dataSourceProperty.getPoolName(), dataSourceCreator.createDataSource(dataSourceProperty));
assertThat(ds.getDataSources().keySet()).contains("slave_1");
ds.removeDataSource("slave_1");
assertThat(ds.getDataSources().keySet()).doesNotContain("slave_1");
}
}
@SpringBootApplication
class AddRemoveDatasourceApplication {
public static void main(String[] args) {
SpringApplication.run(AddRemoveDatasourceApplication.class, args);
}
}

View File

@ -0,0 +1,95 @@
/*
* Copyright © 2018 organization baomidou
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.baomidou.dynamic.datasource.fixture;
import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import com.baomidou.dynamic.datasource.creator.DataSourceProperty;
import com.baomidou.dynamic.datasource.creator.DefaultDataSourceCreator;
import com.baomidou.dynamic.datasource.provider.AbstractJdbcDataSourceProvider;
import com.baomidou.dynamic.datasource.provider.DynamicDataSourceProvider;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.datasource.SimpleDriverDataSource;
import javax.sql.DataSource;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Map;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
@SpringBootTest(classes = LoadDatasourceFromJDBCApplication.class, webEnvironment = RANDOM_PORT)
public class LoadDatasourceFromJDBCTest {
@Autowired
DataSource dataSource;
@Test
void testExistDataSource() {
DynamicRoutingDataSource ds = (DynamicRoutingDataSource) dataSource;
assertThat(ds.getDataSources().keySet()).contains("master", "db1", "db2", "db3");
}
}
@SuppressWarnings({"SqlDialectInspection", "SqlNoDataSourceInspection"})
@SpringBootApplication
class LoadDatasourceFromJDBCApplication {
public static void main(String[] args) {
SpringApplication.run(LoadDatasourceFromJDBCApplication.class, args);
}
@Bean
public DynamicDataSourceProvider dynamicDataSourceProvider(DefaultDataSourceCreator dataSourceCreator) {
return new AbstractJdbcDataSourceProvider(dataSourceCreator, "org.h2.Driver", "jdbc:h2:mem:test;MODE=MySQL", "sa", "") {
@Override
protected Map<String, DataSourceProperty> executeStmt(Statement statement) throws SQLException {
statement.execute("""
CREATE TABLE IF NOT EXISTS `DB`
(
`name` VARCHAR(30) NULL DEFAULT NULL,
`username` VARCHAR(30) NULL DEFAULT NULL,
`password` VARCHAR(30) NULL DEFAULT NULL,
`url` VARCHAR(30) NULL DEFAULT NULL,
`driver` VARCHAR(30) NULL DEFAULT NULL
)""");
statement.executeUpdate("insert into DB values ('master','sa','','jdbc:h2:mem:test;MODE=MySQL','org.h2.Driver')");
statement.executeUpdate("insert into DB values ('db1','sa','','jdbc:h2:mem:test2','org.h2.Driver')");
statement.executeUpdate("insert into DB values ('db2','sa','','jdbc:h2:mem:test3','org.h2.Driver')");
statement.executeUpdate("insert into DB values ('db3','sa','','jdbc:h2:mem:test4','org.h2.Driver')");
Map<String, DataSourceProperty> map = new HashMap<>();
ResultSet rs = statement.executeQuery("select * from DB");
while (rs.next()) {
DataSourceProperty dataSourceProperty = new DataSourceProperty();
dataSourceProperty.setUsername(rs.getString("username"));
dataSourceProperty.setPassword(rs.getString("password"));
dataSourceProperty.setUrl(rs.getString("url"));
dataSourceProperty.setDriverClassName(rs.getString("driver"));
dataSourceProperty.setType(SimpleDriverDataSource.class);
map.put(rs.getString("name"), dataSourceProperty);
}
return map;
}
};
}
}

View File

@ -0,0 +1,95 @@
/*
* Copyright © 2018 organization baomidou
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.baomidou.dynamic.datasource.fixture;
import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import com.baomidou.dynamic.datasource.creator.DataSourceProperty;
import com.baomidou.dynamic.datasource.creator.DefaultDataSourceCreator;
import com.baomidou.dynamic.datasource.fixture.service.nest.*;
import org.h2.tools.Server;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Bean;
import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
@SpringBootTest(classes = NestApplication.class, webEnvironment = RANDOM_PORT)
public class NestDataSourceTest {
@Autowired
DataSource dataSource;
@Autowired
DefaultDataSourceCreator dataSourceCreator;
@Autowired
TeacherService teacherService;
@Autowired
StudentService studentService;
@Autowired
SchoolService schoolService;
@Test
void testNest() {
DataSourceProperty masterDataSourceProperty = new DataSourceProperty();
masterDataSourceProperty.setPoolName("master");
masterDataSourceProperty.setDriverClassName("org.h2.Driver");
masterDataSourceProperty.setUrl("jdbc:h2:mem:test;MODE=MySQL;DB_CLOSE_ON_EXIT=FALSE;INIT=RUNSCRIPT FROM 'classpath:db/add-remove-datasource.sql'");
masterDataSourceProperty.setUsername("sa");
masterDataSourceProperty.setPassword("");
DataSourceProperty teacherDataSourceProperty = new DataSourceProperty();
teacherDataSourceProperty.setPoolName("teacher");
teacherDataSourceProperty.setDriverClassName("org.h2.Driver");
teacherDataSourceProperty.setUrl("jdbc:h2:mem:test;MODE=MySQL;DB_CLOSE_ON_EXIT=FALSE;INIT=RUNSCRIPT FROM 'classpath:db/add-remove-datasource.sql'");
teacherDataSourceProperty.setUsername("sa");
teacherDataSourceProperty.setPassword("");
DataSourceProperty studentDataSourceProperty = new DataSourceProperty();
studentDataSourceProperty.setPoolName("student");
studentDataSourceProperty.setDriverClassName("org.h2.Driver");
studentDataSourceProperty.setUrl("jdbc:h2:mem:test;MODE=MySQL;DB_CLOSE_ON_EXIT=FALSE;INIT=RUNSCRIPT FROM 'classpath:db/add-remove-datasource.sql'");
studentDataSourceProperty.setUsername("sa");
studentDataSourceProperty.setPassword("");
DynamicRoutingDataSource ds = (DynamicRoutingDataSource) dataSource;
ds.addDataSource(masterDataSourceProperty.getPoolName(), dataSourceCreator.createDataSource(masterDataSourceProperty));
ds.addDataSource(teacherDataSourceProperty.getPoolName(), dataSourceCreator.createDataSource(teacherDataSourceProperty));
ds.addDataSource(studentDataSourceProperty.getPoolName(), dataSourceCreator.createDataSource(studentDataSourceProperty));
assertThat(ds.getDataSources().keySet()).contains("master", "teacher", "student");
assertThat(teacherService.addTeacherWithTx("ss", 1)).isEqualTo(1);
assertThat(studentService.addStudentWithTx("tt", 2)).isEqualTo(1);
assertThat(teacherService.selectTeachers()).isEqualTo(List.of(new Teacher(1, "tt", 2)));
assertThat(studentService.selectStudents()).isEqualTo(List.of(new Student(1, "tt", 2)));
assertThat(schoolService.addTeacherAndStudentWithTx()).isEqualTo(2);
assertThat(teacherService.selectTeachers()).isEqualTo(List.of(new Teacher(1, "tt", 2), new Teacher(2, "bb", 4)));
assertThat(studentService.selectStudents()).isEqualTo(List.of(new Student(1, "tt", 2), new Student(2, "bb", 4)));
}
}
@SpringBootApplication
class NestApplication {
public static void main(String[] args) {
SpringApplication.run(NestApplication.class, args);
}
}

View File

@ -0,0 +1,127 @@
/*
* Copyright © 2018 organization baomidou
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.baomidou.dynamic.datasource.fixture;
import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import com.baomidou.dynamic.datasource.creator.DataSourceProperty;
import com.baomidou.dynamic.datasource.creator.DefaultDataSourceCreator;
import com.baomidou.dynamic.datasource.fixture.service.spel.User;
import com.baomidou.dynamic.datasource.fixture.service.spel.UserService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.web.context.WebApplicationContext;
import javax.sql.DataSource;
import java.nio.charset.StandardCharsets;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup;
@SpringBootTest(classes = SPELApplication.class, webEnvironment = RANDOM_PORT)
public class SPELTest {
MockMvc mockMvc;
@Autowired
DataSource dataSource;
@Autowired
DefaultDataSourceCreator dataSourceCreator;
@Autowired
UserService userService;
@BeforeEach
void setup(WebApplicationContext webApplicationContext) {
this.mockMvc = webAppContextSetup(webApplicationContext).defaultResponseCharacterEncoding(StandardCharsets.UTF_8).build();
}
@Test
void testSPEL() {
DataSourceProperty masterDataSourceProperty = new DataSourceProperty();
masterDataSourceProperty.setPoolName("master");
masterDataSourceProperty.setDriverClassName("org.h2.Driver");
masterDataSourceProperty.setUrl("jdbc:h2:mem:test;MODE=MySQL;DB_CLOSE_ON_EXIT=FALSE;INIT=RUNSCRIPT FROM 'classpath:db/spring-expression-language.sql'");
masterDataSourceProperty.setUsername("sa");
masterDataSourceProperty.setPassword("");
DataSourceProperty tenant1_1DataSourceProperty = new DataSourceProperty();
tenant1_1DataSourceProperty.setPoolName("tenant1_1");
tenant1_1DataSourceProperty.setDriverClassName("org.h2.Driver");
tenant1_1DataSourceProperty.setUrl("jdbc:h2:mem:test;MODE=MySQL;DB_CLOSE_ON_EXIT=FALSE;INIT=RUNSCRIPT FROM 'classpath:db/spring-expression-language.sql'");
tenant1_1DataSourceProperty.setUsername("sa");
tenant1_1DataSourceProperty.setPassword("");
DataSourceProperty tenant1_2DataSourceProperty = new DataSourceProperty();
tenant1_2DataSourceProperty.setPoolName("tenant1_2");
tenant1_2DataSourceProperty.setDriverClassName("org.h2.Driver");
tenant1_2DataSourceProperty.setUrl("jdbc:h2:mem:test;MODE=MySQL;DB_CLOSE_ON_EXIT=FALSE;INIT=RUNSCRIPT FROM 'classpath:db/spring-expression-language.sql'");
tenant1_2DataSourceProperty.setUsername("sa");
tenant1_2DataSourceProperty.setPassword("");
DataSourceProperty tenant2_1DataSourceProperty = new DataSourceProperty();
tenant2_1DataSourceProperty.setPoolName("tenant2_1");
tenant2_1DataSourceProperty.setDriverClassName("org.h2.Driver");
tenant2_1DataSourceProperty.setUrl("jdbc:h2:mem:test;MODE=MySQL;DB_CLOSE_ON_EXIT=FALSE;INIT=RUNSCRIPT FROM 'classpath:db/spring-expression-language.sql'");
tenant2_1DataSourceProperty.setUsername("sa");
tenant2_1DataSourceProperty.setPassword("");
DataSourceProperty tenant2_2DataSourceProperty = new DataSourceProperty();
tenant2_2DataSourceProperty.setPoolName("tenant2_2");
tenant2_2DataSourceProperty.setDriverClassName("org.h2.Driver");
tenant2_2DataSourceProperty.setUrl("jdbc:h2:mem:test;MODE=MySQL;DB_CLOSE_ON_EXIT=FALSE");
tenant2_2DataSourceProperty.setUsername("sa");
tenant2_2DataSourceProperty.setPassword("");
DynamicRoutingDataSource ds = (DynamicRoutingDataSource) dataSource;
ds.addDataSource(masterDataSourceProperty.getPoolName(), dataSourceCreator.createDataSource(masterDataSourceProperty));
ds.addDataSource(tenant1_1DataSourceProperty.getPoolName(), dataSourceCreator.createDataSource(tenant1_1DataSourceProperty));
ds.addDataSource(tenant1_2DataSourceProperty.getPoolName(), dataSourceCreator.createDataSource(tenant1_2DataSourceProperty));
ds.addDataSource(tenant2_1DataSourceProperty.getPoolName(), dataSourceCreator.createDataSource(tenant2_1DataSourceProperty));
ds.addDataSource(tenant2_2DataSourceProperty.getPoolName(), dataSourceCreator.createDataSource(tenant2_2DataSourceProperty));
assertThat(ds.getDataSources().keySet()).contains("master", "tenant1_1", "tenant1_2", "tenant2_1", "tenant2_2");
assertDoesNotThrow(() -> {
mockMvc.perform(MockMvcRequestBuilders.get("/users/session").characterEncoding(StandardCharsets.UTF_8))
.andDo(print()).andExpectAll(
status().isOk(),
content().encoding(StandardCharsets.UTF_8)
).andReturn().getResponse().getContentAsString();
mockMvc.perform(MockMvcRequestBuilders.get("/users/header").contentType(MediaType.APPLICATION_FORM_URLENCODED)
.header("tenantName", "tenant1")
.characterEncoding(StandardCharsets.UTF_8)
).andDo(print()).andExpectAll(
status().isOk(),
content().encoding(StandardCharsets.UTF_8)
).andReturn().getResponse().getContentAsString();
});
assertThat(userService.selectSpelByKey("tenant1")).isEqualTo("tenant1");
assertThat(userService.selecSpelByTenant(new User("tenant2"))).isEqualTo("tenant2");
}
}
@SpringBootApplication
class SPELApplication {
public static void main(String[] args) {
SpringApplication.run(SPELApplication.class, args);
}
}

View File

@ -0,0 +1,46 @@
/*
* Copyright © 2018 organization baomidou
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.baomidou.dynamic.datasource.fixture.controller;
import com.baomidou.dynamic.datasource.fixture.service.spel.User;
import com.baomidou.dynamic.datasource.fixture.service.spel.UserService;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RequestMapping("/users")
@RestController
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/session")
public List<User> session(HttpServletRequest request) {
request.getSession().setAttribute("tenantName", "tenant1");
return userService.selectSpelBySession();
}
@GetMapping("/header")
public String header() {
userService.selectSpelByHeader();
return "success";
}
}

View File

@ -0,0 +1,37 @@
/*
* Copyright © 2018 organization baomidou
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.baomidou.dynamic.datasource.fixture.service.nest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class SchoolService {
private final TeacherService teacherService;
private final StudentService studentService;
public SchoolService(TeacherService teacherService, StudentService studentService) {
this.teacherService = teacherService;
this.studentService = studentService;
}
@Transactional
public int addTeacherAndStudentWithTx() {
int aa = teacherService.addTeacherNoTx("aa", 3);
int bb = studentService.addStudentNoTx("bb", 4);
return aa + bb;
}
}

View File

@ -0,0 +1,19 @@
/*
* Copyright © 2018 organization baomidou
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.baomidou.dynamic.datasource.fixture.service.nest;
public record Student(Integer id, String name, Integer age) {
}

View File

@ -0,0 +1,75 @@
/*
* Copyright © 2018 organization baomidou
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.baomidou.dynamic.datasource.fixture.service.nest;
import com.baomidou.dynamic.datasource.annotation.DS;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.LinkedList;
import java.util.List;
@SuppressWarnings({"SqlDialectInspection", "SqlNoDataSourceInspection"})
@Service
@DS("student")
public class StudentService {
private final DataSource dataSource;
public StudentService(DataSource dataSource) {
this.dataSource = dataSource;
}
@Transactional
public int addStudentWithTx(String name, Integer age) {
try (Connection connection = dataSource.getConnection(); PreparedStatement preparedStatement = connection.prepareStatement("insert into student (name,age) values (?,?)")) {
preparedStatement.setString(1, name);
preparedStatement.setInt(2, age);
return preparedStatement.executeUpdate();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
public int addStudentNoTx(String name, Integer age) {
try (Connection connection = dataSource.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("insert into student (name,age) values (?,?)")) {
preparedStatement.setString(1, name);
preparedStatement.setInt(2, age);
return preparedStatement.executeUpdate();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
public List<Student> selectStudents() {
List<Student> result = new LinkedList<>();
try (Connection connection = dataSource.getConnection(); Statement statement = connection.createStatement()) {
ResultSet resultSet = statement.executeQuery("SELECT * FROM student");
while (resultSet.next()) {
result.add(new Student(resultSet.getInt(1), resultSet.getString(2), resultSet.getInt(3)));
}
return result;
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}

View File

@ -0,0 +1,19 @@
/*
* Copyright © 2018 organization baomidou
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.baomidou.dynamic.datasource.fixture.service.nest;
public record Teacher(Integer id, String name, Integer age) {
}

View File

@ -0,0 +1,78 @@
/*
* Copyright © 2018 organization baomidou
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.baomidou.dynamic.datasource.fixture.service.nest;
import com.baomidou.dynamic.datasource.annotation.DS;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.LinkedList;
import java.util.List;
@SuppressWarnings({"SqlNoDataSourceInspection", "SqlDialectInspection"})
@Service
@DS("teacher")
public class TeacherService {
private final DataSource dataSource;
public TeacherService(DataSource dataSource) {
this.dataSource = dataSource;
}
@Transactional
public int addTeacherWithTx(String name, Integer age) {
try (Connection connection = dataSource.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("insert into teacher (name,age) values (?,?)")) {
preparedStatement.setString(1, name);
preparedStatement.setInt(2, age);
return preparedStatement.executeUpdate();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
public int addTeacherNoTx(String name, Integer age) {
try (Connection connection = dataSource.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("insert into teacher (name,age) values (?,?)")) {
preparedStatement.setString(1, name);
preparedStatement.setInt(2, age);
return preparedStatement.executeUpdate();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
public List<Teacher> selectTeachers() {
List<Teacher> result = new LinkedList<>();
try (Connection connection = dataSource.getConnection();
Statement statement = connection.createStatement()) {
ResultSet resultSet = statement.executeQuery("SELECT * FROM student");
while (resultSet.next()) {
result.add(new Teacher(resultSet.getInt(1), resultSet.getString(2), resultSet.getInt(3)));
}
return result;
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}

View File

@ -0,0 +1,22 @@
/*
* Copyright © 2018 organization baomidou
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.baomidou.dynamic.datasource.fixture.service.spel;
public record User(Integer id, String name, Integer age, String tenantName) {
public User(String tenantName) {
this(null, null, null, tenantName);
}
}

View File

@ -0,0 +1,80 @@
/*
* Copyright © 2018 organization baomidou
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.baomidou.dynamic.datasource.fixture.service.spel;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import org.springframework.stereotype.Service;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.LinkedList;
import java.util.List;
@SuppressWarnings({"SqlDialectInspection", "SqlNoDataSourceInspection", "UnusedReturnValue", "unused"})
@Service
@DS("slave")
public class UserService {
private final DataSource dataSource;
public UserService(DataSource dataSource) {
this.dataSource = dataSource;
}
@DS("#session.tenantName")
public List<User> selectSpelBySession() {
List<User> result = new LinkedList<>();
try (Connection connection = dataSource.getConnection(); Statement statement = connection.createStatement()) {
ResultSet resultSet = statement.executeQuery("select * from t_user");
while (resultSet.next()) {
result.add(new User(resultSet.getInt(1), resultSet.getString(2), resultSet.getInt(3), resultSet.getString(4)));
}
return result;
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
@DS("#header.tenantName")
public List<User> selectSpelByHeader() {
List<User> result = new LinkedList<>();
try (Connection connection = dataSource.getConnection(); Statement statement = connection.createStatement()) {
ResultSet resultSet = statement.executeQuery("select * from t_user");
while (resultSet.next()) {
result.add(new User(resultSet.getInt(1), resultSet.getString(2), resultSet.getInt(3), resultSet.getString(4)));
}
return result;
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
@DS("#tenantName")
public String selectSpelByKey(String tenantName) {
return DynamicDataSourceContextHolder.peek();
}
@DS("#user.tenantName")
public String selecSpelByTenant(User user) {
return DynamicDataSourceContextHolder.peek();
}
}

View File

@ -0,0 +1,15 @@
CREATE TABLE IF NOT EXISTS TEACHER
(
id BIGINT(20) NOT NULL AUTO_INCREMENT,
name VARCHAR(30) NULL DEFAULT NULL,
age INT(11) NULL DEFAULT NULL,
PRIMARY KEY (id)
);
CREATE TABLE IF NOT EXISTS STUDENT
(
id BIGINT(20) NOT NULL AUTO_INCREMENT,
name VARCHAR(30) NULL DEFAULT NULL,
age INT(11) NULL DEFAULT NULL,
PRIMARY KEY (id)
);

View File

@ -0,0 +1,7 @@
CREATE TABLE IF NOT EXISTS t_user
(
id BIGINT(20) NOT NULL AUTO_INCREMENT,
name VARCHAR(30) NULL DEFAULT NULL,
age INT(11) NULL DEFAULT NULL,
PRIMARY KEY (id)
);

View File

@ -60,6 +60,7 @@
<p6spy.version>3.9.1</p6spy.version>
<seata.version>1.4.2</seata.version>
<lombok.version>1.18.28</lombok.version>
<h2.version>2.2.220</h2.version>
<maven-clean-plugin.version>3.3.1</maven-clean-plugin.version>
<maven-install-plugin.version>3.1.1</maven-install-plugin.version>
@ -165,6 +166,11 @@
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${h2.version}</version>
</dependency>
</dependencies>
</dependencyManagement>