应用场景
根据用户配置的数据源动态的抽取或者查询该数据库的数据,应用场景还是比较多的,比如BI系统,动态配置多个数据源,无需重启,即可抽取数据
开题前
之前一直以为动态抽取数据是特别高深的技能点,总是望而却步,最近整理元数据系统时用到了该功能,查了部分资料,找了一种算是比较简单的方法(其它的还未尝试,欢迎小伙伴推荐)
正文
1.比如通过页面配置数据源链接,统一管理数据源。
2.点击抽取,配置脚本抽取该库的所有表(功能强大的不可想象)
代码样例
去除各种封装,保留最原始的功能,这样大家拿来即用,便于理解(有帮助欢迎start下)
此案例代码统一放在springboot-13-dynamic-db目录(文末共享链接),利用JdbcTemplate实现
1.引入相关jar
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
2.创建数据库实体类(包含用户名、密码、链接系列的字段)
public class DynamicDataSourceEntity implements java.io.Serializable {
/**id*/
private String id;
/**dbKey*/
private String dbKey;
/**description*/
private String description;
/**driverClass*/
private String driverClass;
/**url*/
private String url;
/**dbUser*/
private String dbUser;
/**dbPassword*/
private String dbPassword;
/**dbType*/
private String dbType;
/**dbName*/
private String dbName;
....
}
3.配置个初始化工具类(可无)
public class JdbcTemplateDynamic {
DriverManagerDataSource dataSource;
JdbcTemplate jdbcTemplate;
public JdbcTemplateDynamic(DynamicDataSourceEntity dynamicDataSourceEntity) {
// 设置数据库信息
this.dataSource = new DriverManagerDataSource();
this.dataSource.setDriverClassName(dynamicDataSourceEntity.getDriverClass());
this.dataSource.setUrl(dynamicDataSourceEntity.getUrl());
this.dataSource.setUsername(dynamicDataSourceEntity.getDbUser());
this.dataSource.setPassword(dynamicDataSourceEntity.getDbPassword());
// 设置数据源
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
public DriverManagerDataSource getDataSource() {
return dataSource;
}
public void setDataSource(DriverManagerDataSource dataSource) {
this.dataSource = dataSource;
}
public JdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
}
4.直接上测试吧,开干
里面包含了增删该查系列方法
@RunWith(SpringRunner.class)
@SpringBootTest
public class Springboot13Test {
static String dbKey = "limp_db";
//定义临时缓存|存放数据
private static Map<String,DynamicDataSourceEntity> mapEntity=new HashMap<>();
@Test
public void contextLoads() {
}
/**
* 定义多数据源配置
*/
@Before
public void initDB(){
DynamicDataSourceEntity dynamicSourceEntity = new DynamicDataSourceEntity();
//以下配置信息应该在数据中获取
String driverClassName = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://192.168.26.112:3306/test?userUnicode=true&characterEncoding=UTF-8&userSSL=false";
String dbUser = "root";
String dbPassword = "123@gla.net.cn";
dynamicSourceEntity.setDbKey(dbKey);
dynamicSourceEntity.setDriverClass(driverClassName);
dynamicSourceEntity.setUrl(url);
dynamicSourceEntity.setDbUser(dbUser);
dynamicSourceEntity.setDbPassword(dbPassword);
//将初始化好的 数据连接信息放在map当中|方便获取
mapEntity.put(dbKey, dynamicSourceEntity);
}
/**
* 测试新增
* @throws Exception
*/
@Test
public void testInsert() throws Exception {
/*******************************************/
String id = UUID.randomUUID().toString().replaceAll("-", "").toUpperCase();
String sql = "insert test (id,name)values(?,'test-DynamicDBTest-insert') ";
DynamicDataSourceEntity dynamicSourceEntity=mapEntity.get(dbKey);
JdbcTemplateDynamic jdbcTemplateDynamic=new JdbcTemplateDynamic(dynamicSourceEntity);
JdbcTemplate jdbcTemplate =jdbcTemplateDynamic.getJdbcTemplate();
Integer effectCount = jdbcTemplate.update(sql, id);
System.out.println("-----------testInsert 成功---------");
}
/**
* 查询方法
*/
@Test
public void testGetList(){
String sql = "select * from test";
DynamicDataSourceEntity dynamicSourceEntity=mapEntity.get(dbKey);
JdbcTemplateDynamic jdbcTemplateDynamic=new JdbcTemplateDynamic(dynamicSourceEntity);
JdbcTemplate jdbcTemplate =jdbcTemplateDynamic.getJdbcTemplate();
//调用方法获得list集合
List<TestPo> testList = jdbcTemplate.query(sql, new MyRowMapper());
System.out.println(testList);
//
String sqlOne = "select * from test where id = ?";
//根据id获取单个对象
TestPo testPo = jdbcTemplate.queryForObject(sqlOne, new MyRowMapper(), "C5828944E72D48B5B4BABCA2F7844EFA");
System.out.println("获取单个对象");
System.out.println(testPo);
//调用方法获得记录数
String sqlGetNum = "select count(*) from test";
int count = jdbcTemplate.queryForObject(sqlGetNum, Integer.class);
System.out.println("数据总数:" + count);
//[TestPo{id='2E747EB9BAC043CEA99F620578B3D6FF', name='DynamicDBTest-insert'}, TestPo{id='C8ACD8BCF6DD4177B6CAC9699509C816', name='DynamicDBTest-insert'}, TestPo{id='034AC4FDE2924D0EA304EE782312C3B6', name='DynamicDBTest-insert'}, TestPo{id='C5828944E72D48B5B4BABCA2F7844EFA', name='test-DynamicDBTest-insert'}]
}
}
特别说明 查询方法中,下面这个还比较常见,应用也比较广泛(无需配置mapper,直接map接收即可)
List<Map<String, Object>> queryForList(String sql, @Nullable Object... args)