mybatis-plus中获取Connection对象并进行jdbc操作

为什么会在一个ORM框架中用jdbc?

鲁迅James Elliott曾说过:

1
2
3
4
As good object-oriented developers got tired of this repetitive work, 
their typical tendency towards enlightened laziness started to manifest itself in the creation of tools to help automate the process.
When working with relational databases,
the culmination of such efforts were object/relational mapping tools.

大致翻译一下就是优秀的OOPer总是喜欢偷懒,所以他们创造了ORM工具。可见mybatis-plus只是一个偷懒的工具罢了,但是当这个工具面对某些场景不那么趁手时(比如一个复杂的查询业务,不得不用QueryWrapper套一大堆lambdaQuery或是在xml里配一大段带着if的sql),用工具反而增加了不少工作量。

所以本懒人选择把jdbc能力加入到项目中,这样就可以在ORM和原生jdbc间反复横跳来最大化偷懒了。

mybatis-plus 多数据源支持和原理

你搜到这篇文章的话,大概率是你的项目里已经配好多数据源了,所以我们简单回顾一下配置步骤:

1、拉个maven依赖

1
2
3
4
5
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>xxx</version>
</dependency>

2、配置一个dynamic datasource

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
spring:
datasource:
dynamic:
primary: master
strict: false
datasource:
master:
url: jdbc:mysql://localhost:3306/xxx?characterEncoding=utf8&useSSL=false
driver-class-name: com.mysql.cj.jdbc.Driver
username: xxx
password: xxx
postgres:
url: jdbc:postgresql://localhost:5432/xxx
driver-class-name: org.postgresql.Driver
username: xxx
password: xxx

3、在Service上加上@DS("postgres")注解指定数据源即可。

所以,其实mybatis-plus多数据源的原理是塞了一个DataSource的实现类DynamicRoutingDataSource,并根据注解调用getDataSource(String ds)方法拿到对应的实际DataSource:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.baomidou.dynamic.datasource;
public class DynamicRoutingDataSource extends AbstractRoutingDataSource implements InitializingBean, DisposableBean {
private final Map<String, DataSource> dataSourceMap = new ConcurrentHashMap();

public DataSource getDataSource(String ds) {
if (StringUtils.isEmpty(ds)) {
return this.determinePrimaryDataSource();
} else if (!this.groupDataSources.isEmpty() && this.groupDataSources.containsKey(ds)) {
log.debug("dynamic-datasource switch to the datasource named [{}]", ds);
return ((GroupDataSource) this.groupDataSources.get(ds)).determineDataSource();
} else if (this.dataSourceMap.containsKey(ds)) {
log.debug("dynamic-datasource switch to the datasource named [{}]", ds);
return (DataSource) this.dataSourceMap.get(ds);
} else if (this.strict) {
throw new CannotFindDataSourceException("dynamic-datasource could not find a datasource named" + ds);
} else {
return this.determinePrimaryDataSource();
}
}
}

编写一个获取Connection对象并执行jdbc操作的工具

了解了大致原理,我们只需写个工具类拿到spring上下文中的DynamicRoutingDataSource实例,即可获取实际的DataSource,进而拿到Connection对象并执行jdbc操作了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
//import org.wowtools.dao.SqlUtil;

import javax.annotation.PostConstruct;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

@Component
public class DbConnectionUtil {
@Autowired
private DynamicRoutingDataSource dynamicRoutingDataSource;


private DataSource mysqlDataSource;

private DataSource pgDataSource;

@PostConstruct
private void init() {
//在初始化的时候就把实际DataSource拿出来提高一点点性能,用的时候再根据名称拿DataSource也没什么问题
mysqlDataSource = dynamicRoutingDataSource.getDataSource("master");
pgDataSource = dynamicRoutingDataSource.getDataSource("postgres");
// System.out.println("SqlUtil.queryBaseObjectWithJdbc"+ SqlUtil.queryBaseObjectWithJdbc(getPgConnection(), "select count(*) from xxx"));
}

/**
* 获取mysql数据源的Connection
*/
public Connection getMysqlConnection(){
return getConnection(mysqlDataSource);
}
/**
* 获取pg数据源的Connection
*/
public Connection getPgConnection(){
return getConnection(pgDataSource);
}

private Connection getConnection(DataSource ds) {
try {
return ds.getConnection();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}

本文采用 CC BY-SA 4.0 协议 ,转载请注明原始链接: https://blog.wowtools.org/2023/02/11/2023-02-11-mybatisplus-jdbc/

×

请作者喝杯咖啡