为什么会在一个ORM框架中用jdbc? 鲁迅James Elliott曾说过:
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依赖
<dependency > <groupId > com.baomidou</groupId > <artifactId > dynamic-datasource-spring-boot-starter</artifactId > <version > xxx</version > </dependency >
2、配置一个dynamic datasource
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 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 () { mysqlDataSource = dynamicRoutingDataSource.getDataSource("master" ); pgDataSource = dynamicRoutingDataSource.getDataSource("postgres" ); } public Connection getMysqlConnection () { return getConnection(mysqlDataSource); } public Connection getPgConnection () { return getConnection(pgDataSource); } private Connection getConnection (DataSource ds) { try { return ds.getConnection(); } catch (SQLException e) { throw new RuntimeException (e); } } }