mysql 分页查询拦截器_MyBatis之拦截器分页

鲁春利的工作笔记,好记性不如烂笔头

数据库的分页主要有物理分页和逻辑分页。

物理分页:数据库本身提供的分页方式,如MySQL的limit、Oracle的rownum、SqlServer的top,好处是效率高,不好的地方就是不同数据库有不同的查询方式。

逻辑分页:从数据库将所有记录查询出来,存储到内存中,然后数据再直接从内存中获取并筛选分页,好处是能够统一查询方式,不好的地方是效率低,因为每次都要把全部数据查询出来再处理。

常用orm框架采用的分页技术:

①:hibernate采用的是物理分页;

②:MyBatis使用RowBounds实现的分页是逻辑分页,也就是先把数据记录全部查询出来,然在再根据offset和limit截断记录。

MetaObject

org.apache.ibatis.reflection.MetaObject是Mybatis提供的一个的工具类,Mybatis在sql参数设置和结果集映射里经常使用到这个对象。属性:// 原始对象

private Object originalObject;

// 对原始对象的一个封装

private ObjectWrapper objectWrapper;

// org.apache.ibatis.reflection.factory.DefaultObjectFactory的父类

private ObjectFactory objectFactory;

// org.apache.ibatis.reflection.wrapper.DefaultObjectWrapperFactory的父类

private ObjectWrapperFactory objectWrapperFactory;

方法:// 用于包装对象

MetaObject forObject(Object object,ObjectFactory objectFactory, ObjectWrapperFactory objectWrapperFactory)

// 用于获取属性的值(支持OGNL的方法)

Object getValue(String name)

// 用于设置属性的值(支持OGNL的方法)

void setValue(String name, Object value)

构造方法private MetaObject(Object object, ObjectFactory objectFactory, ObjectWrapperFactory objectWrapperFactory) {

this.originalObject = object;

this.objectFactory = objectFactory;

this.objectWrapperFactory = objectWrapperFactory;

if (object instanceof ObjectWrapper) {

this.objectWrapper = (ObjectWrapper) object;

} else if (objectWrapperFactory.hasWrapperFor(object)) {

this.objectWrapper = objectWrapperFactory.getWrapperFor(this, object);

} else if (object instanceof Map) {

this.objectWrapper = new MapWrapper(this, (Map) object);

} else if (object instanceof Collection) {

this.objectWrapper = new CollectionWrapper(this, (Collection) object);

} else {

this.objectWrapper = new BeanWrapper(this, object);

}

}

forObject方法public static MetaObject forObject(Object object, ObjectFactory objectFactory, ObjectWrapperFactory objectWrapperFactory) {

if (object == null) {

return SystemMetaObject.NULL_META_OBJECT;

} else {

return new MetaObject(object, objectFactory, objectWrapperFactory);

}

}

getValuepublic Object getValue(String name) {

PropertyTokenizer prop = new PropertyTokenizer(name);

if (prop.hasNext()) {

MetaObject metaValue = metaObjectForProperty(prop.getIndexedName());

if (metaValue == SystemMetaObject.NULL_META_OBJECT) {

return null;

} else {

// 这里相当于递归调用,直到最后一层。例如user.cust.custId

// 第一次递归cust.custId

// 第二次递归custId,这个就是真正访问要返回的

return metaValue.getValue(prop.getChildren());

}

} else {

return objectWrapper.get(prop);

}

}

setValuepublic void setValue(String name, Object value) {

PropertyTokenizer prop = new PropertyTokenizer(name);

if (prop.hasNext()) {

MetaObject metaValue = metaObjectForProperty(prop.getIndexedName());

if (metaValue == SystemMetaObject.NULL_META_OBJECT) {

if (value == null && prop.getChildren() != null) {

return; // don't instantiate child path if value is null

} else {

metaValue = objectWrapper.instantiatePropertyValue(name, prop, objectFactory);

}

}

metaValue.setValue(prop.getChildren(), value);

} else {

objectWrapper.set(prop, value);

}

}

拦截器签名@Intercepts({

@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class})

})

public class PreparePaginationInterceptor extends BaseInterceptor {

从签名里可以看出,要拦截的目标类型是StatementHandler(注意:type只能配置成接口类型),拦截的方法是名称为prepare参数为Connection类型的方法。

说明:关于为什么要把拦截器加到StatementHandler请参阅MyBatis之SqlSession介绍

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值