mirror of
https://gitee.com/orangeform/orange-admin.git
synced 2026-01-18 02:56:30 +08:00
同步1.9.0
This commit is contained in:
@@ -77,20 +77,23 @@
|
||||
<orderEntry type="library" name="Maven: com.alibaba:druid-spring-boot-starter:1.2.6" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.alibaba:druid:1.2.6" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.3.10.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-boot-starter:3.4.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.baomidou:mybatis-plus:3.4.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-extension:3.4.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-core:3.4.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-annotation:3.4.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: tk.mybatis:mapper-spring-boot-starter:2.1.5" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:2.3.10.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.zaxxer:HikariCP:3.4.5" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-jdbc:5.2.14.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-tx:5.2.14.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.mybatis:mybatis:3.4.6" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.mybatis:mybatis-spring:1.3.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: tk.mybatis:mapper-core:1.1.5" level="project" />
|
||||
<orderEntry type="library" name="Maven: javax.persistence:persistence-api:1.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: tk.mybatis:mapper-base:1.1.5" level="project" />
|
||||
<orderEntry type="library" name="Maven: tk.mybatis:mapper-weekend:1.1.5" level="project" />
|
||||
<orderEntry type="library" name="Maven: tk.mybatis:mapper-spring:1.1.5" level="project" />
|
||||
<orderEntry type="library" name="Maven: tk.mybatis:mapper-extra:1.1.5" level="project" />
|
||||
<orderEntry type="library" name="Maven: tk.mybatis:mapper-spring-boot-autoconfigure:2.1.5" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-starter:1.3.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-starter:2.1.3" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-autoconfigure:2.1.3" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.mybatis:mybatis:3.5.5" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.mybatis:mybatis-spring:2.0.5" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-autoconfigure:1.3.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper:5.2.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.github.jsqlparser:jsqlparser:3.2" level="project" />
|
||||
|
||||
@@ -97,9 +97,9 @@
|
||||
<version>${druid.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||
<version>${mybatisplus.version}</version>
|
||||
<groupId>tk.mybatis</groupId>
|
||||
<artifactId>mapper-spring-boot-starter</artifactId>
|
||||
<version>${mybatis-mapper.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.pagehelper</groupId>
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.orange.demo.common.core.annotation;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* 主要用于标记逻辑删除字段。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-08-08
|
||||
*/
|
||||
@Target({ElementType.FIELD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface DeletedFlagColumn {
|
||||
|
||||
}
|
||||
@@ -27,7 +27,7 @@ import java.util.Map;
|
||||
@Slf4j
|
||||
public class DataSourceResolveAspect {
|
||||
|
||||
private Map<Class<? extends DataSourceResolver>, DataSourceResolver> resolverMap = new HashMap<>();
|
||||
private final Map<Class<? extends DataSourceResolver>, DataSourceResolver> resolverMap = new HashMap<>();
|
||||
|
||||
/**
|
||||
* 所有配置MyDataSourceResovler注解的Service实现类。
|
||||
|
||||
@@ -10,8 +10,6 @@ import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 字典缓存同步的AOP。该AOP的优先级必须比事务切面的优先级高,因此会在事务外执行该切面的代码。
|
||||
*
|
||||
@@ -41,23 +39,23 @@ public class DictCacheSyncAspect {
|
||||
Object arg = joinPoint.getArgs()[0];
|
||||
if ("saveNew".equals(methodName)) {
|
||||
Object data = joinPoint.proceed();
|
||||
BaseDictService<Object, Serializable> service =
|
||||
(BaseDictService<Object, Serializable>) joinPoint.getTarget();
|
||||
BaseDictService<Object, Object> service =
|
||||
(BaseDictService<Object, Object>) joinPoint.getTarget();
|
||||
// 这里参数必须使用saveNew方法的返回对象,因为里面包含实际主键值。
|
||||
service.putDictionaryCache(data);
|
||||
return data;
|
||||
} else if ("update".equals(methodName)) {
|
||||
Object data = joinPoint.proceed();
|
||||
BaseDictService<Object, Serializable> service =
|
||||
(BaseDictService<Object, Serializable>) joinPoint.getTarget();
|
||||
BaseDictService<Object, Object> service =
|
||||
(BaseDictService<Object, Object>) joinPoint.getTarget();
|
||||
// update的方法返回的是boolean,因此这里的参数需要使用第一个参数即可。
|
||||
service.putDictionaryCache(arg);
|
||||
return data;
|
||||
} else {
|
||||
// remove
|
||||
BaseDictService<Object, Serializable> service =
|
||||
(BaseDictService<Object, Serializable>) joinPoint.getTarget();
|
||||
service.removeDictionaryCache((Serializable) arg);
|
||||
BaseDictService<Object, Object> service =
|
||||
(BaseDictService<Object, Object>) joinPoint.getTarget();
|
||||
service.removeDictionaryCache(arg);
|
||||
return joinPoint.proceed();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package com.orange.demo.common.core.base.controller;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.orange.demo.common.core.base.mapper.BaseModelMapper;
|
||||
import com.orange.demo.common.core.base.service.IBaseService;
|
||||
import com.orange.demo.common.core.constant.AggregationKind;
|
||||
@@ -19,7 +18,7 @@ import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.collections4.MapUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.Serializable;
|
||||
import javax.persistence.Id;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.util.LinkedList;
|
||||
@@ -38,7 +37,7 @@ import java.util.stream.Collectors;
|
||||
* @date 2020-08-08
|
||||
*/
|
||||
@Slf4j
|
||||
public abstract class BaseController<M, V, K extends Serializable> {
|
||||
public abstract class BaseController<M, V, K> {
|
||||
|
||||
/**
|
||||
* 当前Service关联的主Model实体对象的Class。
|
||||
@@ -69,7 +68,7 @@ public abstract class BaseController<M, V, K extends Serializable> {
|
||||
domainVoClass = (Class<V>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[1];
|
||||
Field[] fields = ReflectUtil.getFields(modelClass);
|
||||
for (Field field : fields) {
|
||||
if (null != field.getAnnotation(TableId.class)) {
|
||||
if (null != field.getAnnotation(Id.class)) {
|
||||
idFieldName = field.getName();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package com.orange.demo.common.core.base.dao;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
import tk.mybatis.mapper.additional.insert.InsertListMapper;
|
||||
import tk.mybatis.mapper.annotation.RegisterMapper;
|
||||
import tk.mybatis.mapper.common.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -14,7 +16,8 @@ import java.util.Map;
|
||||
* @author Jerry
|
||||
* @date 2020-08-08
|
||||
*/
|
||||
public interface BaseDaoMapper<M> extends BaseMapper<M> {
|
||||
@RegisterMapper
|
||||
public interface BaseDaoMapper<M> extends Mapper<M>, InsertListMapper<M> {
|
||||
|
||||
/**
|
||||
* 根据指定的表名、显示字段列表、过滤条件字符串和分组字段,返回聚合计算后的查询结果。
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.orange.demo.common.core.base.model;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
@@ -17,24 +17,24 @@ public class BaseModel {
|
||||
/**
|
||||
* 创建者Id。
|
||||
*/
|
||||
@TableField(value = "create_user_id")
|
||||
@Column(name = "create_user_id")
|
||||
private Long createUserId;
|
||||
|
||||
/**
|
||||
* 创建时间。
|
||||
*/
|
||||
@TableField(value = "create_time")
|
||||
@Column(name = "create_time")
|
||||
private Date createTime;
|
||||
|
||||
/**
|
||||
* 更新者Id。
|
||||
*/
|
||||
@TableField(value = "update_user_id")
|
||||
@Column(name = "update_user_id")
|
||||
private Long updateUserId;
|
||||
|
||||
/**
|
||||
* 更新时间。
|
||||
*/
|
||||
@TableField(value = "update_time")
|
||||
@Column(name = "update_time")
|
||||
private Date updateTime;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.orange.demo.common.core.base.service;
|
||||
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.orange.demo.common.core.constant.GlobalDeletedFlag;
|
||||
import com.orange.demo.common.core.exception.MyRuntimeException;
|
||||
import com.orange.demo.common.core.cache.DictionaryCache;
|
||||
@@ -9,8 +8,8 @@ import com.orange.demo.common.core.object.TokenData;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import tk.mybatis.mapper.entity.Example;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
@@ -23,7 +22,7 @@ import java.util.*;
|
||||
* @date 2020-08-08
|
||||
*/
|
||||
@Slf4j
|
||||
public abstract class BaseDictService<M, K extends Serializable> extends BaseService<M, K> implements IBaseDictService<M, K> {
|
||||
public abstract class BaseDictService<M, K> extends BaseService<M, K> implements IBaseDictService<M, K> {
|
||||
|
||||
/**
|
||||
* 缓存池对象。
|
||||
@@ -90,7 +89,15 @@ public abstract class BaseDictService<M, K extends Serializable> extends BaseSer
|
||||
if (tenantIdField != null) {
|
||||
ReflectUtil.setFieldValue(data, tenantIdField, TokenData.takeFromRequest().getTenantId());
|
||||
}
|
||||
return mapper().updateById(data) == 1;
|
||||
if (deletedFlagFieldName != null) {
|
||||
try {
|
||||
setDeletedFlagMethod.invoke(data, GlobalDeletedFlag.NORMAL);
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to call reflection [setDeletedFlagMethod] in BaseDictService.update.", e);
|
||||
throw new MyRuntimeException(e);
|
||||
}
|
||||
}
|
||||
return mapper().updateByPrimaryKey(data) == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -102,7 +109,7 @@ public abstract class BaseDictService<M, K extends Serializable> extends BaseSer
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public boolean remove(K id) {
|
||||
return mapper().deleteById(id) == 1;
|
||||
return this.removeById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -111,16 +118,15 @@ public abstract class BaseDictService<M, K extends Serializable> extends BaseSer
|
||||
* @param id 主键Id。
|
||||
* @return 主键关联的数据,不存在返回null。
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public M getById(Serializable id) {
|
||||
M data = dictionaryCache.get((K) id);
|
||||
public M getById(K id) {
|
||||
M data = dictionaryCache.get(id);
|
||||
if (data != null) {
|
||||
return data;
|
||||
}
|
||||
data = super.getById(id);
|
||||
if (data != null) {
|
||||
this.dictionaryCache.put((K) id, data);
|
||||
this.dictionaryCache.put(id, data);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
@@ -214,10 +220,8 @@ public abstract class BaseDictService<M, K extends Serializable> extends BaseSer
|
||||
List<M> dataList = this.getInList((Set<K>) inFilterValues);
|
||||
return dataList.size() == inFilterValues.size();
|
||||
}
|
||||
String columnName = this.safeMapToColumnName(inFilterField);
|
||||
QueryWrapper<M> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.in(columnName, inFilterValues);
|
||||
return mapper().selectCount(queryWrapper) == inFilterValues.size();
|
||||
Example e = this.makeDefaultInListExample(inFilterField, inFilterValues, null);
|
||||
return mapper().selectCountByExample(e) == inFilterValues.size();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
package com.orange.demo.common.core.base.service;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.orange.demo.common.core.annotation.*;
|
||||
@@ -13,7 +8,6 @@ import com.orange.demo.common.core.base.client.BaseClient;
|
||||
import com.orange.demo.common.core.constant.AggregationKind;
|
||||
import com.orange.demo.common.core.constant.AggregationType;
|
||||
import com.orange.demo.common.core.constant.GlobalDeletedFlag;
|
||||
import com.orange.demo.common.core.exception.InvalidDataFieldException;
|
||||
import com.orange.demo.common.core.exception.MyRuntimeException;
|
||||
import com.orange.demo.common.core.exception.RemoteDataBuildException;
|
||||
import com.orange.demo.common.core.object.*;
|
||||
@@ -27,14 +21,20 @@ import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.collections4.MapUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import tk.mybatis.mapper.entity.Example;
|
||||
|
||||
import java.io.Serializable;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Transient;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static java.util.stream.Collectors.*;
|
||||
|
||||
@@ -47,7 +47,7 @@ import static java.util.stream.Collectors.*;
|
||||
* @date 2020-08-08
|
||||
*/
|
||||
@Slf4j
|
||||
public abstract class BaseService<M, K extends Serializable> extends ServiceImpl<BaseDaoMapper<M>, M> implements IBaseService<M, K> {
|
||||
public abstract class BaseService<M, K> implements IBaseService<M, K> {
|
||||
/**
|
||||
* 当前Service关联的主Model实体对象的Class。
|
||||
*/
|
||||
@@ -156,11 +156,6 @@ public abstract class BaseService<M, K extends Serializable> extends ServiceImpl
|
||||
|
||||
private static final String AND_OP = " AND ";
|
||||
|
||||
@Override
|
||||
public BaseDaoMapper<M> getBaseMapper() {
|
||||
return mapper();
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造函数,在实例化的时候,一次性完成所有有关主Model对象信息的加载。
|
||||
*/
|
||||
@@ -168,7 +163,7 @@ public abstract class BaseService<M, K extends Serializable> extends ServiceImpl
|
||||
public BaseService() {
|
||||
modelClass = (Class<M>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
|
||||
idFieldClass = (Class<K>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[1];
|
||||
this.tableName = modelClass.getAnnotation(TableName.class).value();
|
||||
this.tableName = modelClass.getAnnotation(Table.class).name();
|
||||
Field[] fields = ReflectUtil.getFields(modelClass);
|
||||
for (Field field : fields) {
|
||||
initializeField(field);
|
||||
@@ -176,10 +171,10 @@ public abstract class BaseService<M, K extends Serializable> extends ServiceImpl
|
||||
}
|
||||
|
||||
private void initializeField(Field field) {
|
||||
if (idFieldName == null && null != field.getAnnotation(TableId.class)) {
|
||||
if (idFieldName == null && null != field.getAnnotation(Id.class)) {
|
||||
idFieldName = field.getName();
|
||||
TableId c = field.getAnnotation(TableId.class);
|
||||
idColumnName = c == null ? idFieldName : c.value();
|
||||
Column c = field.getAnnotation(Column.class);
|
||||
idColumnName = c == null ? idFieldName : c.name();
|
||||
setIdFieldMethod = ReflectUtil.getMethod(
|
||||
modelClass, "set" + StringUtils.capitalize(idFieldName), idFieldClass);
|
||||
getIdFieldMethod = ReflectUtil.getMethod(
|
||||
@@ -187,18 +182,21 @@ public abstract class BaseService<M, K extends Serializable> extends ServiceImpl
|
||||
}
|
||||
if (updateTimeFieldName == null && null != field.getAnnotation(JobUpdateTimeColumn.class)) {
|
||||
updateTimeFieldName = field.getName();
|
||||
updateTimeColumnName = this.safeMapToColumnName(updateTimeFieldName);
|
||||
Column c = field.getAnnotation(Column.class);
|
||||
updateTimeColumnName = c == null ? updateTimeFieldName : c.name();
|
||||
}
|
||||
if (deletedFlagFieldName == null && null != field.getAnnotation(TableLogic.class)) {
|
||||
if (deletedFlagFieldName == null && null != field.getAnnotation(DeletedFlagColumn.class)) {
|
||||
deletedFlagFieldName = field.getName();
|
||||
deletedFlagColumnName = this.safeMapToColumnName(deletedFlagFieldName);
|
||||
Column c = field.getAnnotation(Column.class);
|
||||
deletedFlagColumnName = c == null ? deletedFlagFieldName : c.name();
|
||||
setDeletedFlagMethod = ReflectUtil.getMethod(
|
||||
modelClass, "set" + StringUtils.capitalize(deletedFlagFieldName), Integer.class);
|
||||
}
|
||||
if (tenantIdFieldName == null && null != field.getAnnotation(TenantFilterColumn.class)) {
|
||||
tenantIdField = field;
|
||||
tenantIdFieldName = field.getName();
|
||||
tenantIdColumnName = this.safeMapToColumnName(tenantIdFieldName);
|
||||
Column c = field.getAnnotation(Column.class);
|
||||
tenantIdColumnName = c == null ? tenantIdFieldName : c.name();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,6 +219,31 @@ public abstract class BaseService<M, K extends Serializable> extends ServiceImpl
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 基于主键Id删除数据。如果包含逻辑删除字段,则进行逻辑删除。
|
||||
*
|
||||
* @param id 主键Id值。
|
||||
* @return true删除成功,false数据不存在。
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public boolean removeById(K id) {
|
||||
if (this.deletedFlagFieldName == null) {
|
||||
return mapper().deleteByPrimaryKey(id) == 1;
|
||||
}
|
||||
try {
|
||||
Example e = new Example(modelClass);
|
||||
Example.Criteria c = e.createCriteria().andEqualTo(idFieldName, id);
|
||||
c.andEqualTo(deletedFlagFieldName, GlobalDeletedFlag.NORMAL);
|
||||
M data = modelClass.newInstance();
|
||||
setDeletedFlagMethod.invoke(data, GlobalDeletedFlag.DELETED);
|
||||
return mapper().updateByExampleSelective(data, e) == 1;
|
||||
} catch (Exception ex) {
|
||||
log.error("Failed to call reflection method in BaseService.removeById.", ex);
|
||||
throw new MyRuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据过滤条件删除数据。
|
||||
*
|
||||
@@ -230,7 +253,25 @@ public abstract class BaseService<M, K extends Serializable> extends ServiceImpl
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public Integer removeBy(M filter) {
|
||||
return mapper().delete(new QueryWrapper<>(filter));
|
||||
if (deletedFlagFieldName == null) {
|
||||
return mapper().delete(filter);
|
||||
}
|
||||
Example e = new Example(modelClass);
|
||||
Example.Criteria c = e.createCriteria();
|
||||
Field[] fields = ReflectUtil.getFields(modelClass);
|
||||
for (Field field : fields) {
|
||||
if (field.getAnnotation(Transient.class) == null) {
|
||||
this.assembleCriteriaByFilter(filter, field, c);
|
||||
}
|
||||
}
|
||||
try {
|
||||
M deletedObject = modelClass.newInstance();
|
||||
this.setDeletedFlagMethod.invoke(deletedObject, GlobalDeletedFlag.DELETED);
|
||||
return mapper().updateByExampleSelective(deletedObject, e);
|
||||
} catch (Exception ex) {
|
||||
log.error("Failed to call reflection method in BaseService.removeBy.", ex);
|
||||
throw new MyRuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -258,8 +299,27 @@ public abstract class BaseService<M, K extends Serializable> extends ServiceImpl
|
||||
if (fieldName.equals(this.idFieldName)) {
|
||||
return this.existId((K) fieldValue);
|
||||
}
|
||||
String columnName = MyModelUtil.mapToColumnName(fieldName, modelClass);
|
||||
return mapper().selectCount(new QueryWrapper<M>().eq(columnName, fieldValue)) == 1;
|
||||
Example e = new Example(modelClass);
|
||||
e.createCriteria().andEqualTo(fieldName, fieldValue);
|
||||
return mapper().selectCountByExample(e) == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取主键Id关联的数据。
|
||||
*
|
||||
* @param id 主键Id
|
||||
* @return 主键关联的数据,不存在返回null。
|
||||
*/
|
||||
@Override
|
||||
public M getById(K id) {
|
||||
if (deletedFlagFieldName == null) {
|
||||
return mapper().selectByPrimaryKey(id);
|
||||
}
|
||||
Example e = new Example(modelClass);
|
||||
e.createCriteria()
|
||||
.andEqualTo(idFieldName, id)
|
||||
.andEqualTo(deletedFlagFieldName, GlobalDeletedFlag.NORMAL);
|
||||
return mapper().selectOneByExample(e);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -275,9 +335,12 @@ public abstract class BaseService<M, K extends Serializable> extends ServiceImpl
|
||||
if (filterField.equals(idFieldName)) {
|
||||
return this.getById((K) filterValue);
|
||||
}
|
||||
String columnName = this.safeMapToColumnName(filterField);
|
||||
QueryWrapper<M> queryWrapper = new QueryWrapper<M>().eq(columnName, filterValue);
|
||||
return mapper().selectOne(queryWrapper);
|
||||
Example e = new Example(modelClass);
|
||||
Example.Criteria c = e.createCriteria().andEqualTo(filterField, filterValue);
|
||||
if (deletedFlagFieldName != null) {
|
||||
c.andEqualTo(deletedFlagFieldName, GlobalDeletedFlag.NORMAL);
|
||||
}
|
||||
return mapper().selectOneByExample(e);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -302,7 +365,12 @@ public abstract class BaseService<M, K extends Serializable> extends ServiceImpl
|
||||
*/
|
||||
@Override
|
||||
public List<M> getAllList() {
|
||||
return mapper().selectList(Wrappers.emptyWrapper());
|
||||
if (deletedFlagFieldName == null) {
|
||||
return mapper().selectAll();
|
||||
}
|
||||
Example e = new Example(modelClass);
|
||||
e.createCriteria().andEqualTo(deletedFlagFieldName, GlobalDeletedFlag.NORMAL);
|
||||
return mapper().selectByExample(e);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -313,11 +381,14 @@ public abstract class BaseService<M, K extends Serializable> extends ServiceImpl
|
||||
*/
|
||||
@Override
|
||||
public List<M> getAllListByOrder(String... orderByProperties) {
|
||||
String[] columns = new String[orderByProperties.length];
|
||||
for (int i = 0; i < orderByProperties.length; i++) {
|
||||
columns[i] = this.safeMapToColumnName(orderByProperties[i]);
|
||||
Example e = new Example(modelClass);
|
||||
for (String orderByProperty : orderByProperties) {
|
||||
e.orderBy(orderByProperty);
|
||||
}
|
||||
return mapper().selectList(new QueryWrapper<M>().orderByAsc(columns));
|
||||
if (deletedFlagFieldName != null) {
|
||||
e.and().andEqualTo(deletedFlagFieldName, GlobalDeletedFlag.NORMAL);
|
||||
}
|
||||
return mapper().selectByExample(e);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -346,8 +417,8 @@ public abstract class BaseService<M, K extends Serializable> extends ServiceImpl
|
||||
if (CollectionUtils.isEmpty(inFilterValues)) {
|
||||
return true;
|
||||
}
|
||||
String column = this.safeMapToColumnName(inFilterField);
|
||||
return mapper().selectCount(new QueryWrapper<M>().in(column, inFilterValues)) == inFilterValues.size();
|
||||
Example e = this.makeDefaultInListExample(inFilterField, inFilterValues, null);
|
||||
return mapper().selectCountByExample(e) == inFilterValues.size();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -386,12 +457,8 @@ public abstract class BaseService<M, K extends Serializable> extends ServiceImpl
|
||||
if (CollectionUtils.isEmpty(inFilterValues)) {
|
||||
return new LinkedList<>();
|
||||
}
|
||||
String column = this.safeMapToColumnName(inFilterField);
|
||||
QueryWrapper<M> queryWrapper = new QueryWrapper<M>().in(column, inFilterValues);
|
||||
if (StringUtils.isNotBlank(orderBy)) {
|
||||
queryWrapper.last(orderBy);
|
||||
}
|
||||
return mapper().selectList(queryWrapper);
|
||||
Example e = this.makeDefaultInListExample(inFilterField, inFilterValues, orderBy);
|
||||
return mapper().selectByExample(e);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -402,7 +469,16 @@ public abstract class BaseService<M, K extends Serializable> extends ServiceImpl
|
||||
*/
|
||||
@Override
|
||||
public int getCountByFilter(M filter) {
|
||||
return mapper().selectCount(new QueryWrapper<>(filter));
|
||||
if (deletedFlagFieldName == null) {
|
||||
return mapper().selectCount(filter);
|
||||
}
|
||||
try {
|
||||
setDeletedFlagMethod.invoke(filter, GlobalDeletedFlag.NORMAL);
|
||||
return mapper().selectCount(filter);
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to call reflection [setDeletedFlagMethod] in BaseService.getCountByFilter.", e);
|
||||
throw new MyRuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -424,7 +500,42 @@ public abstract class BaseService<M, K extends Serializable> extends ServiceImpl
|
||||
*/
|
||||
@Override
|
||||
public List<M> getListByFilter(M filter) {
|
||||
return mapper().selectList(new QueryWrapper<>(filter));
|
||||
if (filter == null) {
|
||||
return this.getAllList();
|
||||
}
|
||||
if (deletedFlagFieldName == null) {
|
||||
return mapper().select(filter);
|
||||
}
|
||||
try {
|
||||
setDeletedFlagMethod.invoke(filter, GlobalDeletedFlag.NORMAL);
|
||||
return mapper().select(filter);
|
||||
} catch (Exception ex) {
|
||||
log.error("Failed to call reflection code of BaseService.getListByFilter.", ex);
|
||||
throw new MyRuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void assembleCriteriaByFilter(M filter, Field field, Example.Criteria c) {
|
||||
int modifiers = field.getModifiers();
|
||||
// transient类型的字段不能作为查询条件
|
||||
int transientMask = 128;
|
||||
if ((modifiers & transientMask) != 0 || Modifier.isStatic(modifiers)) {
|
||||
return;
|
||||
}
|
||||
if (field.getName().equals(deletedFlagFieldName)) {
|
||||
c.andEqualTo(deletedFlagFieldName, GlobalDeletedFlag.NORMAL);
|
||||
} else {
|
||||
ReflectUtil.setAccessible(field);
|
||||
try {
|
||||
Object o = field.get(filter);
|
||||
if (o != null) {
|
||||
c.andEqualTo(field.getName(), field.get(filter));
|
||||
}
|
||||
} catch (IllegalAccessException ex) {
|
||||
log.error("Failed to call reflection code of BaseService.getListByFilter.", ex);
|
||||
throw new MyRuntimeException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -436,14 +547,17 @@ public abstract class BaseService<M, K extends Serializable> extends ServiceImpl
|
||||
*/
|
||||
@Override
|
||||
public List<M> getListByParentId(String parentIdFieldName, K parentId) {
|
||||
QueryWrapper<M> queryWrapper = new QueryWrapper<>();
|
||||
String parentIdColumn = this.safeMapToColumnName(parentIdFieldName);
|
||||
Example e = new Example(modelClass);
|
||||
Example.Criteria c = e.createCriteria();
|
||||
if (parentId != null) {
|
||||
queryWrapper.eq(parentIdColumn, parentId);
|
||||
c.andEqualTo(parentIdFieldName, parentId);
|
||||
} else {
|
||||
queryWrapper.isNull(parentIdColumn);
|
||||
c.andIsNull(parentIdFieldName);
|
||||
}
|
||||
return mapper().selectList(queryWrapper);
|
||||
if (deletedFlagFieldName != null) {
|
||||
c.andEqualTo(deletedFlagFieldName, GlobalDeletedFlag.NORMAL);
|
||||
}
|
||||
return mapper().selectByExample(e);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -473,21 +587,32 @@ public abstract class BaseService<M, K extends Serializable> extends ServiceImpl
|
||||
*/
|
||||
@Override
|
||||
public List<M> getListByCondition(List<String> selectList, M filter, String whereClause, String orderBy) {
|
||||
QueryWrapper<M> queryWrapper = new QueryWrapper<>(filter);
|
||||
Example e = new Example(modelClass);
|
||||
Example.Criteria c = null;
|
||||
if (CollectionUtils.isNotEmpty(selectList)) {
|
||||
String[] columns = new String[selectList.size()];
|
||||
for (int i = 0; i < selectList.size(); i++) {
|
||||
columns[i] = this.safeMapToColumnName(selectList.get(i));
|
||||
}
|
||||
queryWrapper.select(columns);
|
||||
}
|
||||
if (StringUtils.isNotBlank(whereClause)) {
|
||||
queryWrapper.apply(whereClause);
|
||||
String[] selectFields = new String[selectList.size()];
|
||||
selectList.toArray(selectFields);
|
||||
e.selectProperties(selectFields);
|
||||
}
|
||||
if (StringUtils.isNotBlank(orderBy)) {
|
||||
queryWrapper.last(" ORDER BY " + orderBy);
|
||||
e.setOrderByClause(orderBy);
|
||||
}
|
||||
return mapper().selectList(queryWrapper);
|
||||
if (filter != null) {
|
||||
c = e.createCriteria();
|
||||
Field[] fields = ReflectUtil.getFields(modelClass);
|
||||
for (Field field : fields) {
|
||||
if (field.getAnnotation(Transient.class) == null) {
|
||||
this.assembleCriteriaByFilter(filter, field, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (StringUtils.isNotBlank(whereClause)) {
|
||||
if (c == null) {
|
||||
c = e.createCriteria();
|
||||
}
|
||||
c.andCondition(whereClause);
|
||||
}
|
||||
return mapper().selectByExample(e);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -592,7 +717,7 @@ public abstract class BaseService<M, K extends Serializable> extends ServiceImpl
|
||||
*
|
||||
* @param resultList 主表实体对象列表。数据集成将直接作用于该对象列表。
|
||||
* @param relationParam 实体对象数据组装的参数构建器。
|
||||
* @param batchSize 每批集成的记录数量。小于等于时将不做分批处理。
|
||||
* @param batchSize 每批集成的记录数量。小于等于0时将不做分批处理。
|
||||
*/
|
||||
@Override
|
||||
public void buildRelationForDataList(List<M> resultList, MyRelationParam relationParam, int batchSize) {
|
||||
@@ -613,7 +738,7 @@ public abstract class BaseService<M, K extends Serializable> extends ServiceImpl
|
||||
*
|
||||
* @param resultList 主表实体对象列表。数据集成将直接作用于该对象列表。
|
||||
* @param relationParam 实体对象数据组装的参数构建器。
|
||||
* @param batchSize 每批集成的记录数量。小于等于时将不做分批处理。
|
||||
* @param batchSize 每批集成的记录数量。小于等于0时将不做分批处理。
|
||||
* @param ignoreFields 该集合中的字段,即便包含注解也不会在当前调用中进行数据组装。
|
||||
*/
|
||||
@Override
|
||||
@@ -786,10 +911,9 @@ public abstract class BaseService<M, K extends Serializable> extends ServiceImpl
|
||||
continue;
|
||||
}
|
||||
Object masterIdValue = ReflectUtil.getFieldValue(dataObject, relationStruct.masterIdField);
|
||||
String masterIdColumn = this.safeMapToColumnName(relationStruct.masterIdField.getName());
|
||||
Map<String, Object> filterMap = new HashMap<>(1);
|
||||
filterMap.put(masterIdColumn, masterIdValue);
|
||||
List<?> manyToManyList = relationStruct.manyToManyMapper.selectByMap(filterMap);
|
||||
Example e = new Example(relationStruct.relationManyToMany.relationModelClass());
|
||||
e.createCriteria().andEqualTo(relationStruct.masterIdField.getName(), masterIdValue);
|
||||
List<?> manyToManyList = relationStruct.manyToManyMapper.selectByExample(e);
|
||||
ReflectUtil.setFieldValue(dataObject, relationStruct.relationField, manyToManyList);
|
||||
}
|
||||
}
|
||||
@@ -1180,7 +1304,7 @@ public abstract class BaseService<M, K extends Serializable> extends ServiceImpl
|
||||
if (CollectionUtils.isEmpty(masterIdSet)) {
|
||||
continue;
|
||||
}
|
||||
BaseService<Object, Serializable> relationService = relationStruct.localService;
|
||||
BaseService<Object, Object> relationService = relationStruct.localService;
|
||||
List<Object> relationList =
|
||||
relationService.getInList(relationStruct.relationOneToOne.slaveIdField(), masterIdSet);
|
||||
MyModelUtil.makeOneToOneRelation(
|
||||
@@ -1189,8 +1313,8 @@ public abstract class BaseService<M, K extends Serializable> extends ServiceImpl
|
||||
if (withDict && relationStruct.relationOneToOne.loadSlaveDict()
|
||||
&& CollectionUtils.isNotEmpty(relationList)) {
|
||||
@SuppressWarnings("unchecked")
|
||||
BaseService<Object, Serializable> proxyTarget =
|
||||
(BaseService<Object, Serializable>) AopTargetUtil.getTarget(relationService);
|
||||
BaseService<Object, Object> proxyTarget =
|
||||
(BaseService<Object, Object>) AopTargetUtil.getTarget(relationService);
|
||||
// 关联常量字典
|
||||
proxyTarget.buildConstDictForDataList(relationList, ignoreFields);
|
||||
// 关联本地字典。
|
||||
@@ -1219,14 +1343,14 @@ public abstract class BaseService<M, K extends Serializable> extends ServiceImpl
|
||||
}
|
||||
Object id = ReflectUtil.getFieldValue(dataObject, relationStruct.masterIdField);
|
||||
if (id != null) {
|
||||
BaseService<Object, Serializable> relationService = relationStruct.localService;
|
||||
BaseService<Object, Object> relationService = relationStruct.localService;
|
||||
Object relationObject = relationService.getOne(relationStruct.relationOneToOne.slaveIdField(), id);
|
||||
ReflectUtil.setFieldValue(dataObject, relationStruct.relationField, relationObject);
|
||||
// 仅仅当需要加载从表字典关联时,才去加载。
|
||||
if (withDict && relationStruct.relationOneToOne.loadSlaveDict() && relationObject != null) {
|
||||
@SuppressWarnings("unchecked")
|
||||
BaseService<Object, Serializable> proxyTarget =
|
||||
(BaseService<Object, Serializable>) AopTargetUtil.getTarget(relationService);
|
||||
BaseService<Object, Object> proxyTarget =
|
||||
(BaseService<Object, Object>) AopTargetUtil.getTarget(relationService);
|
||||
// 关联常量字典
|
||||
proxyTarget.buildConstDictForData(relationObject, ignoreFields);
|
||||
// 关联本地字典。
|
||||
@@ -1258,7 +1382,7 @@ public abstract class BaseService<M, K extends Serializable> extends ServiceImpl
|
||||
.collect(toSet());
|
||||
// 从主表集合中,抽取主表关联字段的集合,再以in list形式去从表中查询。
|
||||
if (CollectionUtils.isNotEmpty(masterIdSet)) {
|
||||
BaseService<Object, Serializable> relationService = relationStruct.localService;
|
||||
BaseService<Object, Object> relationService = relationStruct.localService;
|
||||
List<Object> relationList =
|
||||
relationService.getInList(relationStruct.relationOneToMany.slaveIdField(), masterIdSet);
|
||||
MyModelUtil.makeOneToManyRelation(
|
||||
@@ -1283,7 +1407,7 @@ public abstract class BaseService<M, K extends Serializable> extends ServiceImpl
|
||||
}
|
||||
Object id = ReflectUtil.getFieldValue(dataObject, relationStruct.masterIdField);
|
||||
if (id != null) {
|
||||
BaseService<Object, Serializable> relationService = relationStruct.localService;
|
||||
BaseService<Object, Object> relationService = relationStruct.localService;
|
||||
Set<Object> masterIdSet = new HashSet<>(1);
|
||||
masterIdSet.add(id);
|
||||
List<Object> relationObject = relationService.getInList(
|
||||
@@ -1611,6 +1735,23 @@ public abstract class BaseService<M, K extends Serializable> extends ServiceImpl
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void saveInternal(List<M> dataList, Supplier<K> idGenerator, Consumer<List<M>> batchInserter) {
|
||||
if (CollectionUtils.isEmpty(dataList)) {
|
||||
return;
|
||||
}
|
||||
dataList.stream().filter(c -> ReflectUtil.getFieldValue(c, idFieldName) == null)
|
||||
.forEach(o -> ReflectUtil.setFieldValue(o, idFieldName, idGenerator.get()));
|
||||
if (batchInserter != null) {
|
||||
batchInserter.accept(dataList);
|
||||
} else {
|
||||
for (M data : dataList) {
|
||||
mapper().insert(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 缺省实现返回null,在进行一对多和多对多聚合计算时,没有额外的自定义过滤条件。如有需要,需子类自行实现。
|
||||
*
|
||||
@@ -1658,97 +1799,32 @@ public abstract class BaseService<M, K extends Serializable> extends ServiceImpl
|
||||
}
|
||||
|
||||
/**
|
||||
* 因为Mybatis Plus中QueryWrapper的条件方法都要求传入数据表字段名,因此提供该函数将
|
||||
* Java实体对象的字段名转换为数据表字段名,如果不存在会抛出异常。
|
||||
* 另外在MyModelUtil.mapToColumnName有一级缓存,对于查询过的对象字段都会放到缓存中,
|
||||
* 下次映射转换的时候,会直接从缓存获取。
|
||||
* 通过(In-list)条件和orderBy条件,构建Example对象,以供后续的查询操作使用。
|
||||
*
|
||||
* @param fieldName Java实体对象的字段名。
|
||||
* @return 对应的数据表字段名。
|
||||
* @param inFilterField 参与(In-list)过滤的Java字段。
|
||||
* @param inFilterValues 参与(In-list)过滤的字段值集合。
|
||||
* @param orderBy 排序字段。
|
||||
* @param <T> in 属性字段的类型。
|
||||
* @return 构建后的Example对象。
|
||||
*/
|
||||
protected String safeMapToColumnName(String fieldName) {
|
||||
String columnName = MyModelUtil.mapToColumnName(fieldName, modelClass);
|
||||
if (columnName == null) {
|
||||
throw new InvalidDataFieldException(modelClass.getSimpleName(), fieldName);
|
||||
protected <T> Example makeDefaultInListExample(String inFilterField, Collection<T> inFilterValues, String orderBy) {
|
||||
Set<T> inFilterValueSet;
|
||||
Example e = new Example(modelClass);
|
||||
if (StringUtils.isNotBlank(orderBy)) {
|
||||
e.setOrderByClause(orderBy);
|
||||
}
|
||||
return columnName;
|
||||
}
|
||||
|
||||
/**
|
||||
* 因为Mybatis Plus在update的时候,不能将实体对象中值为null的字段,更新为null,
|
||||
* 而且忽略更新,在全部更新场景下,这个是非常重要的,所以我们写了这个函数绕开这一问题。
|
||||
* 该函数会遍历实体对象中,所有不包含@Transient注解,没有transient修饰符的字段,如果
|
||||
* 当前对象的该字段值为null,则会调用UpdateWrapper的set方法,将该字段赋值为null。
|
||||
* 相比于其他重载方法,该方法会将参数中的主键id,设置到UpdateWrapper的过滤条件中。
|
||||
*
|
||||
* @param o 实体对象。
|
||||
* @param id 实体对象的主键值。
|
||||
* @return 创建后的UpdateWrapper。
|
||||
*/
|
||||
protected UpdateWrapper<M> createUpdateQueryForNullValue(M o, K id) {
|
||||
UpdateWrapper<M> uw = createUpdateQueryForNullValue(o, modelClass);
|
||||
try {
|
||||
M filter = modelClass.newInstance();
|
||||
this.setIdFieldMethod.invoke(filter, id);
|
||||
uw.setEntity(filter);
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to call reflection code of BaseService.createUpdateQueryForNullValue.", e);
|
||||
throw new MyRuntimeException(e);
|
||||
if (inFilterValues instanceof Set) {
|
||||
inFilterValueSet = (Set<T>) inFilterValues;
|
||||
} else {
|
||||
inFilterValueSet = new HashSet<>(inFilterValues.size());
|
||||
inFilterValueSet.addAll(inFilterValues);
|
||||
}
|
||||
return uw;
|
||||
}
|
||||
|
||||
/**
|
||||
* 因为Mybatis Plus在update的时候,不能将实体对象中值为null的字段,更新为null,
|
||||
* 而且忽略更新,在全部更新场景下,这个是非常重要的,所以我们写了这个函数绕开这一问题。
|
||||
* 该函数会遍历实体对象中,所有不包含@Transient注解,没有transient修饰符的字段,如果
|
||||
* 当前对象的该字段值为null,则会调用UpdateWrapper的set方法,将该字段赋值为null。
|
||||
*
|
||||
* @param o 实体对象。
|
||||
* @return 创建后的UpdateWrapper。
|
||||
*/
|
||||
protected UpdateWrapper<M> createUpdateQueryForNullValue(M o) {
|
||||
return createUpdateQueryForNullValue(o, modelClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* 因为Mybatis Plus在update的时候,不能将实体对象中值为null的字段,更新为null,
|
||||
* 而且忽略更新,在全部更新场景下,这个是非常重要的,所以我们写了这个函数绕开这一问题。
|
||||
* 该函数会遍历实体对象中,所有不包含@Transient注解,没有transient修饰符的字段,如果
|
||||
* 当前对象的该字段值为null,则会调用UpdateWrapper的set方法,将该字段赋值为null。
|
||||
*
|
||||
* @param o 实体对象。
|
||||
* @param clazz 实体对象的class。
|
||||
* @return 创建后的UpdateWrapper。
|
||||
*/
|
||||
public static <T> UpdateWrapper<T> createUpdateQueryForNullValue(T o, Class<T> clazz) {
|
||||
UpdateWrapper<T> uw = new UpdateWrapper<>();
|
||||
Field[] fields = ReflectUtil.getFields(clazz);
|
||||
List<String> nullColumnList = new LinkedList<>();
|
||||
for (Field field : fields) {
|
||||
TableField tableField = field.getAnnotation(TableField.class);
|
||||
if (tableField == null || tableField.exist()) {
|
||||
int modifiers = field.getModifiers();
|
||||
// transient类型的字段不能作为查询条件,静态字段和逻辑删除都不考虑。
|
||||
int transientMask = 128;
|
||||
if ((modifiers & transientMask) == 1
|
||||
|| Modifier.isStatic(modifiers)
|
||||
|| field.getAnnotation(TableLogic.class) != null) {
|
||||
continue;
|
||||
}
|
||||
// 仅当实体对象参数中,当前字段值为null的时候,才会赋值给UpdateWrapper。
|
||||
// 以便在后续的更新中,可以将这些null字段的值设置到数据库表对应的字段中。
|
||||
if (ReflectUtil.getFieldValue(o, field) == null) {
|
||||
nullColumnList.add(MyModelUtil.safeMapToColumnName(field.getName(), clazz));
|
||||
}
|
||||
}
|
||||
Example.Criteria c = e.createCriteria();
|
||||
c.andIn(inFilterField, inFilterValueSet);
|
||||
if (deletedFlagFieldName != null) {
|
||||
c.andEqualTo(deletedFlagFieldName, GlobalDeletedFlag.NORMAL);
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(nullColumnList)) {
|
||||
for (String nullColumn : nullColumnList) {
|
||||
uw.set(nullColumn, null);
|
||||
}
|
||||
}
|
||||
return uw;
|
||||
return e;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -1838,7 +1914,7 @@ public abstract class BaseService<M, K extends Serializable> extends ServiceImpl
|
||||
relationStruct.localService = ApplicationContextHolder.getBean(
|
||||
StringUtils.uncapitalize(relationOneToOne.slaveServiceName()));
|
||||
} else {
|
||||
relationStruct.localService = (BaseService<Object, Serializable>)
|
||||
relationStruct.localService = (BaseService<Object, Object>)
|
||||
ApplicationContextHolder.getBean(relationOneToOne.slaveServiceClass());
|
||||
}
|
||||
localRelationOneToOneStructList.add(relationStruct);
|
||||
@@ -1854,7 +1930,7 @@ public abstract class BaseService<M, K extends Serializable> extends ServiceImpl
|
||||
relationStruct.localService = ApplicationContextHolder.getBean(
|
||||
StringUtils.uncapitalize(relationOneToMany.slaveServiceName()));
|
||||
} else {
|
||||
relationStruct.localService = (BaseService<Object, Serializable>)
|
||||
relationStruct.localService = (BaseService<Object, Object>)
|
||||
ApplicationContextHolder.getBean(relationOneToMany.slaveServiceClass());
|
||||
}
|
||||
localRelationOneToManyStructList.add(relationStruct);
|
||||
@@ -1901,7 +1977,7 @@ public abstract class BaseService<M, K extends Serializable> extends ServiceImpl
|
||||
relationStruct.localService =
|
||||
ApplicationContextHolder.getBean(StringUtils.uncapitalize(relationDict.slaveServiceName()));
|
||||
} else {
|
||||
relationStruct.localService = (BaseService<Object, Serializable>)
|
||||
relationStruct.localService = (BaseService<Object, Object>)
|
||||
ApplicationContextHolder.getBean(relationDict.slaveServiceClass());
|
||||
}
|
||||
localRelationDictStructList.add(relationStruct);
|
||||
@@ -1923,7 +1999,7 @@ public abstract class BaseService<M, K extends Serializable> extends ServiceImpl
|
||||
relationStruct.localService = ApplicationContextHolder.getBean(
|
||||
StringUtils.uncapitalize(relationOneToManyAggregation.slaveServiceName()));
|
||||
} else {
|
||||
relationStruct.localService = (BaseService<Object, Serializable>)
|
||||
relationStruct.localService = (BaseService<Object, Object>)
|
||||
ApplicationContextHolder.getBean(relationOneToManyAggregation.slaveServiceClass());
|
||||
}
|
||||
localRelationOneToManyAggrStructList.add(relationStruct);
|
||||
@@ -1942,7 +2018,7 @@ public abstract class BaseService<M, K extends Serializable> extends ServiceImpl
|
||||
relationStruct.localService = ApplicationContextHolder.getBean(
|
||||
StringUtils.uncapitalize(relationManyToManyAggregation.slaveServiceName()));
|
||||
} else {
|
||||
relationStruct.localService = (BaseService<Object, Serializable>)
|
||||
relationStruct.localService = (BaseService<Object, Object>)
|
||||
ApplicationContextHolder.getBean(relationManyToManyAggregation.slaveServiceClass());
|
||||
}
|
||||
localRelationManyToManyAggrStructList.add(relationStruct);
|
||||
@@ -2335,7 +2411,7 @@ public abstract class BaseService<M, K extends Serializable> extends ServiceImpl
|
||||
|
||||
static class LocalRelationStruct extends RelationStruct {
|
||||
private Field equalOneToOneRelationField;
|
||||
private BaseService<Object, Serializable> localService;
|
||||
private BaseService<Object, Object> localService;
|
||||
private BaseDaoMapper<Object> manyToManyMapper;
|
||||
private Map<Object, String> dictMap;
|
||||
private RelationDict relationDict;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.orange.demo.common.core.base.service;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -11,7 +10,7 @@ import java.util.List;
|
||||
* @author Jerry
|
||||
* @date 2020-08-08
|
||||
*/
|
||||
public interface IBaseDictService<M, K extends Serializable> extends IBaseService<M, K> {
|
||||
public interface IBaseDictService<M, K> extends IBaseService<M, K> {
|
||||
|
||||
/**
|
||||
* 重新加载数据库中所有当前表数据到系统内存。
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package com.orange.demo.common.core.base.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.orange.demo.common.core.object.MyRelationParam;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* 所有Service的接口。
|
||||
@@ -14,7 +14,15 @@ import java.util.*;
|
||||
* @author Jerry
|
||||
* @date 2020-08-08
|
||||
*/
|
||||
public interface IBaseService<M, K extends Serializable> extends IService<M>{
|
||||
public interface IBaseService<M, K> {
|
||||
|
||||
/**
|
||||
* 基于主键Id删除数据。如果包含逻辑删除字段,则进行逻辑删除。
|
||||
*
|
||||
* @param id 主键Id值。
|
||||
* @return true删除成功,false数据不存在。
|
||||
*/
|
||||
boolean removeById(K id);
|
||||
|
||||
/**
|
||||
* 根据过滤条件删除数据。
|
||||
@@ -42,6 +50,14 @@ public interface IBaseService<M, K extends Serializable> extends IService<M>{
|
||||
*/
|
||||
boolean existId(K id);
|
||||
|
||||
/**
|
||||
* 获取主键Id关联的数据。
|
||||
*
|
||||
* @param id 主键Id。
|
||||
* @return 主键关联的数据,不存在返回null。
|
||||
*/
|
||||
M getById(K id);
|
||||
|
||||
/**
|
||||
* 返回符合 filterField = filterValue 条件的一条数据。
|
||||
*
|
||||
@@ -218,7 +234,7 @@ public interface IBaseService<M, K extends Serializable> extends IService<M>{
|
||||
*
|
||||
* @param resultList 主表实体对象列表。数据集成将直接作用于该对象列表。
|
||||
* @param relationParam 实体对象数据组装的参数构建器。
|
||||
* @param batchSize 每批集成的记录数量。小于等于时将不做分批处理。
|
||||
* @param batchSize 每批集成的记录数量。小于等于0时将不做分批处理。
|
||||
*/
|
||||
void buildRelationForDataList(List<M> resultList, MyRelationParam relationParam, int batchSize);
|
||||
|
||||
@@ -236,7 +252,7 @@ public interface IBaseService<M, K extends Serializable> extends IService<M>{
|
||||
*
|
||||
* @param resultList 主表实体对象列表。数据集成将直接作用于该对象列表。
|
||||
* @param relationParam 实体对象数据组装的参数构建器。
|
||||
* @param batchSize 每批集成的记录数量。小于等于时将不做分批处理。
|
||||
* @param batchSize 每批集成的记录数量。小于等于0时将不做分批处理。
|
||||
* @param ignoreFields 该集合中的字段,即便包含注解也不会在当前调用中进行数据组装。
|
||||
*/
|
||||
void buildRelationForDataList(
|
||||
@@ -274,4 +290,16 @@ public interface IBaseService<M, K extends Serializable> extends IService<M>{
|
||||
* 仅仅在spring boot 启动后的监听器事件中调用,缓存所有service的关联关系,加速后续的数据绑定效率。
|
||||
*/
|
||||
void loadLocalRelationStruct();
|
||||
|
||||
/**
|
||||
* 内部使用的批量保存方法。在使用前要确保清楚该方法的实现功能。
|
||||
* 该方法通常用于从表数据的批量更新,为了保证已有数据的主键不变,我们通常会在执行该方法前,根据主表的关联数据,
|
||||
* 删除从表中的数据。之后在迭代参数dataList,并将没有主键值的对象视为新对象,该方法将为这些新对象生成主键值。
|
||||
* 其他包含主键值的对象,为已有对象,不做任何修改。填充主键后,将dataList集合中的数据批量插入到数据表。
|
||||
*
|
||||
* @param dataList 待操作的数据列表。
|
||||
* @param idGenerator 主键值生成器方法。
|
||||
* @param batchInserter 批量插入方法。
|
||||
*/
|
||||
void saveInternal(List<M> dataList, Supplier<K> idGenerator, Consumer<List<M>> batchInserter);
|
||||
}
|
||||
|
||||
@@ -29,6 +29,9 @@ public class FeignConfig implements RequestInterceptor {
|
||||
requestTemplate.header(TokenData.REQUEST_ATTRIBUTE_NAME, tokenData);
|
||||
}
|
||||
String traceId = ContextUtil.getHttpRequest().getHeader(ApplicationConstant.HTTP_HEADER_TRACE_ID);
|
||||
if (StringUtils.isBlank(traceId)) {
|
||||
traceId = (String) ContextUtil.getHttpRequest().getAttribute(ApplicationConstant.HTTP_HEADER_TRACE_ID);
|
||||
}
|
||||
if (StringUtils.isNotBlank(traceId)) {
|
||||
requestTemplate.header(ApplicationConstant.HTTP_HEADER_TRACE_ID, traceId);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.orange.demo.common.core.constant;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* App 登录的设备类型。
|
||||
*
|
||||
* @author Jerry
|
||||
* @date 2020-08-08
|
||||
*/
|
||||
public final class AppDeviceType {
|
||||
|
||||
/**
|
||||
* 移动端 (如果不考虑区分android或ios的,可以使用该值)
|
||||
*/
|
||||
public static final int MOBILE = 0;
|
||||
/**
|
||||
* android
|
||||
*/
|
||||
public static final int ANDROID = 1;
|
||||
/**
|
||||
* iOS
|
||||
*/
|
||||
public static final int IOS = 2;
|
||||
/**
|
||||
* 微信公众号和小程序
|
||||
*/
|
||||
public static final int WEIXIN = 3;
|
||||
/**
|
||||
* PC WEB
|
||||
*/
|
||||
public static final int WEB = 4;
|
||||
|
||||
private static final Map<Object, String> DICT_MAP = new HashMap<>(5);
|
||||
static {
|
||||
DICT_MAP.put(MOBILE, "移动端");
|
||||
DICT_MAP.put(ANDROID, "Android");
|
||||
DICT_MAP.put(IOS, "iOS");
|
||||
DICT_MAP.put(WEIXIN, "微信");
|
||||
DICT_MAP.put(WEB, "PC WEB");
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断参数是否为当前常量字典的合法值。
|
||||
*
|
||||
* @param value 待验证的参数值。
|
||||
* @return 合法返回true,否则false。
|
||||
*/
|
||||
public static boolean isValid(Integer value) {
|
||||
return value != null && DICT_MAP.containsKey(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 私有构造函数,明确标识该常量类的作用。
|
||||
*/
|
||||
private AppDeviceType() {
|
||||
}
|
||||
}
|
||||
@@ -55,4 +55,8 @@ public class LoginUserInfo {
|
||||
* 登录时间。
|
||||
*/
|
||||
private Date loginTime;
|
||||
/**
|
||||
* 登录设备类型。
|
||||
*/
|
||||
private Integer deviceType;
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@ public class ResponseResult<T> {
|
||||
* @return 返回创建的ResponseResult实例对象
|
||||
*/
|
||||
public static <T> ResponseResult<T> error(String errorCode, String errorMessage) {
|
||||
return new ResponseResult<>(false, errorCode, errorMessage);
|
||||
return new ResponseResult<>(errorCode, errorMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -213,8 +213,8 @@ public class ResponseResult<T> {
|
||||
|
||||
}
|
||||
|
||||
private ResponseResult(boolean success, String errorCode, String errorMessage) {
|
||||
this.success = success;
|
||||
private ResponseResult(String errorCode, String errorMessage) {
|
||||
this.success = false;
|
||||
this.errorCode = errorCode;
|
||||
this.errorMessage = errorMessage;
|
||||
}
|
||||
|
||||
@@ -37,6 +37,10 @@ public class TokenData {
|
||||
* 仅当系统支持uaa时可用,否则可以直接忽略该字段。保留该字段是为了保持单体和微服务通用代码部分的兼容性。
|
||||
*/
|
||||
private Long deptId;
|
||||
/**
|
||||
* 用户的部门岗位Id。多个岗位之间逗号分隔。仅当系统支持岗位时有值。
|
||||
*/
|
||||
private String deptPostIds;
|
||||
/**
|
||||
* 租户Id。
|
||||
* 仅当系统支持uaa时可用,否则可以直接忽略该字段。保留该字段是为了保持单体和微服务通用代码部分的兼容性。
|
||||
@@ -54,6 +58,10 @@ public class TokenData {
|
||||
* 用户显示名称。
|
||||
*/
|
||||
private String showName;
|
||||
/**
|
||||
* 设备类型。参考 AppDeviceType。
|
||||
*/
|
||||
private Integer deviceType;
|
||||
/**
|
||||
* 标识不同登录的会话Id。
|
||||
*/
|
||||
|
||||
@@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.crypto.digest.DigestUtil;
|
||||
import com.orange.demo.common.core.constant.AppDeviceType;
|
||||
|
||||
import javax.validation.ConstraintViolation;
|
||||
import javax.validation.Validation;
|
||||
@@ -168,6 +169,24 @@ public class MyCommonUtil {
|
||||
return new String[]{};
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取请求头中的设备信息。
|
||||
*
|
||||
* @return 设备类型,具体值可参考AppDeviceType常量类。
|
||||
*/
|
||||
public static int getDeviceType() {
|
||||
// 缺省都按照Web登录方式设置,如果前端header中的值为不合法值,这里也不会报错,而是使用Web缺省方式。
|
||||
int deviceType = AppDeviceType.WEB;
|
||||
String deviceTypeString = ContextUtil.getHttpRequest().getHeader("deviceType");
|
||||
if (StrUtil.isNotBlank(deviceTypeString)) {
|
||||
Integer type = Integer.valueOf(deviceTypeString);
|
||||
if (AppDeviceType.isValid(type)) {
|
||||
deviceType = type;
|
||||
}
|
||||
}
|
||||
return deviceType;
|
||||
}
|
||||
|
||||
/**
|
||||
* 私有构造函数,明确标识该常量类的作用。
|
||||
*/
|
||||
|
||||
@@ -2,19 +2,22 @@ package com.orange.demo.common.core.util;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.orange.demo.common.core.exception.InvalidDataFieldException;
|
||||
import com.orange.demo.common.core.annotation.*;
|
||||
import com.orange.demo.common.core.exception.MyRuntimeException;
|
||||
import com.orange.demo.common.core.object.TokenData;
|
||||
import com.orange.demo.common.core.object.Tuple2;
|
||||
import com.orange.demo.common.core.upload.UploadStoreInfo;
|
||||
import com.google.common.base.CaseFormat;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.collections4.MapUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import tk.mybatis.mapper.entity.Example;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Transient;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@@ -204,20 +207,8 @@ public class MyModelUtil {
|
||||
if (field == null) {
|
||||
return null;
|
||||
}
|
||||
TableField c = field.getAnnotation(TableField.class);
|
||||
String columnName = null;
|
||||
if (c == null) {
|
||||
TableId id = field.getAnnotation(TableId.class);
|
||||
if (id != null) {
|
||||
columnName = id.value();
|
||||
}
|
||||
}
|
||||
if (columnName == null) {
|
||||
columnName = c == null ? CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, fieldName) : c.value();
|
||||
if (StringUtils.isBlank(columnName)) {
|
||||
columnName = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, fieldName);
|
||||
}
|
||||
}
|
||||
Column c = field.getAnnotation(Column.class);
|
||||
String columnName = c == null ? fieldName : c.name();
|
||||
// 这里缺省情况下都是按照整型去处理,因为他覆盖太多的类型了。
|
||||
// 如Integer/Long/Double/BigDecimal,可根据实际情况完善和扩充。
|
||||
String typeName = field.getType().getSimpleName();
|
||||
@@ -240,8 +231,8 @@ public class MyModelUtil {
|
||||
* @return Model对象对应的数据表名称。
|
||||
*/
|
||||
public static String mapToTableName(Class<?> modelClazz) {
|
||||
TableName t = modelClazz.getAnnotation(TableName.class);
|
||||
return t == null ? null : t.value();
|
||||
Table t = modelClazz.getAnnotation(Table.class);
|
||||
return t == null ? null : t.name();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -614,6 +605,43 @@ public class MyModelUtil {
|
||||
return isMap ? BeanUtil.beanToMap(model) : model;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换过滤对象到与其等效的Example对象。
|
||||
*
|
||||
* @param filterModel 过滤对象。
|
||||
* @param modelClass 过滤对象的Class对象。
|
||||
* @param <T> 过滤对象类型。
|
||||
* @return 转换后的Example对象。
|
||||
*/
|
||||
public static <T> Example convertFilterModelToExample(T filterModel, Class<T> modelClass) {
|
||||
if (filterModel == null) {
|
||||
return null;
|
||||
}
|
||||
Example e = new Example(modelClass);
|
||||
Example.Criteria c = e.createCriteria();
|
||||
Field[] fields = ReflectUtil.getFields(modelClass);
|
||||
for (Field field : fields) {
|
||||
if (field.getAnnotation(Transient.class) == null) {
|
||||
int modifiers = field.getModifiers();
|
||||
// transient类型的字段不能作为查询条件
|
||||
if ((modifiers & 128) != 0 || Modifier.isStatic(modifiers)) {
|
||||
continue;
|
||||
}
|
||||
ReflectUtil.setAccessible(field);
|
||||
try {
|
||||
Object o = field.get(filterModel);
|
||||
if (o != null) {
|
||||
c.andEqualTo(field.getName(), field.get(filterModel));
|
||||
}
|
||||
} catch (IllegalAccessException ex) {
|
||||
log.error("Failed to call reflection code.", ex);
|
||||
throw new MyRuntimeException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取上传字段的存储信息。
|
||||
*
|
||||
|
||||
@@ -27,6 +27,17 @@ public class RedisKeyUtil {
|
||||
return "SESSIONID__" + loginName + "_";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定用户Id和登录设备类型的session缓存的键前缀。
|
||||
*
|
||||
* @param loginName 指定的用户登录名。
|
||||
* @param deviceType 设备类型。
|
||||
* @return session缓存的键前缀。
|
||||
*/
|
||||
public static String getSessionIdPrefix(String loginName, int deviceType) {
|
||||
return "SESSIONID__" + loginName + "_" + deviceType + "_";
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算SessionId返回存储于Redis中的键。
|
||||
*
|
||||
|
||||
@@ -64,20 +64,23 @@
|
||||
<orderEntry type="library" name="Maven: com.alibaba:druid-spring-boot-starter:1.2.6" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.alibaba:druid:1.2.6" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.3.10.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-boot-starter:3.4.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.baomidou:mybatis-plus:3.4.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-extension:3.4.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-core:3.4.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-annotation:3.4.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: tk.mybatis:mapper-spring-boot-starter:2.1.5" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:2.3.10.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.zaxxer:HikariCP:3.4.5" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-jdbc:5.2.14.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-tx:5.2.14.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.mybatis:mybatis:3.4.6" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.mybatis:mybatis-spring:1.3.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: tk.mybatis:mapper-core:1.1.5" level="project" />
|
||||
<orderEntry type="library" name="Maven: javax.persistence:persistence-api:1.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: tk.mybatis:mapper-base:1.1.5" level="project" />
|
||||
<orderEntry type="library" name="Maven: tk.mybatis:mapper-weekend:1.1.5" level="project" />
|
||||
<orderEntry type="library" name="Maven: tk.mybatis:mapper-spring:1.1.5" level="project" />
|
||||
<orderEntry type="library" name="Maven: tk.mybatis:mapper-extra:1.1.5" level="project" />
|
||||
<orderEntry type="library" name="Maven: tk.mybatis:mapper-spring-boot-autoconfigure:2.1.5" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-starter:1.3.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-starter:2.1.3" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-autoconfigure:2.1.3" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.mybatis:mybatis:3.5.5" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.mybatis:mybatis-spring:2.0.5" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-autoconfigure:1.3.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper:5.2.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.github.jsqlparser:jsqlparser:3.2" level="project" />
|
||||
|
||||
@@ -65,20 +65,23 @@
|
||||
<orderEntry type="library" name="Maven: com.alibaba:druid-spring-boot-starter:1.2.6" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.alibaba:druid:1.2.6" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.3.10.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-boot-starter:3.4.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.baomidou:mybatis-plus:3.4.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-extension:3.4.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-core:3.4.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-annotation:3.4.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: tk.mybatis:mapper-spring-boot-starter:2.1.5" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:2.3.10.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.zaxxer:HikariCP:3.4.5" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-jdbc:5.2.14.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-tx:5.2.14.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.mybatis:mybatis:3.4.6" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.mybatis:mybatis-spring:1.3.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: tk.mybatis:mapper-core:1.1.5" level="project" />
|
||||
<orderEntry type="library" name="Maven: javax.persistence:persistence-api:1.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: tk.mybatis:mapper-base:1.1.5" level="project" />
|
||||
<orderEntry type="library" name="Maven: tk.mybatis:mapper-weekend:1.1.5" level="project" />
|
||||
<orderEntry type="library" name="Maven: tk.mybatis:mapper-spring:1.1.5" level="project" />
|
||||
<orderEntry type="library" name="Maven: tk.mybatis:mapper-extra:1.1.5" level="project" />
|
||||
<orderEntry type="library" name="Maven: tk.mybatis:mapper-spring-boot-autoconfigure:2.1.5" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-starter:1.3.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-starter:2.1.3" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-autoconfigure:2.1.3" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.mybatis:mybatis:3.5.5" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.mybatis:mybatis-spring:2.0.5" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-autoconfigure:1.3.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper:5.2.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.github.jsqlparser:jsqlparser:3.2" level="project" />
|
||||
|
||||
@@ -82,20 +82,23 @@
|
||||
<orderEntry type="library" name="Maven: com.alibaba:druid-spring-boot-starter:1.2.6" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.alibaba:druid:1.2.6" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.3.10.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-boot-starter:3.4.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.baomidou:mybatis-plus:3.4.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-extension:3.4.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-core:3.4.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.baomidou:mybatis-plus-annotation:3.4.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: tk.mybatis:mapper-spring-boot-starter:2.1.5" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-jdbc:2.3.10.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.zaxxer:HikariCP:3.4.5" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-jdbc:5.2.14.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.springframework:spring-tx:5.2.14.RELEASE" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.mybatis:mybatis:3.4.6" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.mybatis:mybatis-spring:1.3.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: tk.mybatis:mapper-core:1.1.5" level="project" />
|
||||
<orderEntry type="library" name="Maven: javax.persistence:persistence-api:1.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: tk.mybatis:mapper-base:1.1.5" level="project" />
|
||||
<orderEntry type="library" name="Maven: tk.mybatis:mapper-weekend:1.1.5" level="project" />
|
||||
<orderEntry type="library" name="Maven: tk.mybatis:mapper-spring:1.1.5" level="project" />
|
||||
<orderEntry type="library" name="Maven: tk.mybatis:mapper-extra:1.1.5" level="project" />
|
||||
<orderEntry type="library" name="Maven: tk.mybatis:mapper-spring-boot-autoconfigure:2.1.5" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-starter:1.3.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-starter:2.1.3" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.mybatis.spring.boot:mybatis-spring-boot-autoconfigure:2.1.3" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.mybatis:mybatis:3.5.5" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.mybatis:mybatis-spring:2.0.5" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper-spring-boot-autoconfigure:1.3.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.github.pagehelper:pagehelper:5.2.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: com.github.jsqlparser:jsqlparser:3.2" level="project" />
|
||||
|
||||
Reference in New Issue
Block a user