mysql dialect配置_iBatis3基于方言(Dialect)的分页
(注:以下代码是基于ibatis3 beta4的扩展,ibatis3正式版如果实现改变,将会继续跟进修改)
iBatis3默认使用的分页是基于游标的分页,而这种分页在不同的数据库上性能差异不一致,最好的办法当然是使用类似hibernate的基于方言(Dialect)的物理分页功能。
iBatis3现在提供插件功能,通过插件我们可以编写自己的拦截器来拦截iBatis3的主要执行方法来完成相关功能的扩展。
能够拦截的的类如下:
Java代码 收藏代码
Executor
(update,query,flushStatements,commit,rollback,getTransaction,close,isClosed)
ParameterHandler
(getParameterObject,setParameters)
ResultSetHandler
(handleResultSets,handleOutputParameters)
StatementHandler
(prepare,parameterize,batch,update,query)
但此次我们感兴趣的是Executor.query()方法,查询方法最终都是执行该方法。
该方法完整是:
Java代码 收藏代码
Executor.query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException;
分页方言的基本实现:
以Mysql数据库示例,即有一个方法 query(sql,offset,limit);
Java代码 收藏代码
query("select * from user",5,10);
经过我们的拦截器拦截处理,变成
Java代码 收藏代码
query("select * from user limit 5,10",0,0);
1.拦截类实现:
Java代码 收藏代码
@Intercepts({@Signature(
type= Executor.class,
method = "query",
args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})})
public class OffsetLimitInterceptor implements Interceptor{
static int MAPPED_STATEMENT_INDEX = 0;
static int PARAMETER_INDEX = 1;
static int ROWBOUNDS_INDEX = 2;
static int RESULT_HANDLER_INDEX = 3;
Dialect dialect;
public Object intercept(Invocation invocation) throws Throwable {
processIntercept(invocation.getArgs());
return invocation.proceed();
}
void processIntercept(final Object[] queryArgs) {
//queryArgs = query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler)
MappedStatement ms = (MappedStatement)queryArgs[MAPPED_STATEMENT_INDEX];
Object parameter = queryArgs[PARAMETER_INDEX];
final RowBounds rowBounds = (RowBounds)queryArgs[ROWBOUNDS_INDEX];
int offset = rowBounds.getOffset();
int limit = rowBounds.getLimit();
if(dialect.supportsLimit() && (offset != RowBounds.NO_ROW_OFFSET || limit != RowBounds.NO_ROW_LIMIT)) {
BoundSql boundSql = ms.getBoundSql(parameter);
String sql = boundSql.getSql().trim();
if (dialect.supportsLimitOffset()) {
sql = dialect.getLimitString(sql, offset, limit);
offset = RowBounds.NO_ROW_OFFSET;
} else {
sql = dialect.getLimitString(sql, 0, limit);
}
limit = RowBounds.NO_ROW_LIMIT;
queryArgs[ROWBOUNDS_INDEX] = new RowBounds(offset,limit);
BoundSql newBoundSql = new BoundSql(sql, boundSql.getParameterMappings(), boundSql.getParameterObject());
MappedStatement newMs = copyFromMappedStatement(ms, new BoundSqlSqlSource(newBoundSql));
queryArgs[MAPPED_STATEMENT_INDEX] = newMs;
}
}
private MappedStatement copyFromMappedStatement(MappedStatement ms,SqlSource newSqlSource) {
Builder builder = new MappedStatement.Builder(ms.getConfiguration(),ms.getId(),newSqlSource,ms.getSqlCommandType());
builder.resource(ms.getResource());
builder.fetchSize(ms.getFetchSize());
builder.statementType(ms.getStatementType());
builder.keyGenerator(ms.getKeyGenerator());
builder.keyProperty(ms.getKeyProperty());
builder.timeout(ms.getTimeout());
builder.parameterMap(ms.getParameterMap());
builder.resultMaps(ms.getResultMaps());
builder.cache(ms.getCache());
MappedStatement newMs = builder.build();
return newMs;
}
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
public void setProperties(Properties properties) {
String dialectClass = new PropertiesHelper(properties).getRequiredString("dialectClass");
try {
dialect = (Dialect)Class.forName(dialectClass).newInstance();
} catch (Exception e) {
throw new RuntimeException("cannot create dialect instance by dialectClass:"+dialectClass,e);
}
System.out.println(OffsetLimitInterceptor.class.getSimpleName()+".dialect="+dialectClass);
}
public static class BoundSqlSqlSource implements SqlSource {
BoundSql boundSql;
public BoundSqlSqlSource(BoundSql boundSql) {
this.boundSql = boundSql;
}
public BoundSql getBoundSql(Object parameterObject) {
return boundSql;
}
}
}
2.ibatis3配置文件内容:
Xml代码 收藏代码
3.MysqlDialect实现
Java代码 收藏代码
public class MySQLDialect extends Dialect{
public boolean supportsLimitOffset(){
return true;
}
public boolean supportsLimit() {
return true;
}
public String getLimitString(String sql, int offset, int limit) {
return getLimitString(sql,offset,String.valueOf(offset),limit,String.valueOf(limit));
}
public String getLimitString(String sql, int offset,String offsetPlaceholder, int limit, String limitPlaceholder) {
if (offset > 0) {
return sql + " limit "+offsetPlaceholder+","+limitPlaceholder;
} else {
return sql + " limit "+limitPlaceholder;
}
}
}
其它数据库的Dialect实现请查看:
4.分页使用
直接调用SqlSession.selectList(statement, parameter, new RowBounds(offset,limit))即可使用物理分页
5.存在的问题
现不是使用占位符的方式(即不是“limit ?,?”而是使用“limit 8,20”)使用分页
完整代码可以查看即将发布的rapid-framework 3.0的ibatis3插件
mysql dialect配置_iBatis3基于方言(Dialect)的分页相关推荐
- java里dialect_iBatis3基于方言(Dialect)的分页
(注:以下代码是基于ibatis3 beta4的扩展,ibatis3正式版如果实现改变,将会继续跟进修改) iBatis3默认使用的分页是基于游标的分页,而这种分页在不同的数据库上性能差异不一致,最好 ...
- mysql 多进程配置_基于mysql_multi实现MySQL多实例多进程配置
环境设置 一台服务器配置IP为:192.168.200.111 主机名为:localhost 实验初始配置:关闭防火墙与selinux systemctl stop firewalld iptable ...
- mysql dialect配置_一步一步升级配置14: Mysql数据库,hibernate.dialect 使用MySQL5Dialect 替代 MySQLDialect...
一步一步升级配置14:Mysql数据库,hibernate.dialect使用org.hibernate.dialect.MySQL5Dialect替代org.hibernate.dialect.My ...
- mysql dialect配置_一步一步升级配置14:Mysql数据库,hibernate.dialect使用MySQL5_MySQL
Hibernate 一步一步升级配置14:Mysql数据库,hibernate.dialect使用org.hibernate.dialect.MySQL5Dialect替代org.hibernate. ...
- mysql dialect配置_一步一步升级配置14: Mysql数据库,hibernate.dialect 使用MySQL5_MySQL
Hibernate 一步一步升级配置14:Mysql数据库,hibernate.dialect使用org.hibernate.dialect.MySQL5Dialect替代org.hibernate. ...
- 数据库方言Dialect
使用Hibernate,在配置hibernate.cfg.xml时需指定使用数据库的方言: 例: <property name="dialect">org.hibern ...
- MySQL高级配置(二)详细介绍
一.MySQL优化配置详解 转自:http://blog.csdn.net/nightelve/article/details/17393631 1.目的: 通过根据服务器目前状况,修改Mysql的系 ...
- springboot + mysql + mybatis配置
上一篇文章中我们引入了基本的环境配置,接下来我们开始mysql相关配置: 依然是基于demo-springboot项目: 1.打开pom.xml,加入以下内容: <!--mysql--> ...
- MySQL数据库安全配置
文章来源:http://www.xfocus.net MySQL数据库安全配置 1.前言 MySQL 是完全网络化的跨平台关系型数据库系统,同时是具有客户机/服务器体系结构的分布式数据库管理系统.它具 ...
最新文章
- Python 学习之中的一个:在Mac OS X下基于Sublime Text搭建开发平台包括numpy,scipy
- 解决ScrollView嵌套ViewPager出现的滑动冲突问题
- 从源码说说dispatchTouchEvent与onTouchEvent的关系以及OnTouchListener的用法
- java——springmvc——注册中央调度器
- vue 中的nextTick
- Java语言程序设计(沈泽刚主编)第3版 第1~3章编程练习答案
- sox 转换pcm格式采样率
- 【YBT2022寒假Day1 B】方格填写(插头DP)
- WSO2流处理器相关学习(1)快速入门指南【转】
- 优化问题---切线、切向量、切平面;法线,法向量,法平面
- 移动互联网寒冬到来,程序员该怎么办?
- 小技巧(12):关于PC端简单的视频剪辑处理中,bandicam(录制)、pr(配音)、pr(导出)、剪映(字幕识别)、pr(最终版导出)的全过程及基础设置
- USB(十)2022-03-03
- 关于Vue和Yii的作者国籍
- 5. 求cosx计算公式
- Unable to preventDefault inside passive event listener due to target being treated as passive.
- Mysql的基本函数--与自定义函数
- MySQL的存储过程你了解吗?来看这篇文章,保证你不会后悔!
- 小米路由器探测和测评本人亲测
- antd的Table列选择、列拓展