org.projectlombok
diff --git a/sharding-multiple-data-sources/src/main/java/com/baiye/ShardingMultipleDataSourceApplication.java b/sharding-multiple-data-sources/src/main/java/com/baiye/ShardingMultipleDataSourceApplication.java
index 6a71ca4..0511801 100644
--- a/sharding-multiple-data-sources/src/main/java/com/baiye/ShardingMultipleDataSourceApplication.java
+++ b/sharding-multiple-data-sources/src/main/java/com/baiye/ShardingMultipleDataSourceApplication.java
@@ -5,7 +5,6 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter;
-import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
* @author q
diff --git a/sharding-multiple-data-sources/src/main/java/com/baiye/config/DataSourceConfiguration.java b/sharding-multiple-data-sources/src/main/java/com/baiye/config/DataSourceConfiguration.java
new file mode 100644
index 0000000..fa5c46e
--- /dev/null
+++ b/sharding-multiple-data-sources/src/main/java/com/baiye/config/DataSourceConfiguration.java
@@ -0,0 +1,120 @@
+package com.baiye.config;
+
+import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
+import com.baomidou.dynamic.datasource.provider.AbstractDataSourceProvider;
+import com.baomidou.dynamic.datasource.provider.DynamicDataSourceProvider;
+import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty;
+import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceAutoConfiguration;
+import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties;
+import org.apache.shardingsphere.shardingjdbc.jdbc.adapter.AbstractDataSourceAdapter;
+import org.springframework.beans.factory.annotation.Configurable;
+import org.springframework.boot.SpringBootConfiguration;
+import org.springframework.boot.autoconfigure.AutoConfigureBefore;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.jdbc.DataSourceBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.context.annotation.Primary;
+
+import javax.annotation.Resource;
+import javax.sql.DataSource;
+import java.util.Map;
+
+/**
+ * 动态数据源配置:
+ *
+ * 使用{@link com.baomidou.dynamic.datasource.annotation.DS}注解,切换数据源
+ *
+ * @DS(DataSourceConfiguration.SHARDING_DATA_SOURCE_NAME)
+ *
+ * @author q
+ */
+@Configurable
+@AutoConfigureBefore({DynamicDataSourceAutoConfiguration.class,
+ SpringBootConfiguration.class})
+public class DataSourceConfiguration {
+
+
+ /**
+ * 分表数据源名称
+ */
+ private static final String SHARDING_DATA_SOURCE_NAME = "sharding_ds";
+
+
+ @Resource
+ private DynamicDataSourceProperties properties;
+
+
+ /**
+ * shardingjdbc 有四种数据源,需要根据业务注入不同的数据源
+ *
+ * 1. 未使用分片, 脱敏的名称(默认): shardingDataSource;
+ *
2. 主从数据源: masterSlaveDataSource;
+ *
3. 脱敏数据源:encryptDataSource;
+ *
4. 影子数据源:shadowDataSource
+ *
+ * fixme 特别注意,有的spring版本不用加Lazy一样能注入,有的会空指针。 根据自己测试选择,但是如果加了lazy就没强转了,也就无法添加其内部的数据源了。 有办法请联系作者。
+ *
+ */
+ @Lazy
+ @Resource(name = "masterSlaveDataSource")
+ AbstractDataSourceAdapter shardingDataSource;
+
+
+ @Bean
+ public DynamicDataSourceProvider dynamicDataSourceProvider() {
+ Map datasourceMap = properties.getDatasource();
+ return new AbstractDataSourceProvider() {
+ @Override
+ public Map loadDataSources() {
+ Map dataSourceMap = createDataSourceMap(datasourceMap);
+ // 将 shardingjdbc 管理的数据源也交给动态数据源管理
+ dataSourceMap.put(SHARDING_DATA_SOURCE_NAME, shardingDataSource);
+ //打开下面的代码可以把 shardingJdbc 内部管理的子数据源也同时添加到动态数据源里 (根据自己需要选择开启)
+// dataSourceMap.putAll(((MasterSlaveDataSource) masterSlaveDataSource).getDataSourceMap());
+ return dataSourceMap;
+ }
+ };
+ }
+
+
+ /**
+ * 将动态数据源设置为首选的
+ * 当spring存在多个数据源时, 自动注入的是首选的对象
+ * 设置为主要的数据源之后,就可以支持 shardingjdbc 原生的配置方式了
+ * 3.4.0版本及以上使用以下方式注入,老版本请阅读文档 进阶-手动注入多数据源
+ */
+ @Primary
+ @Bean
+ public DataSource dataSource() {
+ DynamicRoutingDataSource dataSource = new DynamicRoutingDataSource();
+ dataSource.setPrimary(properties.getPrimary());
+ dataSource.setStrict(properties.getStrict());
+ dataSource.setStrategy(properties.getStrategy());
+ dataSource.setP6spy(properties.getP6spy());
+ dataSource.setSeata(properties.getSeata());
+ return dataSource;
+ }
+
+ /**
+ * 第一个数据连接,默认优先级最高
+ * @return
+ */
+ @Bean(name = "dataSourceFirst")
+ @ConfigurationProperties(prefix = "spring.datasource.first")
+ public DataSource dataSourceFirst() {
+ //这种方式的配置默认只满足spring的配置方式,如果使用其他数据连接(druid),需要自己独立获取配置
+ return DataSourceBuilder.create().build();
+ }
+
+ /**
+ * 第二个数据源
+ * @return
+ */
+ @Bean(name = "dataSourceSecond")
+ @ConfigurationProperties(prefix = "spring.datasource.second")
+ public DataSource dataSourceSecond() {
+ return DataSourceBuilder.create().build();
+ }
+
+}
diff --git a/sharding-multiple-data-sources/src/main/java/com/baiye/config/JpaFirstConfiguration.java b/sharding-multiple-data-sources/src/main/java/com/baiye/config/JpaFirstConfiguration.java
new file mode 100644
index 0000000..dfcfdc4
--- /dev/null
+++ b/sharding-multiple-data-sources/src/main/java/com/baiye/config/JpaFirstConfiguration.java
@@ -0,0 +1,108 @@
+package com.baiye.config;
+
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.autoconfigure.domain.EntityScan;
+import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties;
+import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings;
+import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
+import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+import org.springframework.orm.jpa.JpaTransactionManager;
+import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+import javax.persistence.EntityManager;
+import javax.sql.DataSource;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * 第一个数据源,jpa的相关配置
+ *
+ * 1、实体扫描
+ * 2、实体管理ref
+ * 3、事务管理
+ */
+@Configuration
+@EntityScan(basePackages = "com.baiye.domain.first")
+
+@EnableJpaRepositories(
+ basePackages = "com.baiye.domain.first",
+ entityManagerFactoryRef = "firstEntityManagerFactoryBean",
+ transactionManagerRef = "firstTransactionManager")
+@EnableTransactionManagement
+public class JpaFirstConfiguration {
+
+ @Autowired
+ private HibernateProperties hibernateProperties;
+ /**
+ * 第一个数据源,可以不加Qualifier
+ */
+ @Autowired
+ @Qualifier("dataSourceFirst")
+ private DataSource dataSource;
+
+ /**
+ * jpa其他参数配置
+ */
+ @Autowired
+ private JpaProperties jpaProperties;
+
+ /**
+ * 实体管理工厂builder
+ */
+ @Autowired
+ private EntityManagerFactoryBuilder factoryBuilder;
+
+ /**
+ * 配置第一个实体管理工厂的bean
+ *
+ * @return
+ */
+ @Bean(name = "firstEntityManagerFactoryBean")
+ @Primary
+ public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() {
+ Map properties = hibernateProperties
+ .determineHibernateProperties(
+ jpaProperties.getProperties(),
+ new HibernateSettings()
+ );
+
+ return factoryBuilder.dataSource(dataSource)
+ //这一行的目的是加入jpa的其他配置参数比如(ddl-auto: update等)
+ //当然这个参数配置可以在事务配置的时候也可以
+ .properties(properties)
+ .packages("com.baiye.domain.first")
+ .persistenceUnit("firstPersistenceUnit")
+ .build();
+ }
+
+ /**
+ * EntityManager不过解释,用过jpa的应该都了解
+ * @return
+ */
+ @Bean(name = "firstEntityManager")
+ @Primary
+ public EntityManager entityManager() {
+ return Objects.requireNonNull(entityManagerFactoryBean().getObject()).createEntityManager();
+ }
+
+ /**
+ * jpa事务管理
+ * @return
+ */
+ @Bean(name = "firstTransactionManager")
+ @Primary
+ public JpaTransactionManager transactionManager() {
+ JpaTransactionManager jpaTransactionManager = new JpaTransactionManager();
+ jpaTransactionManager.setEntityManagerFactory(entityManagerFactoryBean().getObject());
+ return jpaTransactionManager;
+ }
+
+
+}
diff --git a/sharding-multiple-data-sources/src/main/java/com/baiye/config/JpaSecondConfiguration.java b/sharding-multiple-data-sources/src/main/java/com/baiye/config/JpaSecondConfiguration.java
new file mode 100644
index 0000000..a8814bc
--- /dev/null
+++ b/sharding-multiple-data-sources/src/main/java/com/baiye/config/JpaSecondConfiguration.java
@@ -0,0 +1,100 @@
+package com.baiye.config;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.autoconfigure.domain.EntityScan;
+import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties;
+import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings;
+import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
+import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
+import org.springframework.orm.jpa.JpaTransactionManager;
+import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+import javax.persistence.EntityManager;
+import javax.sql.DataSource;
+import java.util.Map;
+import java.util.Objects;
+
+
+/**
+ * 第二个数据源,jpa的相关配置
+ *
+ * 1、实体扫描
+ * 2、实体管理ref
+ * 3、事务管理
+ */
+@Configuration
+@EntityScan(basePackages = "com.baiye.domain.second")
+@EnableJpaRepositories(
+ basePackages = "com.baiye.domain.second",
+ entityManagerFactoryRef = "secondEntityManagerFactoryBean",
+ transactionManagerRef = "secondTransactionManager")
+@EnableTransactionManagement
+public class JpaSecondConfiguration {
+ @Autowired
+ private HibernateProperties hibernateProperties;
+
+ /**
+ * 第二个数据源,必须加Qualifier
+ */
+ @Autowired
+ @Qualifier("dataSourceSecond")
+ private DataSource dataSource;
+
+ /**
+ * jpa其他参数配置
+ */
+ @Autowired
+ private JpaProperties jpaProperties;
+
+ /**
+ * 实体管理工厂builder
+ */
+ @Autowired
+ private EntityManagerFactoryBuilder factoryBuilder;
+
+ /**
+ * 配置第二个实体管理工厂的bean
+ *
+ * @return
+ */
+ @Bean(name = "secondEntityManagerFactoryBean")
+ public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() {
+ Map properties = hibernateProperties.determineHibernateProperties(
+ jpaProperties.getProperties(),
+ new HibernateSettings()
+ );
+
+ return factoryBuilder.dataSource(dataSource)
+ .properties(properties)
+ .packages("com.baiye.domain.second")
+ .persistenceUnit("secondPersistenceUnit")
+ .build();
+ }
+
+ /**
+ * EntityManager不过解释,用过jpa的应该都了解
+ *
+ * @return
+ */
+ @Bean(name = "secondEntityManager")
+ public EntityManager entityManager() {
+ return Objects.requireNonNull(entityManagerFactoryBean().getObject()).createEntityManager();
+ }
+
+ /**
+ * jpa事务管理
+ *
+ * @return
+ */
+ @Bean(name = "secondTransactionManager")
+ public JpaTransactionManager transactionManager() {
+ JpaTransactionManager jpaTransactionManager = new JpaTransactionManager();
+ jpaTransactionManager.setEntityManagerFactory(entityManagerFactoryBean().getObject());
+ return jpaTransactionManager;
+ }
+}
diff --git a/sharding-multiple-data-sources/src/main/java/com/baiye/dao/first/PriceRepository.java b/sharding-multiple-data-sources/src/main/java/com/baiye/dao/first/PriceRepository.java
new file mode 100644
index 0000000..31c6582
--- /dev/null
+++ b/sharding-multiple-data-sources/src/main/java/com/baiye/dao/first/PriceRepository.java
@@ -0,0 +1,7 @@
+package com.baiye.dao.first;
+
+import com.baiye.domain.first.Price;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface PriceRepository extends JpaRepository {
+}
diff --git a/sharding-multiple-data-sources/src/main/java/com/baiye/dao/second/UserRepository.java b/sharding-multiple-data-sources/src/main/java/com/baiye/dao/second/UserRepository.java
new file mode 100644
index 0000000..e9e4876
--- /dev/null
+++ b/sharding-multiple-data-sources/src/main/java/com/baiye/dao/second/UserRepository.java
@@ -0,0 +1,14 @@
+package com.baiye.dao.second;
+
+import com.baiye.domain.second.User;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+/**
+ * 对应user表 -> 存储在库 test_sharding_1
+ *
+ * 代表业务主库
+ *
+ * @author q
+ */
+public interface UserRepository extends JpaRepository {
+}
diff --git a/sharding-multiple-data-sources/src/main/java/com/baiye/domain/Price.java b/sharding-multiple-data-sources/src/main/java/com/baiye/domain/first/Price.java
similarity index 90%
rename from sharding-multiple-data-sources/src/main/java/com/baiye/domain/Price.java
rename to sharding-multiple-data-sources/src/main/java/com/baiye/domain/first/Price.java
index 24a1812..ba8e17b 100644
--- a/sharding-multiple-data-sources/src/main/java/com/baiye/domain/Price.java
+++ b/sharding-multiple-data-sources/src/main/java/com/baiye/domain/first/Price.java
@@ -1,4 +1,4 @@
-package com.baiye.domain;
+package com.baiye.domain.first;
import lombok.Data;
diff --git a/sharding-multiple-data-sources/src/main/java/com/baiye/domain/User.java b/sharding-multiple-data-sources/src/main/java/com/baiye/domain/second/User.java
similarity index 88%
rename from sharding-multiple-data-sources/src/main/java/com/baiye/domain/User.java
rename to sharding-multiple-data-sources/src/main/java/com/baiye/domain/second/User.java
index 45981ec..7d57da0 100644
--- a/sharding-multiple-data-sources/src/main/java/com/baiye/domain/User.java
+++ b/sharding-multiple-data-sources/src/main/java/com/baiye/domain/second/User.java
@@ -1,4 +1,4 @@
-package com.baiye.domain;
+package com.baiye.domain.second;
import lombok.Data;
diff --git a/sharding-multiple-data-sources/src/main/java/com/baiye/service/ShardService.java b/sharding-multiple-data-sources/src/main/java/com/baiye/service/ShardService.java
index 9cc69c7..934947a 100644
--- a/sharding-multiple-data-sources/src/main/java/com/baiye/service/ShardService.java
+++ b/sharding-multiple-data-sources/src/main/java/com/baiye/service/ShardService.java
@@ -3,6 +3,7 @@ package com.baiye.service;
import com.baiye.dao.OrderRepository;
import com.baiye.domain.Order;
+import com.baomidou.dynamic.datasource.annotation.DS;
import org.apache.shardingsphere.transaction.annotation.ShardingTransactionType;
import org.apache.shardingsphere.transaction.core.TransactionType;
import org.springframework.beans.factory.annotation.Autowired;
@@ -16,6 +17,7 @@ import java.util.Optional;
* @author q
*/
@Service
+@DS("sharding_ds")
public class ShardService {
@Autowired
@@ -24,6 +26,7 @@ public class ShardService {
/**
* 增
*/
+ @DS("sharding_ds")
public Order insertOne(Order order) {
return orderRepository.save(order);
}
@@ -31,10 +34,12 @@ public class ShardService {
/**
* 批量增加
*/
+ @DS("sharding_ds")
public List batchInsert(List orders) {
return orderRepository.saveAll(orders);
}
+ @DS("sharding_ds")
public Order queryOne(Long id) {
Optional optional = orderRepository.findById(id);
return optional.orElse(null);
@@ -44,6 +49,7 @@ public class ShardService {
/**
* 批量查
*/
+ @DS("sharding_ds")
public List queryByCondition(List ids) {
return orderRepository.findAllById(ids);
}
@@ -55,6 +61,7 @@ public class ShardService {
*/
@Transactional(value = "transactionManager")
@ShardingTransactionType(TransactionType.XA)
+ @DS("sharding_ds")
public Order updateByCondition(Order order) {
return orderRepository.save(order);
}
@@ -62,6 +69,7 @@ public class ShardService {
/**
* 删除
*/
+ @DS("sharding_ds")
public void deleterByCondition(Order order) {
orderRepository.delete(order);
}
diff --git a/sharding-multiple-data-sources/src/main/resources/application-sharddb.properties b/sharding-multiple-data-sources/src/main/resources/application-sharddb.properties
index 0a8cd63..8d4b2d1 100644
--- a/sharding-multiple-data-sources/src/main/resources/application-sharddb.properties
+++ b/sharding-multiple-data-sources/src/main/resources/application-sharddb.properties
@@ -1,3 +1,4 @@
+# ??????
spring.shardingsphere.datasource.names=ds0,ds1
spring.shardingsphere.datasource.ds0.type=com.alibaba.druid.pool.DruidDataSource
@@ -20,4 +21,20 @@ spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.sharding-col
spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.algorithm-expression=t_order_$->{user_id % 2}
spring.shardingsphere.sharding.tables.t_order.key-generator.column=id
spring.shardingsphere.sharding.tables.t_order.key-generator.type=SNOWFLAKE
+spring.shardingsphere.sharding.tables.t_order.key-generator.props.worker.id=13
+
+# ??????
+spring.datasource.primary.key=ds-1
+spring.datasource.primary.type=com.alibaba.druid.pool.DruidDataSource
+spring.datasource.primary.driverClassName=com.mysql.cj.jdbc.Driver
+spring.datasource.primary.url=jdbc:mysql://127.0.0.1:3306/master-1?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8&useTimezone=true
+spring.datasource.primary.username=root
+spring.datasource.primary.password=root
+
+spring.datasource.secondary.key=ds-2
+spring.datasource.secondary.type=com.alibaba.druid.pool.DruidDataSource
+spring.datasource.secondary.driverClassName=com.mysql.cj.jdbc.Driver
+spring.datasource.secondary.url=jdbc:mysql://127.0.0.1:3306/slave-2?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8&useTimezone=true
+spring.datasource.secondary.username=root
+spring.datasource.secondary.password=root
diff --git a/sharding-multiple-data-sources/src/main/resources/application.yml b/sharding-multiple-data-sources/src/main/resources/application.yml
index 99243eb..3ede147 100644
--- a/sharding-multiple-data-sources/src/main/resources/application.yml
+++ b/sharding-multiple-data-sources/src/main/resources/application.yml
@@ -5,10 +5,29 @@ spring:
name: sharding-multiple-data-sources
profiles:
active: sharddb
+# jpa配置
jpa:
properties:
hibernate:
show_sql: true
+ ddl-auto: update
+ naming:
+ physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
+ implicit-strategy: org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
+ database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
database: mysql
+ open-in-view: false # true会让数据库连接绑定请求线程,jpa查询是只读事务,会造成主从不能切换!
main:
allow-bean-definition-overriding: true
+ # 多数据源配置
+ datasource:
+ first:
+ driver-class-name: com.mysql.cj.jdbc.Driver
+ jdbc-url: jdbc:mysql://127.0.0.1:3306/master-1?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8&useTimezone=true
+ username: root
+ password: root
+ second:
+ driver-class-name: com.mysql.cj.jdbc.Driver
+ jdbc-url: jdbc:mysql://127.0.0.1:3306/slave-1?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8&useTimezone=true
+ username: root
+ password: root
\ No newline at end of file