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.row;
017
018import com.mybatisflex.core.paginate.Page;
019import com.mybatisflex.core.query.QueryWrapper;
020import org.apache.ibatis.executor.BatchResult;
021import org.apache.ibatis.session.ExecutorType;
022import org.apache.ibatis.session.SqlSession;
023import org.apache.ibatis.session.SqlSessionFactory;
024
025import java.util.Collection;
026import java.util.List;
027import java.util.function.BiConsumer;
028import java.util.function.Function;
029
030public class RowMapperInvoker {
031
032    private final SqlSessionFactory sqlSessionFactory;
033
034    public RowMapperInvoker(SqlSessionFactory sqlSessionFactory) {
035        this.sqlSessionFactory = sqlSessionFactory;
036    }
037
038    private <R> R execute(Function<RowMapper, R> function) {
039        try (SqlSession sqlSession = sqlSessionFactory.openSession(true)) {
040            RowMapper mapper = sqlSession.getMapper(RowMapper.class);
041            return function.apply(mapper);
042        }
043    }
044
045    public int insert(String schema, String tableName, Row row) {
046        return execute(mapper -> mapper.insert(schema, tableName, row));
047    }
048
049
050    public int insertBySql(String sql, Object... args) {
051        return execute(mapper -> mapper.insertBySql(sql, args));
052    }
053
054    public int insertBatchWithFirstRowColumns(String schema, String tableName, List<Row> rows) {
055        return execute(mapper -> mapper.insertBatchWithFirstRowColumns(schema, tableName, rows));
056    }
057
058    public int deleteBySql(String sql, Object... args) {
059        return execute(mapper -> mapper.deleteBySql(sql, args));
060    }
061
062    public int deleteById(String schema, String tableName, Row row) {
063        return execute(mapper -> mapper.deleteById(schema, tableName, row));
064    }
065
066    public int deleteById(String schema, String tableName, String primaryKey, Object id) {
067        return execute(mapper -> mapper.deleteById(schema, tableName, primaryKey, id));
068    }
069
070    public int deleteBatchByIds(String schema, String tableName, String primaryKey, Collection<?> ids) {
071        return execute(mapper -> mapper.deleteBatchByIds(schema, tableName, primaryKey, ids));
072    }
073
074
075    public int deleteByQuery(String schema, String tableName, QueryWrapper queryWrapper) {
076        return execute(mapper -> mapper.deleteByQuery(schema, tableName, queryWrapper));
077    }
078
079    public int updateBySql(String sql, Object... args) {
080        return execute(mapper -> mapper.updateBySql(sql, args));
081    }
082
083
084    public <M, E> int[] executeBatch(Collection<E> datas, int batchSize, Class<M> mapperClass, BiConsumer<M, E> consumer) {
085        int[] results = new int[datas.size()];
086        try (SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, true)) {
087            M mapper = sqlSession.getMapper(mapperClass);
088            int counter = 0;
089            int resultsPos = 0;
090            for (E data : datas) {
091                consumer.accept(mapper, data);
092                if (++counter == batchSize) {
093                    counter = 0;
094                    List<BatchResult> batchResults = sqlSession.flushStatements();
095                    for (BatchResult batchResult : batchResults) {
096                        int[] updateCounts = batchResult.getUpdateCounts();
097                        for (int updateCount : updateCounts) {
098                            results[resultsPos++] = updateCount;
099                        }
100                    }
101                }
102            }
103            if (counter != 0) {
104                List<BatchResult> batchResults = sqlSession.flushStatements();
105                for (BatchResult batchResult : batchResults) {
106                    int[] updateCounts = batchResult.getUpdateCounts();
107                    for (int updateCount : updateCounts) {
108                        results[resultsPos++] = updateCount;
109                    }
110                }
111            }
112        }
113        return results;
114    }
115
116
117
118    public <M> int[] executeBatch(int totalSize, int batchSize, Class<M> mapperClass, BiConsumer<M, Integer> consumer) {
119        int[] results = new int[totalSize];
120        try (SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, true)) {
121            M mapper = sqlSession.getMapper(mapperClass);
122            int counter = 0;
123            int resultsPos = 0;
124            for (int i = 0; i < totalSize; i++) {
125                consumer.accept(mapper, i);
126                if (++counter == batchSize) {
127                    counter = 0;
128                    List<BatchResult> batchResults = sqlSession.flushStatements();
129                    for (BatchResult batchResult : batchResults) {
130                        int[] updateCounts = batchResult.getUpdateCounts();
131                        for (int updateCount : updateCounts) {
132                            results[resultsPos++] = updateCount;
133                        }
134                    }
135                }
136
137            }
138
139            if (counter != 0) {
140                List<BatchResult> batchResults = sqlSession.flushStatements();
141                for (BatchResult batchResult : batchResults) {
142                    int[] updateCounts = batchResult.getUpdateCounts();
143                    for (int updateCount : updateCounts) {
144                        results[resultsPos++] = updateCount;
145                    }
146                }
147            }
148        }
149        return results;
150    }
151
152    public int updateById(String schema, String tableName, Row row) {
153        return execute(mapper -> mapper.updateById(schema, tableName, row));
154    }
155
156    public int updateByQuery(String schema, String tableName, Row data, QueryWrapper queryWrapper) {
157        return execute(mapper -> mapper.updateByQuery(schema, tableName, data, queryWrapper));
158    }
159
160    public int updateBatchById(String schema, String tableName, List<Row> rows) {
161        return execute(mapper -> mapper.updateBatchById(schema, tableName, rows));
162    }
163
164    public Row selectOneBySql(String sql, Object... args) {
165        return execute(mapper -> mapper.selectOneBySql(sql, args));
166    }
167
168    public Row selectOneById(String schema, String tableName, Row row) {
169        return execute(mapper -> mapper.selectOneById(schema, tableName, row));
170    }
171
172    public Row selectOneById(String schema, String tableName, String primaryKey, Object id) {
173        return execute(mapper -> mapper.selectOneById(schema, tableName, primaryKey, id));
174    }
175
176    public Row selectOneByQuery(String schema, String tableName, QueryWrapper queryWrapper) {
177        return execute(mapper -> mapper.selectOneByQuery(schema, tableName, queryWrapper));
178    }
179
180    public List<Row> selectListBySql(String sql, Object... args) {
181        return execute(mapper -> mapper.selectListBySql(sql, args));
182    }
183
184    public List<Row> selectListByQuery(String schema, String tableName, QueryWrapper queryWrapper) {
185        return execute(mapper -> mapper.selectListByQuery(schema, tableName, queryWrapper));
186    }
187
188    public List<Row> selectAll(String schema, String tableName) {
189        return execute(mapper -> mapper.selectAll(schema, tableName));
190    }
191
192    public Object selectObjectByQuery(String schema, String tableName, QueryWrapper queryWrapper) {
193        return execute(mapper -> mapper.selectObjectByQuery(schema, tableName, queryWrapper));
194    }
195
196    public List<Object> selectObjectListByQuery(String schema, String tableName, QueryWrapper queryWrapper) {
197        return execute(mapper -> mapper.selectObjectListByQuery(schema, tableName, queryWrapper));
198    }
199
200    public Object selectObject(String sql, Object... args) {
201        return execute(mapper -> mapper.selectObject(sql, args));
202    }
203
204    public List<Object> selectObjectList(String sql, Object... args) {
205        return execute(mapper -> mapper.selectObjectList(sql, args));
206    }
207
208    public long selectCount(String sql, Object... args) {
209        return execute(mapper -> mapper.selectCount(sql, args));
210    }
211
212
213    public long selectCountByQuery(String schema, String tableName, QueryWrapper queryWrapper) {
214        return execute(mapper -> mapper.selectCountByQuery(schema, tableName, queryWrapper));
215    }
216
217    public Page<Row> paginate(String schema, String tableName, Page<Row> page, QueryWrapper queryWrapper) {
218        return execute(mapper -> mapper.paginate(schema, tableName, page, queryWrapper));
219    }
220
221}