当某一个表的数据太庞大的时候,查询就会变得很困难,这个时候需要进行分表操作,就是把一个总表分成几个分表,这样查询某些数据的时候,就会变得快一些:
分表操作:
1 在sql中加一个占位符,代表分表,如下T_HTLPRO_DAYINCREASE_TBL_SHD :
SELECT thd.increasetype,
thd.increaseamount,
thd.increasecurrency,
thd.commodityid,
thd.saledate
FROM T_HTLPRO_DAYINCREASE_TBL_SHD thd, t_htlpro_salechannel channel
where thd.salechannelid = channel.salechannelid
and thd.commodityid = #commodityId#
and thd.salechannelcd = #saleChannelCd#
<![CDATA[
and thd.saledate >= #saleStartDate#
and thd.saledate <= #saleEndDate#
]]>
2 这个分表关联merchantCode,不同的merchantCode,数据保存到不同的分表中,即根据merchantCode找到对应的分表:
select * from htl_org.t_shard_map t where t.merchant_code = 'M10000001' ;
3 ibatis执行sql操作会调用SqlExecutor里的方法,因此需要继承这个类,并重写相关方法:
在执行sql之前,用分表名替换占位符,
package com.fangcang.dao.shard.executor;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.fangcang.dao.shard.config.ShardMappingInfo;
import com.fangcang.dao.shard.util.AnnotationUtils;
import com.ibatis.sqlmap.engine.execution.SqlExecutor;
import com.ibatis.sqlmap.engine.mapping.statement.RowHandlerCallback;
import com.ibatis.sqlmap.engine.scope.StatementScope;
/**
* 继承ibatis的SqlExecutor 处理分表
* @author wangjun
* @date 2016-3-7
*/
public class ShardedSqlExecutor extends SqlExecutor {
private static final Log log = LogFactory.getLog(ShardedSqlExecutor.class);
private static final ThreadLocal<String> shardParam = new ThreadLocal<String>();
public void setMerchantCode(String merchantCode){
shardParam.set(merchantCode);
}
public String wrapperSql(String sql){
if(AnnotationUtils.isCallerShardablePresent()){
String merchantCode = shardParam.get();
if(StringUtils.isEmpty(merchantCode)){
throw new RuntimeException("使用分表功能商家编码不能为空!");
}
if(log.isDebugEnabled()){
log.debug("\r\n");
log.debug("==========对以下sql执行分表替换==========");
log.debug("==========替换前==========");
log.debug("=========="+sql+"==========");
log.debug("==========使用映射配置==========");
log.debug("\r\n");
}
List<ShardMappingInfo> mappings = ShardMappingInfo.getShardMappingInfo(merchantCode);
if(null == mappings || mappings.isEmpty()){
throw new RuntimeException("使用分表功能分表配置不能为空!");
}
if(log.isDebugEnabled()){
log.debug("\r\n");
log.debug("==========商家编码:"+merchantCode+",映射配置"+mappings+"==========");
log.debug("\r\n");
}
for (ShardMappingInfo mapping : mappings) {
if(!StringUtils.isEmpty(mapping.getMainTableName()) && !StringUtils.isEmpty(mapping.getShardTableName())){
sql = sql.replaceAll(mapping.getMainTableName()+"_TBL_SHD", mapping.getShardTableName());
}
}
if(log.isDebugEnabled()){
log.debug("\r\n");
log.debug("==========替换后==========");
log.debug("=========="+sql+"==========");
log.debug("\r\n");
}
return sql;
}
return sql;
};
@Override
public int executeUpdate(StatementScope statementScope, Connection conn,
String sql, Object[] parameters) throws SQLException {
if(log.isDebugEnabled()){
log.debug("\r\n");
log.debug("==========正在执行sql==========");
log.debug("=========="+sql+"==========");
log.debug("==========sql参数"+resolveParamters(parameters)+"==========");
log.debug("\r\n");
}
return super.executeUpdate(statementScope, conn, wrapperSql(sql), parameters);
}
@Override
public void addBatch(StatementScope statementScope, Connection conn,
String sql, Object[] parameters) throws SQLException {
if(log.isDebugEnabled()){
log.debug("\r\n");
log.debug("==========正在执行sql==========");
log.debug("=========="+sql+"==========");
log.debug("==========sql参数"+resolveParamters(parameters)+"==========");
log.debug("\r\n");
}
super.addBatch(statementScope, conn, wrapperSql(sql), parameters);
}
@Override
public void executeQuery(StatementScope statementScope, Connection conn,
String sql, Object[] parameters, int skipResults, int maxResults,
RowHandlerCallback callback) throws SQLException {
if(log.isDebugEnabled()){
log.debug("\r\n");
log.debug("==========正在执行sql==========");
log.debug("=========="+sql+"==========");
log.debug("==========sql参数"+resolveParamters(parameters)+"==========");
log.debug("\r\n");
}
super.executeQuery(statementScope, conn, wrapperSql(sql), parameters, skipResults,
maxResults, callback);
}
@Override
public int executeUpdateProcedure(StatementScope statementScope,
Connection conn, String sql, Object[] parameters)
throws SQLException {
if(log.isDebugEnabled()){
log.debug("\r\n");
log.debug("==========正在执行sql==========");
log.debug("=========="+sql+"==========");
log.debug("==========sql参数"+resolveParamters(parameters)+"==========");
log.debug("\r\n");
}
return super.executeUpdateProcedure(statementScope, conn, wrapperSql(sql), parameters);
}
@Override
public void executeQueryProcedure(StatementScope statementScope,
Connection conn, String sql, Object[] parameters, int skipResults,
int maxResults, RowHandlerCallback callback) throws SQLException {
if(log.isDebugEnabled()){
log.debug("\r\n");
log.debug("==========正在执行sql==========");
log.debug("=========="+sql+"==========");
log.debug("==========sql参数:"+resolveParamters(parameters)+"==========");
log.debug("\r\n");
}
super.executeQueryProcedure(statementScope, conn, wrapperSql(sql), parameters, skipResults,
maxResults, callback);
}
private String resolveParamters(Object[] parameters){
if(null == parameters || parameters.length < 1){
return "";
}
StringBuilder sb = new StringBuilder();
sb.append("[ ");
for (Object object : parameters) {
if(null != object){
sb.append(object.toString()).append(" ");
}
}
sb.append("]");
return sb.toString();
}
}
相关推荐
本文将深入探讨"Ibatis之分表分库解决方案",这是一个针对高并发、大数据处理的有效策略。Ibatis,作为一个轻量级的Java持久层框架,允许开发者将SQL语句直接写在配置文件或映射接口中,提供了灵活的数据访问接口。...
heng-dao 满足公司业务分表业务,轻量级封装ibatis, 封装轻量级ibatis author barney.wang email: 1.支持ibatis分库事务 2.支持ibatis分表处理 3.复写sqlSessionTemplate
1. **创建拦截器类**:实现`org.apache.ibatis.plugin.Interceptor`接口,并重写`intercept`方法,这是插件的核心,用于处理SQL语句。 2. **定义分片策略**:根据业务需求,定义如何将数据分配到不同的库表。例如,...
在IT行业中,数据库操作是应用程序开发中的核心环节。Ibatis作为一个轻量级的持久层框架,为Java...对于大型项目,Ibatis可以通过Mapper接口和Mapper XML文件的组合,实现更高级的分库分表策略,提高系统的扩展性。
Mycat支持读写分离、分库分表、分布式事务等特性,能有效提升系统的处理能力。 要将这些技术整合起来,你需要按照以下步骤进行: 1. **配置Mycat**:安装并配置Mycat服务器,设置数据节点、切分规则和路由策略,...
【MySQL主从分布式sharding 切分表远离】 在应对互联网大规模应用的高并发和海量数据存储时,数据库的设计和优化至关重要。其中,数据库水平切分(Sharding)是一种常用的解决策略,它通过将数据分散到多个数据库或...
谢谢大家的关注#halo-dal使用说明#####使用场景:数据库分布式访问#####使用语言:java#####使用条件:支持PreparedStatement处理的任何jdbc框架,最好配合spring管理数据库连接池.#####sql语句必须使用小写字符#####jdk...
相比于单条插入,批量插入能够显著提升数据处理效率,减少数据库I/O操作,从而提高整体性能。本文将深入探讨如何利用MyBatis框架结合MySQL数据库实现批量插入功能,包括其原理、配置、代码实现以及优化策略。 ### ...
因为本人在国内最大的电子商务公司工作期间,深感一个好的分表分库框架可以大大提高系统的承载能力及系统的灵活性,而一个不好的分表分库方案,则让系统在大数据量处理的时候非常郁闷。所以, 在根据笔者在从事电子...
"jdbc:hsqldb:mem:testdb"username = "sa"password = ""mybatis使用到的设计模式代理模式JDK Proy://org.apache.ibatis.binding.MapperProxyFactory.newInstance(org.apache.ibatis.binding.MapperProxy) protected ...
- 核心部分与Java框架的结合:虽然选择了Scala作为主要语言,但项目组依然保留了Java的开发,核心部分使用了iBatis、Spring和SpringMVC等Java框架。 5. Scala在实际应用中的好处: - 代码的简洁性与高效率:Scala...
对于分布式数据访问,框架层的实现如淘宝的基于iBatis和Spring的DDAL(分布式数据访问层),能够有效地支持分库分表的路由规则,提高应用的读写性能和并发能力。 **7. 扩展性挑战** 分库分表带来的挑战之一是如何在...
例如,阿里集团的"变形虫"(Amoeba)项目是对JDBC层的封装,而淘宝基于iBatis和Spring的分布式数据访问层则是在ORM层实现的。这些框架简化了数据切分和路由的实现,同时也确保了生产环境的稳定性和效率。 4. 扩展性...
1. **互联网金融业务挑战**:互联网金融业务通常需要处理海量并发交易,如2014年双11期间,每分钟285万笔订单和每秒8万笔交易。这要求系统具备分布服务、数据分布、强一致性、秒级容灾和亚秒级服务质量的能力。 2. ...
- **历史沿革**:MyBatis 最初源自 Apache 的一个开源项目 iBatis,在 2010 年该项目从 Apache 迁移到 Google Code,并更名为 MyBatis。2013 年 11 月,MyBatis 项目又迁移至 Github。 - **官网地址**:...
Interceptor 拦截器的使用场景主要是更新数据库的通用字段,分库分表,加解密等的处理。Interceptor 拦截器需要实现 org.apache.ibatis.plugin.Interceptor 接口,并且使用 @Intercepts 注解来指定要拦截的方法。 ...
就ORM 框架层的实现而言,比如Taobao 的基于 ibatis 和 Spring 的的分布式数据访问层,已有多年的应用,运行效率和生产实效性得到了开发人员和用户的肯定。本文就是以ORM 框架层为基础而实现的分布式数据访问层。本...
在实际应用中,数据库分库分表的扩展性面临诸多挑战,比如如何最小化数据迁移以适应容量扩展,如何动态调整路由规则以应对业务变化,以及如何确保数据的一致性和完整性。这些问题需要在设计时综合考虑,以实现高效且...