Introducing sharding-mybatis: A Lightweight Sharding Solution Integrated with Spring Boot and MyBatis
This article introduces sharding-mybatis, a lightweight, non‑intrusive sharding library that seamlessly integrates with Spring Boot and MyBatis, explains why it may be preferable to Sharding‑Sphere, lists its features, provides a GitHub link, and offers detailed usage instructions with code examples.
In this article the author, a senior architect, presents sharding-mybatis, a self‑developed sharding solution that integrates smoothly with the Spring Boot/MyBatis ecosystem, offers high performance, and supports multiple data sources and custom sharding rules.
Why use sharding-mybatis
Seamless integration with Spring Boot/MyBatis, lightweight and non‑intrusive.
Ideal for common sharding scenarios where Sharding‑Sphere’s dependencies are too heavy.
Supports any SQL syntax of the underlying database via AST parsing, covering cases Sharding‑Sphere cannot.
Simple configuration for multiple data sources.
Works with heterogeneous databases (MySQL, Postgres, Oracle) as long as JDBC interfaces are implemented.
High efficiency with negligible performance overhead; validated in production with tens of thousands of TPS.
Project Overview
Project address: https://github.com/winjeg/sharding-mybatis
Note: This article is not written to collect stars; feel free to give a star if the project helps you.
Feature List
Multiple data source support.
Sharding by database and/or table (integer sharding key only).
Support for database‑only, table‑only, or both sharding.
Transactional support.
Customizable sharding rules using Aviator expression engine.
Mixed‑type data source usage.
Usage Instructions
1. Add dependency (disable Spring Boot’s default datasource auto‑configuration)
<dependency>
<groupId>com.winjeg.spring</groupId>
<artifactId>sharding-mybatis</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>2. Configure data sources (example in application.yaml)
datasource:
list:
- name: demo-1
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://10.10.10.10:3306/demo_1?useSSL=false&useUnicode=true&characterEncoding=UTF-8
username: demo_user
password: 123456
- name: demo-2
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://10.10.10.10:3306/demo_2?useSSL=false&useUnicode=true&characterEncoding=UTF-8
username: demo_user
password: 1234563. Enable sharding support
@SpringBootApplication
@EnableSharding(packages = {"com.winjeg.spring.test.mapper", "com.winjeg.spring.test.dao"})
public class SpringApplicationDemo {
public static void main(String[] args) {
SpringApplication.run(SpringApplicationDemo.class, args);
}
}4. Annotate mapper with sharding configuration
@Sharding(
datasource = {"demo-1", "demo-2"},
mapperLocation = "classpath:mappers/demo/*.xml",
dbRule = "'demo-' + (id % 16 / 8 + 1)",
tableRule = "'user_' + (id % 16 % 4)",
shardingKey = "id"
)
public interface ShardingMapper {
int updateUser(@ShardingKey @Param("id") final long id,
@Param("name") final String name);
}5. Sample XML mapper
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.winjeg.spring.sharding.test.mapper.ShardingMapper">
<insert id="addUser">
INSERT INTO ${tableName} (id, name) VALUES(#{id}, #{name})
</insert>
<update id="updateUser">
UPDATE ${tableName} SET name=#{name} WHERE id = #{id}
</update>
</mapper>6. Using the mapper in code (including transaction example)
@Autowired
private NormalMapper testMapper;
@Autowired
private WonderMapper wonderMapper;
@GetMapping("/normal")
public List<String> noneSharding(@RequestParam(value = "uid", defaultValue = "1") final long userId) {
val tables = testMapper.getTables();
tables.add(wonderMapper.getUser());
return tables;
}
@GetMapping("/trans")
public String Sharding(@RequestParam(value = "uid", defaultValue = "1") final long userId,
@RequestParam(value = "name", defaultValue = "") final String name) {
val manager = transactionManager.getTransactionManager(ShardingMapper.class, userId);
TransactionStatus status = manager.getTransaction(definition);
try {
if (shardingMapper.addUser(userId, name) < 1) {
manager.rollback(status);
return "add_trans_fail";
}
if (shardingMapper.updateUser(userId, name + "updated") < 1) {
manager.rollback(status);
return "update_trans_fail";
}
manager.commit(status);
return "trans_success";
} catch (Exception e) {
manager.rollback(status);
return "trans_fail";
}
}The article concludes with a call for readers to discuss, share opinions, and join the author’s community for further learning.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Top Architect
Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
