mysql 分库分表中 使用 mybatis 占位符 #和$的区别

本文介绍在MyBatis中实现分库分表查询的方法,重点讲解如何使用$符号来动态生成表名,避免预编译SQL的问题,并提供了一个具体的Java示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目中使用mysql分库分表查询,表名后面往往要带后缀,比如同一张用户表拆成16张,在数据库中就有16张用户表如:

user_01 user_02  …  user_16

在java实际项目中,我们一般使用sql框架,比如mybatis中#和$在jdbc预编译处理中是不一样的,在jdbc中,数据库操作主要用 PreparedStatement和Statement两个对象。PreparedStatement执行语句会预编译在数据库系统中。执行计划同样会被缓存起来,它允许数据库做参数化查询。使用预处理语句比普通的查询更快,数据库对SQL语句的分析,编译,优化已经在第一次查询前完成了。参数化查询用法如下
1.	public static void main(String args[]) throws SQLException {
2.	        Connection conn = DriverManager.getConnection("mysql:\\localhost:1520", "root", "root");
3.	        PreparedStatement preStatement = conn.prepareStatement("select distinct loan_type from loan where bank=?");
4.	        preStatement.setString(1, "Citibank");	 
6.	        ResultSet result = preStatement.executeQuery();	 
8.	        while(result.next()){
9.	            System.out.println("Loan Type: " + result.getString("loan_type"));
10.	        }       
11.     }

使用占位符?将参数传给已经预编译好的sql语句,这样可以防止sql注入,但传入的参数不能是表名,因为预编译必须得到真实的表名。所以在mybatis mapper文件中,我们要这样写

1.	select * from user_${tableIndex} where id = #{id}

这里使用$生成的sql语句为

select * from user_01 where id = ?


### 若依框架的分库分表实现方案 若依(RuoYi)是一个基于Spring BootMyBatis-Plus开发的企业级后台管理系统开源项目。虽然其官方版本并未内置完整的分库分表功能,但由于其采用了模块化设计以及支持扩展中间件的能力,因此可以通过引入第三方工具来实现分库分表的功能。 以下是关于如何在若依框架中实现分库分表的具体方法: #### 1. **水平拆分与垂直拆分的选择** 数据库拆分的核心在于选择合适的拆分策略。通常情况下,可以选择两种主要方式之一: - 垂直拆分是指按照业务领域将不同的数据存储到不同的数据库中[^1]。 - 水平拆分则是指在同一张表的基础上按某种规则(如时间范围、用户ID等)将数据分布到多个物理表或数据库实例中[^1]。 #### 2. **通过ShardingSphere集成分库分表** ShardingSphere 是一个广泛使用的分布式数据库解决方案,提供了丰富的特性,包括分片、读写分离等功能[^2]。可以将其作为若依项目的插件进行配置,具体步骤如下: #### 配置依赖 在 `pom.xml` 文件中加入 ShardingSphere 的 Maven 依赖项: ```xml <dependency> <groupId>org.apache.shardingsphere</groupId> <artifactId>sharding-jdbc-core-spring-boot-starter</artifactId> <version>5.x.x</version> </dependency> ``` #### 编写分片规则 创建自定义的分片算法并注册至 Spring 上下文中。例如,可以根据用户的 ID 进行取模操作分配数据节点: ```java public class ModuloDatabaseShardingAlgorithm implements PreciseShardingAlgorithm<Long> { @Override public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Long> shardingValue) { long userId = shardingValue.getValue(); int targetIndex = (int)(userId % availableTargetNames.size()); return availableTargetNames.stream().skip(targetIndex).findFirst().orElse(null); } } ``` 将此算法绑定到实际的数据源名称集合上,并声明逻辑表名映射关系。 #### 修改 MyBatis Plus 配置文件 更新 `application.yml` 中的相关参数以适配新的连接池设置及路由规则。 #### 3. **其他可能的技术选型** 除了 ShardingSphere 外,还有多种技术手段可用于解决大规模并发场景下的性能瓶颈问题,比如采用 Redis 或 Elasticsearch 来缓存热点查询结果从而减轻后端压力;或者利用 Canal 同步 MySQL Binlog 日志完成异构系统的增量同步任务等等。 --- ### 示例代码片段 下面展示了一个简单的 Java 方法用于演示如何动态切换目标 DataSource: ```java @DataSource(value="ds_${tenant_id}") public List<UserInfo> getUserInfosByTenant(Long tenantId){ // 查询语句省略... } ``` 其中 `${tenant_id}` 占位符会被替换为当前租户对应的编号值。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值