maven
io.shardingsphere
sharding-jdbc-spring-boot-starter
3.1.0
application.yml
sharding:
jdbc:
datasource:
names: dbm,dbs # 多个数据源的名称
dbm: # 主库
type: com.alibaba.druid.pool.DruidDataSource # 使用Druid连接池
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/db_master?serverTimezone=UTC&characterEncoding=utf8&useUnicode=true&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true
username: root
password: 12345678
maxPoolSize: 10
dbs: # 从库
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/db_slaver?serverTimezone=UTC&characterEncoding=utf8&useUnicode=true&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true
username: root
password: 12345678
maxPoolSize: 10
config:
masterslave: # 配置读写分离
load-balance-algorithm-type: round_robin # 配置从库选择策略,提供轮询与随机【random 随机 ;round_robin 轮询】
name: dbs
master-data-source-name: dbm # 主数据源名称
slave-data-source-names: dbs # 从数据源名称,多个用逗号隔开
props:
sql:
show: true # 打印SQL
spring:
main:
allow-bean-definition-overriding: true # 由于shading-jdbc也会创建bean=Datasource,必须开启覆盖
logging:
level:
com.jf.mapper: DEBUG
mybatis配置
@Configuration
@MapperScan(basePackages = {DataConfig.mapperPackage}, sqlSessionFactoryRef = "sqlSessionFactory")
@EnableTransactionManagement
public class DataConfig {
private Logger logger = LoggerFactory.getLogger(DataConfig.class);
public final static String mapperPackage = "com.jf.mapper";
public final static String modelPackage = "com.jf.model";
public final static String xmlMapperLocation = "classpath*:mapper/*.xml";
@Bean(name = "sqlSessionFactory")
@Primary
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) {
try {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
// we MUST set the 'VFS' if you use jar
bean.setVfs(SpringBootVFS.class);
// 实体类位置
bean.setTypeAliasesPackage(modelPackage);
// 设置mapper.xml文件所在位置
org.springframework.core.io.Resource[] resources = new PathMatchingResourcePatternResolver().getResources(xmlMapperLocation);
bean.setMapperLocations(resources);
return bean.getObject();
} catch (Exception e) {
logger.error("Database sqlSessionFactory create error!", e);
return null;
}
}
@Bean(name = "sqlSessionTemplate")
@Primary
public SqlSessionTemplate sqlSessionTemplate(@Qualifier("sqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
/**
* 事务管理
*
* @return
*/
@Bean(name = "platformTransactionManager")
@Primary
public PlatformTransactionManager platformTransactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
UserMapper.xml
<mapper namespace="com.jf.mapper.UserMapper">
<insert id="insert" parameterType="com.jf.model.User">
INSERT INTO t_user (id, username, address, age) VALUES (#{id}, #{username}, #{address}, #{age})
insert>
<select id="findById" parameterType="int" resultType="com.jf.model.User">
SELECT * FROM t_user WHERE id = #{id}
select>
mapper>
UserMapper
public interface UserMapper {
int insert(User user);
User findById(Integer id);
}
UserService
@Service
public class UserService {
@Resource
private UserMapper userMapper;
public User findUserById(Integer id) {
return userMapper.findById(id);
}
public void insertUser(Integer id, String username, Integer age) {
User user = new User();
user.setId(id);
user.setUsername(username);
user.setAge(age);
userMapper.insert(user);
}
}
测试
@RunWith(SpringRunner.class)
@SpringBootTest
public class AppTest {
@Resource
private UserService userService;
@Test
public void test1() {
userService.insertUser(20, "name", 1);
}
@Test
public void test2() {
User user = userService.findUserById(10);
System.out.println(user);
}
}
注释配置项:sharding.jdbc.config.masterslave
,添加以下配置
sharding:
jdbc:
config: # *注意masterslave和sharding不能同时使用
sharding: # 分表配置
tables:
t_user: # 对应数据库表名
actual-data-nodes: ds_0.t_user_$->{0..2} # 表示读取ds_0数据源的t_user_0,t_user_1,t_user_2
table-strategy: # 策略
standard:
sharding-column: id # 根据id来区分(id值必须存在)
precise-algorithm-class-name: com.jf.config.MyPreciseShardingAlgorithm # 配置数据分表的策略的类
master-slave-rules: # 配置主从库
ds_0:
load-balance-algorithm-type: round_robin
master-data-source-name: dbm
slave-data-source-names: dbs
自定义策略
根据id取模(3)来获取表名,也可以根据id范围来决策表
public class MyPreciseShardingAlgorithm implements PreciseShardingAlgorithm<Integer> {
@Override
public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Integer> shardingValue) {
for (String tableName : availableTargetNames) {
if (tableName.endsWith(shardingValue.getValue() % 3 + "")) {
return tableName;
}
}
throw new IllegalArgumentException();
}
}
测试日志:
Actual SQL: ds_0 ::: INSERT INTO t_user_2 (id, username, address, age) VALUES (?, ?, ?, ?) ::: [[20, 333, null, 20]]