001/* 002 * Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com). 003 * <p> 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * <p> 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * <p> 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package com.mybatisflex.core.mybatis; 017 018import com.mybatisflex.core.transaction.TransactionContext; 019import org.apache.ibatis.cursor.Cursor; 020import org.apache.ibatis.executor.Executor; 021import org.apache.ibatis.executor.parameter.ParameterHandler; 022import org.apache.ibatis.executor.resultset.DefaultResultSetHandler; 023import org.apache.ibatis.mapping.BoundSql; 024import org.apache.ibatis.mapping.MappedStatement; 025import org.apache.ibatis.session.ResultHandler; 026import org.apache.ibatis.session.RowBounds; 027 028import java.sql.SQLException; 029import java.sql.Statement; 030import java.util.Iterator; 031 032public class FlexResultSetHandler extends DefaultResultSetHandler { 033 034 public FlexResultSetHandler(Executor executor, MappedStatement mappedStatement, ParameterHandler parameterHandler 035 , ResultHandler<?> resultHandler, BoundSql boundSql, RowBounds rowBounds) { 036 super(executor, mappedStatement, parameterHandler, resultHandler, boundSql, rowBounds); 037 } 038 039 040 /** 041 * 从写 handleCursorResultSets, 用于适配在事务下自动关闭 Cursor 042 */ 043 @Override 044 public <E> Cursor<E> handleCursorResultSets(Statement stmt) throws SQLException { 045 Cursor<E> defaultCursor = super.handleCursorResultSets(stmt); 046 047 //in transaction 048 if (TransactionContext.getXID() != null) { 049 return new FlexCursor<>(defaultCursor); 050 } 051 052 return defaultCursor; 053 } 054 055 056 static class FlexCursor<T> implements Cursor<T> { 057 058 private final Cursor<T> originalCursor; 059 060 public FlexCursor(Cursor<T> cursor) { 061 this.originalCursor = cursor; 062 TransactionContext.holdCursor(cursor); 063 } 064 065 @Override 066 public void close() { 067 // do nothing 068 // 由 TransactionContext 去关闭 069 } 070 071 @Override 072 public boolean isOpen() { 073 return originalCursor.isOpen(); 074 } 075 076 @Override 077 public boolean isConsumed() { 078 return originalCursor.isConsumed(); 079 } 080 081 @Override 082 public int getCurrentIndex() { 083 return originalCursor.getCurrentIndex(); 084 } 085 086 @Override 087 public Iterator<T> iterator() { 088 return originalCursor.iterator(); 089 } 090 091 } 092 093}