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.FlexGlobalConfig;
019import com.mybatisflex.core.exception.FlexExceptions;
020import com.mybatisflex.core.paginate.Page;
021import com.mybatisflex.core.query.CPI;
022import com.mybatisflex.core.query.QueryCondition;
023import com.mybatisflex.core.query.QueryTable;
024import com.mybatisflex.core.query.QueryWrapper;
025import com.mybatisflex.core.transaction.Propagation;
026import com.mybatisflex.core.transaction.TransactionalManager;
027import org.apache.ibatis.session.SqlSessionFactory;
028import org.apache.ibatis.util.MapUtil;
029
030import java.util.Collection;
031import java.util.List;
032import java.util.Map;
033import java.util.concurrent.ConcurrentHashMap;
034import java.util.function.Supplier;
035
036/**
037 * 针对 RowMapper 的静态方法进行封装
038 */
039public class Db {
040
041    private static final Map<String, RowMapperInvoker> INVOKER_MAP = new ConcurrentHashMap<>();
042    static RowMapperInvoker defaultRowMapperInvoker;
043
044    public static RowMapperInvoker invoker() {
045        if (defaultRowMapperInvoker == null) {
046            FlexGlobalConfig defaultConfig = FlexGlobalConfig.getDefaultConfig();
047            SqlSessionFactory sqlSessionFactory = defaultConfig.getSqlSessionFactory();
048            defaultRowMapperInvoker = new RowMapperInvoker(sqlSessionFactory);
049        }
050        return defaultRowMapperInvoker;
051    }
052
053    public static RowMapperInvoker invoker(String environmentId) {
054        return MapUtil.computeIfAbsent(INVOKER_MAP, environmentId, key -> {
055            SqlSessionFactory sqlSessionFactory = FlexGlobalConfig.getConfig(key).getSqlSessionFactory();
056            return new RowMapperInvoker(sqlSessionFactory);
057        });
058    }
059
060
061    /**
062     * 网 tableName 插入一条 row 数据
063     *
064     * @param tableName 表名
065     * @param row       数据
066     */
067    public static int insert(String tableName, Row row) {
068        return invoker().insert(tableName, row);
069    }
070
071
072    /**
073     * 直接编写 sql 插入数据
074     *
075     * @param sql  sql 内容
076     * @param args sql 参数
077     */
078    public static int insertBySql(String sql, Object... args) {
079        return invoker().insertBySql(sql, args);
080    }
081
082
083    /**
084     * 批量插入数据
085     *
086     * @param tableName 表名
087     * @param rows      数据
088     */
089    public static int[] insertBatch(String tableName, Collection<Row> rows) {
090        return insertBatch(tableName, rows, rows.size());
091    }
092
093    /**
094     * 批量插入数据
095     *
096     * @param tableName 表名
097     * @param rows      数据
098     * @param batchSize 每次提交的数据量
099     */
100    public static int[] insertBatch(String tableName, Collection<Row> rows, int batchSize) {
101        return invoker().insertBatch(tableName, rows, batchSize);
102    }
103
104    /**
105     * 批量插入数据,根据第一条内容来构建插入的字段,效率比 {@link #insertBatch(String, Collection, int)} 高
106     *
107     * @param tableName 表名
108     * @param rows      数据
109     */
110    public static int insertBatchWithFirstRowColumns(String tableName, List<Row> rows) {
111        return invoker().insertBatchWithFirstRowColumns(tableName, rows);
112    }
113
114    /**
115     * 编写 delete sql 来删除数据
116     *
117     * @param sql  sql 内容
118     * @param args 参数
119     */
120    public static int deleteBySql(String sql, Object... args) {
121        return invoker().deleteBySql(sql, args);
122    }
123
124    /**
125     * 根据主键来删除数据,其中 row 是通过 {@link Row#ofKey(RowKey, Object)} 来进行构建的
126     *
127     * @param tableName 表名
128     * @param row       主键 和 id值
129     */
130    public static int deleteById(String tableName, Row row) {
131        return invoker().deleteById(tableName, row);
132    }
133
134    /**
135     * 根据主键来删除 1 条数据
136     *
137     * @param tableName  表名
138     * @param primaryKey 主键字段名称
139     * @param id         主键值
140     */
141    public static int deleteById(String tableName, String primaryKey, Object id) {
142        return invoker().deleteById(tableName, primaryKey, id);
143    }
144
145    /**
146     * 根据 id 集合来批量删除数据
147     *
148     * @param tableName  表名
149     * @param primaryKey 主键字段名称
150     * @param ids        id 集合
151     */
152    public static int deleteBatchByIds(String tableName, String primaryKey, Collection<?> ids) {
153        return invoker().deleteBatchByIds(tableName, primaryKey, ids);
154    }
155
156    /**
157     * 根据 map 构建的 where 条件来删除数据
158     *
159     * @param tableName    表名
160     * @param whereColumns where 条件
161     */
162    public static int deleteByMap(String tableName, Map<String, Object> whereColumns) {
163        return invoker().deleteByQuery(tableName, new QueryWrapper().where(whereColumns));
164    }
165
166
167    /**
168     * 根据 condition 条件删除数据
169     *
170     * @param tableName 表名
171     * @param condition 条件内容
172     */
173    public static int deleteByCondition(String tableName, QueryCondition condition) {
174        return invoker().deleteByQuery(tableName, new QueryWrapper().where(condition));
175    }
176
177    /**
178     * 根据 query 构建的条件来删除数据
179     *
180     * @param tableName    表名
181     * @param queryWrapper query
182     */
183    public static int deleteByQuery(String tableName, QueryWrapper queryWrapper) {
184        return invoker().deleteByQuery(tableName, queryWrapper);
185    }
186
187
188    /**
189     * 根据原生 sql 来更新数据
190     *
191     * @param sql  sql 内容
192     * @param args sql 参数
193     */
194    public static int updateBySql(String sql, Object... args) {
195        return invoker().updateBySql(sql, args);
196    }
197
198
199    /**
200     * 根据 id 来更新数据
201     *
202     * @param tableName 表情
203     * @param row       id 及其内容
204     */
205    public static int updateById(String tableName, Row row) {
206        return invoker().updateById(tableName, row);
207    }
208
209    /**
210     * 根据 map 构建的条件来更新数据
211     *
212     * @param tableName    表名
213     * @param data         数据内容
214     * @param whereColumns where 条件
215     */
216    public static int updateByMap(String tableName, Row data, Map<String, Object> whereColumns) {
217        return invoker().updateByQuery(tableName, data, new QueryWrapper().where(whereColumns));
218    }
219
220    /**
221     * 根据 condition 来更新数据
222     *
223     * @param tableName 表名
224     * @param data      数据
225     * @param condition 条件
226     */
227    public static int updateByCondition(String tableName, Row data, QueryCondition condition) {
228        return invoker().updateByQuery(tableName, data, new QueryWrapper().where(condition));
229    }
230
231
232    /**
233     * 根据 query 构建的条件来更新数据
234     *
235     * @param tableName    表名
236     * @param data         数据内容
237     * @param queryWrapper queryWrapper 条件
238     */
239    public static int updateByQuery(String tableName, Row data, QueryWrapper queryWrapper) {
240        return invoker().updateByQuery(tableName, data, queryWrapper);
241    }
242
243
244    /**
245     * 根据主键来批量更新数据
246     *
247     * @param tableName 表名
248     * @param rows      还有主键的数据
249     */
250    public static int updateBatchById(String tableName, List<Row> rows) {
251        return invoker().updateBatchById(tableName, rows);
252    }
253
254
255    /**
256     * 根据 sql 来查询 1 条数据
257     *
258     * @param sql  sql 内容
259     * @param args sql 参数
260     */
261    public static Row selectOneBySql(String sql, Object... args) {
262        return invoker().selectOneBySql(sql, args);
263    }
264
265
266    /**
267     * 根据 id 来查询 1 条数据
268     *
269     * @param tableName 表名
270     * @param row       主键和 id 值
271     */
272    public static Row selectOneById(String tableName, Row row) {
273        return invoker().selectOneById(tableName, row);
274    }
275
276
277    /**
278     * 根据主键来查询 1 条数据
279     *
280     * @param tableName  表名
281     * @param primaryKey 主键字段名称
282     * @param id         主键值
283     */
284    public static Row selectOneById(String tableName, String primaryKey, Object id) {
285        return invoker().selectOneById(tableName, primaryKey, id);
286    }
287
288
289    /**
290     * 根据 map 来查询 1 条数据
291     *
292     * @param tableName    表名
293     * @param whereColumns where条件
294     */
295    public static Row selectOneByMap(String tableName, Map whereColumns) {
296        return invoker().selectOneByQuery(tableName, new QueryWrapper().where(whereColumns));
297    }
298
299    /**
300     * 根据 condition 来查询数据
301     *
302     * @param tableName 表名
303     * @param condition 条件
304     */
305    public static Row selectOneByCondition(String tableName, QueryCondition condition) {
306        return invoker().selectOneByQuery(tableName, new QueryWrapper().where(condition));
307    }
308
309
310    /**
311     * 根据 queryWrapper 来查询 1 条数据
312     *
313     * @param tableName    表名
314     * @param queryWrapper queryWrapper
315     */
316    public static Row selectOneByQuery(String tableName, QueryWrapper queryWrapper) {
317        return invoker().selectOneByQuery(tableName, queryWrapper);
318    }
319
320
321    /**
322     * 直接根据 queryWrapper 查询 1 条数据
323     *
324     * @param queryWrapper 必须带有 from 的 queryWrapper
325     */
326    public static Row selectOneByQuery(QueryWrapper queryWrapper) {
327        List<QueryTable> queryTables = CPI.getQueryTables(queryWrapper);
328        if (queryTables == null || queryTables.isEmpty()) {
329            throw FlexExceptions.wrap("table must not be null or empty in Db.selectOneByQuery");
330        }
331        return invoker().selectOneByQuery(null, queryWrapper);
332    }
333
334
335    /**
336     * 通过 sql 来查询多条数据
337     *
338     * @param sql  sql 内容
339     * @param args sql 参数
340     */
341    public static List<Row> selectListBySql(String sql, Object... args) {
342        return invoker().selectListBySql(sql, args);
343    }
344
345
346    /**
347     * 通过 map 构建的条件来查询数据列表
348     *
349     * @param tableName    表名
350     * @param whereColumns where 条件
351     */
352    public static List<Row> selectListByMap(String tableName, Map<String, Object> whereColumns) {
353        return invoker().selectListByQuery(tableName, new QueryWrapper().where(whereColumns));
354    }
355
356    /**
357     * 根据 map 构建的条件来查询数据列表
358     *
359     * @param tableName    表名
360     * @param whereColumns 条件
361     * @param count        数据量
362     */
363    public static List<Row> selectListByMap(String tableName, Map<String, Object> whereColumns, int count) {
364        return invoker().selectListByQuery(tableName, new QueryWrapper().where(whereColumns).limit(count));
365    }
366
367
368    /**
369     * 通过 condition 条件来查询数据列表
370     *
371     * @param tableName 表名
372     * @param condition where 条件
373     */
374    public static List<Row> selectListByCondition(String tableName, QueryCondition condition) {
375        return invoker().selectListByQuery(tableName, new QueryWrapper().where(condition));
376    }
377
378    /**
379     * 根据 condition 条件来查询数据列表
380     *
381     * @param tableName 表名
382     * @param condition 条件
383     * @param count     数据量
384     */
385    public static List<Row> selectListByCondition(String tableName, QueryCondition condition, int count) {
386        return invoker().selectListByQuery(tableName, new QueryWrapper().where(condition).limit(count));
387    }
388
389
390    /**
391     * 通过 query 来查询数据列表
392     *
393     * @param tableName    表名
394     * @param queryWrapper query 条件
395     */
396    public static List<Row> selectListByQuery(String tableName, QueryWrapper queryWrapper) {
397        return invoker().selectListByQuery(tableName, queryWrapper);
398    }
399
400
401    /**
402     * 通过 query 来查询数据列表
403     *
404     * @param queryWrapper 必须带有 from 的 queryWrapper
405     */
406    public static List<Row> selectListByQuery(QueryWrapper queryWrapper) {
407        List<QueryTable> queryTables = CPI.getQueryTables(queryWrapper);
408        if (queryTables == null || queryTables.isEmpty()) {
409            throw FlexExceptions.wrap("table must not be null or empty in Db.selectListByQuery");
410        }
411        return invoker().selectListByQuery(null, queryWrapper);
412    }
413
414    /**
415     * 查询某张表的所有数据
416     *
417     * @param tableName 表名
418     */
419    public static List<Row> selectAll(String tableName) {
420        return invoker().selectAll(tableName);
421    }
422
423    /**
424     * 查询某个内容,数据返回的应该只有 1 行 1 列
425     *
426     * @param sql  sql 内容
427     * @param args sql 参数
428     */
429    public static Object selectObject(String sql, Object... args) {
430        return invoker().selectObject(sql, args);
431    }
432
433
434    /**
435     * 查询某列内容,数据返回应该有 多行 1 列
436     *
437     * @param sql  sql 内容
438     * @param args sql 参数
439     */
440    public static List<Object> selectObjectList(String sql, Object... args) {
441        return invoker().selectObjectList(sql, args);
442    }
443
444
445    /**
446     * 查收 count 数据,一般用于 select count(*)...
447     * 或者返回的内容是一行1列,且是数值类型的也可以用此方法
448     *
449     * @param sql  sql 内容
450     * @param args sql 参数
451     */
452    public static long selectCount(String sql, Object... args) {
453        return invoker().selectCount(sql, args);
454    }
455
456
457    /**
458     * 根据 condition 条件来查询数量
459     *
460     * @param tableName 表名
461     * @param condition 条件
462     */
463    public static long selectCountByCondition(String tableName, QueryCondition condition) {
464        return invoker().selectCountByQuery(tableName, new QueryWrapper().where(condition));
465    }
466
467
468    /**
469     * 根据 query 构建的条件来查询数据量
470     *
471     * @param tableName    表名
472     * @param queryWrapper query 条件
473     */
474    public static long selectCountByQuery(String tableName, QueryWrapper queryWrapper) {
475        return invoker().selectCountByQuery(tableName, queryWrapper);
476    }
477
478
479    /**
480     * 直接根据 query 来查询数据量
481     *
482     * @param queryWrapper 必须带有表名的 queryWrapper
483     * @return 数据量
484     */
485    public static long selectCountByQuery(QueryWrapper queryWrapper) {
486        List<QueryTable> queryTables = CPI.getQueryTables(queryWrapper);
487        if (queryTables == null || queryTables.isEmpty()) {
488            throw FlexExceptions.wrap("table must not be null or empty in Db.selectCountByQuery");
489        }
490        return invoker().selectCountByQuery(null, queryWrapper);
491    }
492
493
494    /**
495     * 分页查询
496     *
497     * @param tableName  表名
498     * @param pageNumber 当前的页码
499     * @param pageSize   每页的数据量
500     * @param condition  条件
501     */
502    public static Page<Row> paginate(String tableName, int pageNumber, int pageSize, QueryCondition condition) {
503        return invoker().paginate(tableName, new Page<>(pageNumber, pageSize), QueryWrapper.create().where(condition));
504    }
505
506
507    /**
508     * 分页查询
509     *
510     * @param tableName  表名
511     * @param pageNumber 当前的页码
512     * @param pageSize   每页的数据量
513     * @param totalRow   数据总量
514     * @param condition  条件
515     */
516    public static Page<Row> paginate(String tableName, int pageNumber, int pageSize, int totalRow, QueryCondition condition) {
517        return invoker().paginate(tableName, new Page<>(pageNumber, pageSize, totalRow), QueryWrapper.create().where(condition));
518    }
519
520
521    /**
522     * 分页查询
523     *
524     * @param tableName    表名
525     * @param pageNumber   当前的页码
526     * @param pageSize     每页的数据量
527     * @param queryWrapper 条件
528     */
529    public static Page<Row> paginate(String tableName, int pageNumber, int pageSize, QueryWrapper queryWrapper) {
530        return invoker().paginate(tableName, new Page<>(pageNumber, pageSize), queryWrapper);
531    }
532
533
534    /**
535     * 分页查询
536     *
537     * @param tableName    表名
538     * @param pageNumber   当前的页码
539     * @param pageSize     每页的数据量
540     * @param totalRow     数据总量
541     * @param queryWrapper 条件
542     */
543    public static Page<Row> paginate(String tableName, int pageNumber, int pageSize, int totalRow, QueryWrapper queryWrapper) {
544        return invoker().paginate(tableName, new Page<>(pageNumber, pageSize, totalRow), queryWrapper);
545    }
546
547
548    /**
549     * 分页查询
550     *
551     * @param tableName    表名
552     * @param page         page 对象,若 page 有 totalCount 值,则不会再去查询分类的数据总量
553     * @param queryWrapper 条件
554     */
555    public static Page<Row> paginate(String tableName, Page<Row> page, QueryWrapper queryWrapper) {
556        return invoker().paginate(tableName, page, queryWrapper);
557    }
558
559
560    /**
561     * 进行事务操作
562     *
563     * @param supplier
564     */
565    public static boolean tx(Supplier<Boolean> supplier) {
566        return tx(supplier, Propagation.REQUIRED);
567    }
568
569
570    public static boolean tx(Supplier<Boolean> supplier, Propagation propagation) {
571        Boolean result = TransactionalManager.exec(supplier, propagation);
572        return result != null && result;
573    }
574}