iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >iBatis3基于方言(Dialect)
  • 728
分享到

iBatis3基于方言(Dialect)

方言Dialect 2023-01-31 01:01:19 728人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

(注:以下代码是基于ibatis3 beta4的扩展,ibatis3正式版如果实现改变,将会继续跟进修改) iBatis3默认使用的分页是基于游标的分页,而这种分页在不同的数据库上性能差异不一致,最好的办法当然是使用类似hibernate的

(注:以下代码是基于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代码 收藏代码
<configuration>
<plugins>
<!-- 指定数据库分页方言Dialect, 其它方言:oracleDialect,SQLServerDialect,SybaseDialect,DB2Dialect,postgresqlDialect,mysqlDialect,DerbyDialect-->
<plugin interceptor="cn.org.rapid_framework.ibatis3.plugin.OffsetLimitInterceptor">
<property name="dialectClass" value="cn.org.rapid_framework.jdbc.dialect.MySQLDialect"/>
</plugin>
</plugins>

<environments default="development">  
    <environment id="development">  
        <transactionManager type="JDBC" />  
        <dataSource type="POOLED">  
            <property name="driver" value="com.mysql.jdbc.Driver" />  
            <property name="url" value="jdbc:mysql://localhost:3306/test" />  
            <property name="username" value="root" />  
            <property name="passWord" value="123456" />  
        </dataSource>  
    </environment>  
</environments>  

<mappers>  
    <mapper resource="com/company/project/model/mapper/BlogMapper.xml" />  
</mappers>  

</configuration>

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实现请查看:

Http://rapid-framework.Googlecode.com/svn/trunk/rapid-framework/src/rapid_framework_common/cn/org/rapid_framework/jdbc/dialect/

4.分页使用

直接调用SqlSession.selectList(statement, parameter, new RowBounds(offset,limit))即可使用物理分页

5.存在的问题

现不是使用占位符的方式(即不是“limit ?,?”而是使用“limit 8,20”)使用分页

完整代码可以查看即将发布的rapid-framework 3.0的ibatis3插件

--结束END--

本文标题: iBatis3基于方言(Dialect)

本文链接: https://www.lsjlt.com/news/183540.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • iBatis3基于方言(Dialect)
    (注:以下代码是基于ibatis3 beta4的扩展,ibatis3正式版如果实现改变,将会继续跟进修改) iBatis3默认使用的分页是基于游标的分页,而这种分页在不同的数据库上性能差异不一致,最好的办法当然是使用类似hibernate的...
    99+
    2023-01-31
    方言 Dialect
  • 基于R语言for循环的替换方案
    R语言中,for循环运行比较慢 for(i in 1:1000){ print(i^2) } 补充:R语言:for循环使用小结 基本结构展示: vals =c(5,6,7)...
    99+
    2022-11-12
  • 基于Java语言MD5加密Base64转换方法
    本文提供了基于MD5加密16位和32位的方法,具体内容如下import java.io.IOException;import java.math.BigInteger;import java.security.MessageDigest;i...
    99+
    2023-05-31
    java md5 加密
  • javascript是基于什么的语言
    这篇文章主要讲解了“javascript是基于什么的语言”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“javascript是基于什么的语言”吧! ...
    99+
    2022-10-19
  • 基于R语言中的各种更新方法分享
    宏包的更新 卸载package remove.packages("mypackage") 查看的version R.version 或者 getRversion() ...
    99+
    2022-11-12
  • Go 语言下基于Redis分布式锁的实现方式
    分布式锁一般有三种实现方式:1. 数据库乐观锁;2. 基于Redis的分布式锁;3. 基于ZooKeeper的分布式锁。本篇博客将介绍第二种方式,基于Redis实现分布式锁。虽然网上...
    99+
    2022-11-12
  • 基于Ubuntu的R语言版本升级方法有哪些
    这篇文章主要讲解了“基于Ubuntu的R语言版本升级方法有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“基于Ubuntu的R语言版本升级方法有哪些”吧!1. 具体操作我们以 Ubuntu...
    99+
    2023-06-25
  • javascript是基于对象的语言吗
    这篇文章主要讲解了“javascript是基于对象的语言吗”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“javascript是基于对象的语言吗”吧! ...
    99+
    2022-10-19
  • vue基于哪个语言开发的
    这篇文章将为大家详细讲解有关vue基于哪个语言开发的,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。vue是基于JavaScript语言开发的,是一套用于构建用户界面的渐进...
    99+
    2022-10-19
  • 基于C语言实现2048游戏
    本文实例为大家分享了C语言实现2048游戏的具体代码,供大家参考,具体内容如下 #include <stdio.h> #include <stdlib.h>...
    99+
    2022-11-12
  • C语言基于EasyX绘制时钟
    本文实例为大家分享了C语言基于EasyX绘制时钟的具体代码,供大家参考,具体内容如下 函数说明: void line(     int x1,     int y1,     int...
    99+
    2022-11-13
  • 基于go语言的agent怎么用
    这篇文章给大家介绍基于go语言的agent怎么用,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。一 介绍     在构建数据库自动化运维系统的时候,数据库服务器上必须要有一个agent来执行...
    99+
    2023-06-04
  • nlp自然语言处理基于SVD的降维优化方法
    这篇文章主要介绍“nlp自然语言处理基于SVD的降维优化方法”,在日常操作中,相信很多人在nlp自然语言处理基于SVD的降维优化方法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”nlp自然语言处理基于SVD的...
    99+
    2023-06-29
  • 基于C语言实现http下载器
    目录功能思路缺陷代码C语言实现http的下载器。 例:做OTA升级功能时,我们能直接拿到的往往只是升级包的链接,需要我们自己去下载,这时候就需要用到http下载器。 这里分享一个: ...
    99+
    2022-12-28
    C语言http下载器 C语言http下载 C语言 下载器
  • 基于Go语言构建RESTful API服务
    目录什么是 RESTful API 一个简单的 RESTful API RESTful JSON API Gin 框架 引入 Gin 框架 使用 Gin 框架 新增一个用户 获取特定...
    99+
    2022-11-12
  • C语言基于EasyX实现贪吃蛇
    本文实例为大家分享了C语言基于EasyX实现贪吃蛇的具体代码,供大家参考,具体内容如下 成品展示: 实现思路: 贪吃蛇的实现思路并不复杂,由于我们需要将数据展示在图形窗口上,因此就...
    99+
    2022-11-13
  • C语言基于graphics.h实现圣诞树
    头文件 icon.h: #pragma once #ifndef _ICON_H_ #define _ICON_H_ #include<graphics.h> #...
    99+
    2022-11-12
  • 基于R语言 数据检验详解
    目录1. W检验(Shapiro–Wilk (夏皮罗–威克尔 ) W统计量检验)2. K检验(经验分布的Kolmogorov-Smirnov检验)3. 相关性...
    99+
    2022-11-13
  • 基于java语言实现快递系统
    本文实例为大家分享了java语言实现快递系统的具体代码,供大家参考,具体内容如下 功能介绍: 1、角色切换(快递员和普通用户) 快递员:有存快递、删除快递、修改快递信息、查看所有快递...
    99+
    2022-11-13
  • 以太网 VLAN的5种划分方式(基于端口、基于MAC地址、基于IP子网、基于协议、基于策略)介绍与基础配置命令
    2.8.3 以太网 VLAN(VLAN划分方式) VLAN的划分方式有 2.8.3 以太网 VLAN(VLAN划分方式)一、基于端口划分二、基于MAC地址划分三、基于IP子网划分四、基于协议划...
    99+
    2023-09-04
    网络 华为
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作