唐耀东
2021-12-01 ac56d8fbfbe82096da31ed9f73bc29308284edfe
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
package com.ruoyi.common.core.mybatisplus.core;
 
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.ReflectionKit;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.page.PagePlus;
import com.ruoyi.common.utils.BeanCopyUtils;
import com.ruoyi.common.utils.reflect.ReflectUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
 
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
 
/**
 * IServicePlus 实现类
 *
 * @param <M> Mapper类
 * @param <T> 数据实体类
 * @param <V> vo类
 * @author Lion Li
 */
@Slf4j
@SuppressWarnings("unchecked")
public class ServicePlusImpl<M extends BaseMapperPlus<T>, T, V> extends ServiceImpl<M, T> implements IServicePlus<T, V> {
 
    @Autowired
    protected M baseMapper;
 
    @Override
    public M getBaseMapper() {
        return baseMapper;
    }
 
 
    protected Class<T> entityClass = currentModelClass();
 
    @Override
    public Class<T> getEntityClass() {
        return entityClass;
    }
 
    protected Class<M> mapperClass = currentMapperClass();
 
    protected Class<V> voClass = currentVoClass();
 
    public Class<V> getVoClass() {
        return voClass;
    }
 
    @Override
    protected Class<M> currentMapperClass() {
        return (Class<M>) ReflectionKit.getSuperClassGenericType(this.getClass(), ServicePlusImpl.class, 0);
    }
 
    @Override
    protected Class<T> currentModelClass() {
        return (Class<T>) ReflectionKit.getSuperClassGenericType(this.getClass(), ServicePlusImpl.class, 1);
    }
 
    protected Class<V> currentVoClass() {
        return (Class<V>) ReflectionKit.getSuperClassGenericType(this.getClass(), ServicePlusImpl.class, 2);
    }
 
    /**
     * 单条执行性能差 适用于列表对象内容不确定
     */
    @Override
    public boolean saveBatch(Collection<T> entityList, int batchSize) {
        return super.saveBatch(entityList, batchSize);
    }
 
    @Override
    public boolean saveOrUpdate(T entity) {
        return super.saveOrUpdate(entity);
    }
 
    /**
     * 单条执行性能差 适用于列表对象内容不确定
     */
    @Override
    public boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize) {
        return super.saveOrUpdateBatch(entityList, batchSize);
    }
 
    @Override
    public boolean updateBatchById(Collection<T> entityList, int batchSize) {
        return super.updateBatchById(entityList, batchSize);
    }
 
    /**
     * 单sql批量插入( 全量填充 无视数据库默认值 )
     * 适用于无脑插入
     */
    @Override
    public boolean saveBatch(Collection<T> entityList) {
        return saveBatch(entityList, DEFAULT_BATCH_SIZE);
    }
 
    @Override
    public boolean saveOrUpdateBatch(Collection<T> entityList) {
        return saveOrUpdateBatch(entityList, DEFAULT_BATCH_SIZE);
    }
 
    @Override
    public boolean updateBatchById(Collection<T> entityList) {
        return updateBatchById(entityList, DEFAULT_BATCH_SIZE);
    }
 
    /**
     * 单sql批量插入( 全量填充 )
     */
    @Override
    public boolean saveAll(Collection<T> entityList) {
        if (CollUtil.isEmpty(entityList)) {
            return false;
        }
        return baseMapper.insertAll(entityList) == entityList.size();
    }
 
    /**
     * 全量保存或更新 ( 按主键区分 )
     */
    @Override
    public boolean saveOrUpdateAll(Collection<T> entityList) {
        if (CollUtil.isEmpty(entityList)) {
            return false;
        }
        TableInfo tableInfo = TableInfoHelper.getTableInfo(entityClass);
        Assert.notNull(tableInfo, "error: can not execute. because can not find cache of TableInfo for entity!");
        String keyProperty = tableInfo.getKeyProperty();
        Assert.notEmpty(keyProperty, "error: can not execute. because can not find column for id from entity!");
        List<T> addList = new ArrayList<>();
        List<T> updateList = new ArrayList<>();
        int row = 0;
        for (T entity : entityList) {
            Object id = ReflectUtils.invokeGetter(entity, keyProperty);
            if (ObjectUtil.isNull(id)) {
                addList.add(entity);
            } else {
                updateList.add(entity);
            }
        }
        if (CollUtil.isNotEmpty(updateList) && updateBatchById(updateList)) {
            row += updateList.size();
        }
        if (CollUtil.isNotEmpty(addList)) {
            row += baseMapper.insertAll(addList);
        }
        return row == entityList.size();
    }
 
    /**
     * 根据 ID 查询
     *
     * @param id 主键ID
     */
    @Override
    public V getVoById(Serializable id, CopyOptions copyOptions) {
        T t = getBaseMapper().selectById(id);
        return BeanCopyUtils.oneCopy(t, copyOptions, voClass);
    }
 
    /**
     * 查询(根据ID 批量查询)
     *
     * @param idList 主键ID列表
     */
    @Override
    public List<V> listVoByIds(Collection<? extends Serializable> idList, CopyOptions copyOptions) {
        List<T> list = getBaseMapper().selectBatchIds(idList);
        if (list == null) {
            return null;
        }
        return BeanCopyUtils.listCopy(list, copyOptions, voClass);
    }
 
    /**
     * 查询(根据 columnMap 条件)
     *
     * @param columnMap 表字段 map 对象
     */
    @Override
    public List<V> listVoByMap(Map<String, Object> columnMap, CopyOptions copyOptions) {
        List<T> list = getBaseMapper().selectByMap(columnMap);
        if (list == null) {
            return null;
        }
        return BeanCopyUtils.listCopy(list, copyOptions, voClass);
    }
 
    /**
     * 根据 Wrapper,查询一条记录 <br/>
     * <p>结果集,如果是多个会抛出异常,随机取一条加上限制条件 wrapper.last("LIMIT 1")</p>
     *
     * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
     */
    @Override
    public V getVoOne(Wrapper<T> queryWrapper, CopyOptions copyOptions) {
        T t = getOne(queryWrapper, true);
        return BeanCopyUtils.oneCopy(t, copyOptions, voClass);
    }
 
    /**
     * 查询列表
     *
     * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
     */
    @Override
    public List<V> listVo(Wrapper<T> queryWrapper, CopyOptions copyOptions) {
        List<T> list = getBaseMapper().selectList(queryWrapper);
        if (list == null) {
            return null;
        }
        return BeanCopyUtils.listCopy(list, copyOptions, voClass);
    }
 
    /**
     * 翻页查询
     *
     * @param page         翻页对象
     * @param queryWrapper 实体对象封装操作类
     */
    @Override
    public PagePlus<T, V> pageVo(PagePlus<T, V> page, Wrapper<T> queryWrapper, CopyOptions copyOptions) {
        PagePlus<T, V> result = getBaseMapper().selectPage(page, queryWrapper);
        List<V> volist = BeanCopyUtils.listCopy(result.getRecords(), copyOptions, voClass);
        result.setRecordsVo(volist);
        return result;
    }
 
}