Spring 系列
- IoC 容器
- AOP
- SpringMVC
- Spring 事务
- Spring 源码故事(瞎编版)
- Spring 整体脉络
- Spring 类解析
- Spring 自定义标签解析
- Spring Scan 包扫描
- Spring 注解工具类
- Spring 别名注册
- Spring 标签解析类
- Spring ApplicationListener
- Spring messageSource
- Spring 自定义属性解析器
- Spring 排序工具
- Spring-import 注解
- Spring-定时任务
- Spring StopWatch
- Spring 元数据
- Spring 条件接口
- Spring MultiValueMap
- Spring MethodOverride
- Spring BeanDefinitionReaderUtils
- Spring PropertyPlaceholderHelper
- Spring-AnnotationFormatterFactory
- Spring-Formatter
- Spring-Parser
- Spring-Printer
- Spring5 新特性
- Spring RMI
- Spring Message
- SpringBoot
- SpringBootBatch
- Spring Cloud
- SpringSecurity
MyBatis
- 基础支持层
- 核心处理层
- 类解析
Netty
- 网络 IO 技术基础
- JDK1.8 NIO 包 核心组件源码剖析
- Netty 粘拆包及解决方案
- Netty 多协议开发
- 基于 Netty 开发服务端及客户端
- Netty 主要组件的源码分析
- Netty 高级特性
- Netty 技术细节源码分析
Dubbo
- 架构设计
- SPI 机制
- 注册中心
- 远程通信
- RPC
- 集群
Tomcat
- Servlet 与 Servlet 容器
- Web 容器
Redis
Nacos
Sentinel
RocketMQ
- RocketMQ NameServer 与 Broker 的通信
- RocketMQ 生产者启动流程
- RocketMQ 消息发送流程
- RocketMQ 消息发送存储流程
- RocketMQ MappedFile 内存映射文件详解
- RocketMQ ConsumeQueue 详解
- RocketMQ CommitLog 详解
- RocketMQ IndexFile 详解
- RocketMQ 消费者启动流程
- RocketMQ 消息拉取流程
- RocketMQ Broker 处理拉取消息请求流程
- RocketMQ 消息消费流程
番外篇(JDK 1.8)
- 基础类库
- 集合
- 并发编程
学习心得
文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
Mybatis Cursor
Mybatis Cursor
- Author: HuiFer
- Description: 该文介绍 mybatis Cursor 源码
- 源码阅读工程: SourceHot-Mybatis
Cursor
- 源码位置:
org.apache.ibatis.cursor.Cursor
- 继承
Iterable
说明是一个迭代器,继承Closeable
说明有一个东西需要关闭
public interface Cursor<T> extends Closeable, Iterable<T> {
/**
* 游标开始从数据库获取数据,返回true,反之false
*
* @return true if the cursor has started to fetch items from database.
*/
boolean isOpen();
/**
* 数据库元素都被获取,返回true,反之false
*
* @return true if the cursor is fully consumed and has returned all elements matching the query.
*/
boolean isConsumed();
/**
* 获取数据索引,从0开始,没有返回-1
* Get the current item index. The first item has the index 0.
*
* @return -1 if the first cursor item has not been retrieved. The index of the current item retrieved.
*/
int getCurrentIndex();
}
DefaultCursor
public class DefaultCursor<T> implements Cursor<T> {
/**
* 对象包装结果处理类
*/
protected final ObjectWrapperResultHandler<T> objectWrapperResultHandler = new ObjectWrapperResultHandler<>();
// ResultSetHandler stuff
/**
* ResultSet 处理器
*/
private final DefaultResultSetHandler resultSetHandler;
/**
* 结果映射
*/
private final ResultMap resultMap;
/**
* ResultSet 包装对象
*/
private final ResultSetWrapper rsw;
/**
* 分页的
*/
private final RowBounds rowBounds;
/**
* 游标的迭代器
*/
private final CursorIterator cursorIterator = new CursorIterator();
/**
* 游标开启判断
*/
private boolean iteratorRetrieved;
/**
* 游标状态,默认是创建未使用
*/
private CursorStatus status = CursorStatus.CREATED;
/**
* 分页索引,默认-1
*/
private int indexWithRowBound = -1;
/**
* 构造方法
*
* @param resultSetHandler
* @param resultMap
* @param rsw
* @param rowBounds
*/
public DefaultCursor(DefaultResultSetHandler resultSetHandler, ResultMap resultMap, ResultSetWrapper rsw, RowBounds rowBounds) {
this.resultSetHandler = resultSetHandler;
this.resultMap = resultMap;
this.rsw = rsw;
this.rowBounds = rowBounds;
}
@Override
public boolean isOpen() {
return status == CursorStatus.OPEN;
}
@Override
public boolean isConsumed() {
return status == CursorStatus.CONSUMED;
}
/**
* 当前索引
* @return
*/
@Override
public int getCurrentIndex() {
return rowBounds.getOffset() + cursorIterator.iteratorIndex;
}
/**
* 迭代器获取
* @return
*/
@Override
public Iterator<T> iterator() {
// 是否获取过
if (iteratorRetrieved) {
throw new IllegalStateException("Cannot open more than one iterator on a Cursor");
}
// 是否关闭
if (isClosed()) {
throw new IllegalStateException("A Cursor is already closed.");
}
iteratorRetrieved = true;
return cursorIterator;
}
/**
* {@link Closeable} 关闭{@link ResultSet}
*/
@Override
public void close() {
// 判断是否关闭
if (isClosed()) {
return;
}
ResultSet rs = rsw.getResultSet();
try {
if (rs != null) {
rs.close();
}
} catch (SQLException e) {
// ignore
} finally {
// 设置游标状态
status = CursorStatus.CLOSED;
}
}
/**
* 去到真正的数据行
* @return
*/
protected T fetchNextUsingRowBound() {
T result = fetchNextObjectFromDatabase();
while (objectWrapperResultHandler.fetched && indexWithRowBound < rowBounds.getOffset()) {
result = fetchNextObjectFromDatabase();
}
return result;
}
/**
* 从数据库获取数据
* @return
*/
protected T fetchNextObjectFromDatabase() {
if (isClosed()) {
return null;
}
try {
objectWrapperResultHandler.fetched = false;
// 游标状态设置
status = CursorStatus.OPEN;
if (!rsw.getResultSet().isClosed()) {
// 处理数据结果放入,objectWrapperResultHandler
resultSetHandler.handleRowValues(rsw, resultMap, objectWrapperResultHandler, RowBounds.DEFAULT, null);
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
// 获取处理结果
T next = objectWrapperResultHandler.result;
// 结果不为空
if (objectWrapperResultHandler.fetched) {
// 索引+1
indexWithRowBound++;
}
// No more object or limit reached
// 如果没有数据, 或者 当前读取条数= 偏移量+限额量
if (!objectWrapperResultHandler.fetched || getReadItemsCount() == rowBounds.getOffset() + rowBounds.getLimit()) {
// 关闭游标
close();
status = CursorStatus.CONSUMED;
}
// 设置结果为null
objectWrapperResultHandler.result = null;
return next;
}
/**
* 是否关闭状态判断
*
* @return
*/
private boolean isClosed() {
return status == CursorStatus.CLOSED || status == CursorStatus.CONSUMED;
}
/**
* 下一个索引
* @return
*/
private int getReadItemsCount() {
return indexWithRowBound + 1;
}
/**
* 游标的状态
*/
private enum CursorStatus {
/**
* 新创建的游标, ResultSet 还没有使用过
* A freshly created cursor, database ResultSet consuming has not started.
*/
CREATED,
/**
* 游标使用过, ResultSet 被使用
* A cursor currently in use, database ResultSet consuming has started.
*/
OPEN,
/**
* 游标关闭, 可能没有被消费完全
* A closed cursor, not fully consumed.
*/
CLOSED,
/**
* 游标彻底消费完毕, 关闭了
* A fully consumed cursor, a consumed cursor is always closed.
*/
CONSUMED
}
/**
* 对象处理结果的包装类
* @param <T>
*/
protected static class ObjectWrapperResultHandler<T> implements ResultHandler<T> {
/**
* 数据结果
*/
protected T result;
/**
* 是否null
*/
protected boolean fetched;
/**
* 从{@link ResultContext} 获取结果对象
* @param context
*/
@Override
public void handleResult(ResultContext<? extends T> context) {
this.result = context.getResultObject();
context.stop();
fetched = true;
}
}
/**
* 游标迭代器
*/
protected class CursorIterator implements Iterator<T> {
/**
* 下一个数据
* Holder for the next object to be returned.
*/
T object;
/**
* 下一个的索引
* Index of objects returned using next(), and as such, visible to users.
*/
int iteratorIndex = -1;
/**
* 是否有下一个值
* @return
*/
@Override
public boolean hasNext() {
if (!objectWrapperResultHandler.fetched) {
object = fetchNextUsingRowBound();
}
return objectWrapperResultHandler.fetched;
}
/**
* 下一个值
* @return
*/
@Override
public T next() {
// Fill next with object fetched from hasNext()
T next = object;
if (!objectWrapperResultHandler.fetched) {
next = fetchNextUsingRowBound();
}
if (objectWrapperResultHandler.fetched) {
objectWrapperResultHandler.fetched = false;
object = null;
iteratorIndex++;
return next;
}
throw new NoSuchElementException();
}
/**
* 不可执行抛出异常
*/
@Override
public void remove() {
throw new UnsupportedOperationException("Cannot remove element from Cursor");
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论