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