MPJLambdaWrapper兼容单表update和delete

This commit is contained in:
yulichang 2023-02-22 18:00:40 +08:00
parent 1cce8e8e10
commit 11db738c62
45 changed files with 1242 additions and 91 deletions

View File

@ -1,12 +1,12 @@
# mybatis-plus-join
* 对 [mybatis-plus](https://gitee.com/baomidou/mybatis-plus) 多表查询的扩展
* [演示工程](https://gitee.com/best_handsome/mybatis-plus-join-demo)
* 对 <a href="https://gitee.com/baomidou/mybatis-plus" target="_blank">mybatis-plus</a> 多表查询的扩展
* <a href="https://gitee.com/best_handsome/mybatis-plus-join-demo" target="_blank">演示工程</a>
* <a href="https://ylctmh.com" target="_blank">文档</a>
* 点个Star支持一下吧 :)
QQ群:1022221898
[加入微信群](https://gitee.com/best_handsome/mybatis-plus-join/issues/I65N2M)
<a href="https://gitee.com/best_handsome/mybatis-plus-join/issues/I65N2M" target="_blank">加入微信群</a>
### <a href="https://ylctmh.com" target="_blank">文档</a>
@ -28,7 +28,7 @@ QQ群:1022221898
```
或者clone代码到本地执行 mvn install, 再引入以上依赖
<br>
注意: mybatis plus version >= 3.4.0
注意: mybatis plus version >= 3.3.0
<br>
### 使用
@ -252,7 +252,7 @@ ORDER BY
addr.id DESC
```
# [wiki](https://ylctmh.com)
# <a href="https://ylctmh.com" target="_blank">wiki</a>

View File

@ -5,7 +5,9 @@ import com.baomidou.mybatisplus.core.toolkit.ReflectionKit;
import com.github.yulichang.annotation.EntityMapping;
import com.github.yulichang.annotation.FieldMapping;
import com.github.yulichang.exception.MPJException;
import com.github.yulichang.mapper.MPJTableFieldInfo;
import com.github.yulichang.mapper.MPJTableInfo;
import com.github.yulichang.toolkit.MPJReflectionKit;
import com.github.yulichang.toolkit.TableHelper;
import org.apache.ibatis.session.Configuration;
@ -28,7 +30,6 @@ import java.util.concurrent.ConcurrentHashMap;
* @author yulichang
* @see TableInfoHelper
*/
@SuppressWarnings("deprecation")
public class MPJTableInfoHelper {
/**
@ -45,7 +46,7 @@ public class MPJTableInfoHelper {
* @return 数据库表反射信息
*/
public static MPJTableInfo getTableInfo(Class<?> clazz) {
if (clazz == null || ReflectionKit.isPrimitiveOrWrapper(clazz) || clazz == String.class || clazz.isInterface()) {
if (clazz == null || MPJReflectionKit.isPrimitiveOrWrapper(clazz) || clazz == String.class || clazz.isInterface()) {
return null;
}
return TABLE_INFO_CACHE.get(clazz);
@ -76,10 +77,14 @@ public class MPJTableInfoHelper {
}
MPJTableInfo mpjTableInfo = new MPJTableInfo();
mpjTableInfo.setMapperClass(mapperClass);
mpjTableInfo.setEntityClass(clazz);
TableInfo tableInfo = TableHelper.get(clazz);
if (tableInfo == null) {
return;
if (mapperClass != null) {
return;
}
}
mpjTableInfo.setDto(tableInfo == null);
mpjTableInfo.setTableInfo(tableInfo);
initMapping(mpjTableInfo);
TABLE_INFO_CACHE.put(clazz, mpjTableInfo);
@ -98,26 +103,26 @@ public class MPJTableInfoHelper {
*/
public static void initMapping(MPJTableInfo mpjTableInfo) {
// 是否存在 @EntityMapping 注解
boolean existMapping = isExistMapping(mpjTableInfo.getTableInfo().getEntityType());
boolean existMapping = isExistMapping(mpjTableInfo.getEntityClass());
mpjTableInfo.setHasMapping(existMapping);
// 是否存在 @FieldMapping 注解
boolean existMappingField = isExistMappingField(mpjTableInfo.getTableInfo().getEntityType());
boolean existMappingField = isExistMappingField(mpjTableInfo.getEntityClass());
mpjTableInfo.setHasMappingField(existMappingField);
mpjTableInfo.setHasMappingOrField(existMapping || existMappingField);
/* 关系映射初始化 */
List<com.github.yulichang.mapper.MPJTableFieldInfo> mpjFieldList = new ArrayList<>();
List<Field> fields = ReflectionKit.getFieldList(ClassUtils.getUserClass(mpjTableInfo.getTableInfo().getEntityType()));
List<MPJTableFieldInfo> mpjFieldList = new ArrayList<>();
List<Field> fields = ReflectionKit.getFieldList(ClassUtils.getUserClass(mpjTableInfo.getEntityClass()));
for (Field field : fields) {
if (existMapping) {
EntityMapping mapping = field.getAnnotation(EntityMapping.class);
if (mapping != null) {
mpjFieldList.add(new com.github.yulichang.mapper.MPJTableFieldInfo(mpjTableInfo.getTableInfo().getEntityType(), mapping, field));
mpjFieldList.add(new MPJTableFieldInfo(mpjTableInfo.getEntityClass(), mapping, field));
}
}
if (existMappingField) {
FieldMapping mapping = field.getAnnotation(FieldMapping.class);
if (mapping != null) {
mpjFieldList.add(new com.github.yulichang.mapper.MPJTableFieldInfo(mpjTableInfo.getTableInfo().getEntityType(), mapping, field));
mpjFieldList.add(new MPJTableFieldInfo(mpjTableInfo.getEntityClass(), mapping, field));
}
}
}

View File

@ -3,12 +3,13 @@ package com.github.yulichang.base;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.github.yulichang.base.mapper.MPJDeepMapper;
import com.github.yulichang.base.mapper.MPJJoinMapper;
import com.github.yulichang.base.mapper.MPJRelationMapper;
/**
* @author yulichang
* @see BaseMapper
*/
public interface MPJBaseMapper<T> extends MPJJoinMapper<T>, MPJDeepMapper<T> {
public interface MPJBaseMapper<T> extends MPJJoinMapper<T>, MPJRelationMapper<T>, MPJDeepMapper<T> {
}

View File

@ -9,7 +9,6 @@ import com.github.yulichang.base.service.MPJJoinService;
*
* @author yulichang
* @see MPJJoinService
* @see MPJDeepService
*/
public interface MPJBaseService<T> extends MPJJoinService<T>, MPJDeepService<T> {
}

View File

@ -0,0 +1,77 @@
package com.github.yulichang.base.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ExceptionUtils;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.github.yulichang.relation.Relation;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
public interface MPJRelationMapper<T> extends BaseMapper<T> {
/**
* 通过注解实现单表多次查询
*
* @param function BaseMapper调用方法
* @param deep 是否深度查询
* @param prop 属性过滤, 可以只查询需要映射的属性
* @see com.github.yulichang.annotation.EntityMapping
* @see com.github.yulichang.annotation.FieldMapping
*/
@SuppressWarnings("unchecked")
default <R, M extends BaseMapper<T>> R selectRelation(Function<M, R> function, boolean deep, SFunction<T, ?>... prop) {
R r = function.apply((M) this);
if (Objects.isNull(r)) {
return null;
}
if (r instanceof List) {
List<T> data = (List<T>) r;
if (CollectionUtils.isEmpty(data)) {
return r;
} else {
T t = data.get(0);
if (Map.class.isAssignableFrom(t.getClass())) {
throw ExceptionUtils.mpe("暂不支持Map类型映射");
}
if (Object.class == t.getClass()) {
return r;
}
return (R) Relation.list(data, Arrays.asList(prop), deep);
}
}
if (r instanceof IPage) {
IPage<T> data = (IPage<T>) r;
if (!CollectionUtils.isEmpty(data.getRecords())) {
T t = data.getRecords().get(0);
if (Map.class.isAssignableFrom(t.getClass())) {
throw ExceptionUtils.mpe("暂不支持Map类型映射");
}
if (Object.class == t.getClass()) {
return r;
}
Relation.list(data.getRecords(), Arrays.asList(prop), deep);
}
return r;
}
if (r instanceof Integer) {
return r;
}
if (r instanceof Long) {
return r;
}
if (r instanceof Boolean) {
return r;
}
if (Object.class == r.getClass()) {
return r;
}
T data = (T) r;
return (R) Relation.one(data, Arrays.asList(prop), deep);
}
}

View File

@ -7,7 +7,7 @@ import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.service.IService;
import com.github.yulichang.annotation.EntityMapping;
import com.github.yulichang.annotation.FieldMapping;
import com.github.yulichang.base.MPJBaseMapper;
import com.github.yulichang.base.mapper.MPJDeepMapper;
import java.io.Serializable;
import java.util.Arrays;
@ -38,7 +38,7 @@ public interface MPJDeepService<T> extends IService<T> {
* @param id 主键ID列表
*/
default T getByIdDeep(Serializable id) {
return ((MPJBaseMapper<T>) getBaseMapper()).selectByIdDeep(id);
return ((MPJDeepMapper<T>) getBaseMapper()).selectByIdDeep(id);
}
/**
@ -50,7 +50,7 @@ public interface MPJDeepService<T> extends IService<T> {
* @param property 需要关联的字段
*/
default <R> T getByIdDeep(Serializable id, SFunction<T, R>... property) {
return ((MPJBaseMapper<T>) getBaseMapper()).selectByIdDeep(id, property);
return ((MPJDeepMapper<T>) getBaseMapper()).selectByIdDeep(id, property);
}
/**
@ -63,7 +63,7 @@ public interface MPJDeepService<T> extends IService<T> {
* @param property 需要关联的字段
*/
default <R> T getByIdDeep(Serializable id, List<SFunction<T, R>> property) {
return ((MPJBaseMapper<T>) getBaseMapper()).selectByIdDeep(id, property);
return ((MPJDeepMapper<T>) getBaseMapper()).selectByIdDeep(id, property);
}
/**
@ -72,7 +72,7 @@ public interface MPJDeepService<T> extends IService<T> {
* @param idList 主键ID列表
*/
default List<T> listByIdsDeep(Collection<? extends Serializable> idList) {
return ((MPJBaseMapper<T>) getBaseMapper()).selectBatchIdsDeep(idList);
return ((MPJDeepMapper<T>) getBaseMapper()).selectBatchIdsDeep(idList);
}
/**
@ -84,7 +84,7 @@ public interface MPJDeepService<T> extends IService<T> {
* @param property 需要关联的字段
*/
default <R> List<T> listByIdsDeep(Collection<? extends Serializable> idList, SFunction<T, R>... property) {
return ((MPJBaseMapper<T>) getBaseMapper()).selectBatchIdsDeep(idList, Arrays.asList(property));
return ((MPJDeepMapper<T>) getBaseMapper()).selectBatchIdsDeep(idList, Arrays.asList(property));
}
/**
@ -97,7 +97,7 @@ public interface MPJDeepService<T> extends IService<T> {
* @param property 需要关联的字段
*/
default <R> List<T> listByIdsDeep(Collection<? extends Serializable> idList, List<SFunction<T, R>> property) {
return ((MPJBaseMapper<T>) getBaseMapper()).selectBatchIdsDeep(idList, property);
return ((MPJDeepMapper<T>) getBaseMapper()).selectBatchIdsDeep(idList, property);
}
/**
@ -106,7 +106,7 @@ public interface MPJDeepService<T> extends IService<T> {
* @param columnMap 表字段 map 对象
*/
default List<T> listByMapDeep(Map<String, Object> columnMap) {
return ((MPJBaseMapper<T>) getBaseMapper()).selectByMapDeep(columnMap);
return ((MPJDeepMapper<T>) getBaseMapper()).selectByMapDeep(columnMap);
}
/**
@ -118,7 +118,7 @@ public interface MPJDeepService<T> extends IService<T> {
* @param property 需要关联的字段
*/
default <R> List<T> listByMapDeep(Map<String, Object> columnMap, SFunction<T, R>... property) {
return ((MPJBaseMapper<T>) getBaseMapper()).selectByMapDeep(columnMap, Arrays.asList(property));
return ((MPJDeepMapper<T>) getBaseMapper()).selectByMapDeep(columnMap, Arrays.asList(property));
}
/**
@ -131,7 +131,7 @@ public interface MPJDeepService<T> extends IService<T> {
* @param property 需要关联的字段
*/
default <R> List<T> listByMapDeep(Map<String, Object> columnMap, List<SFunction<T, R>> property) {
return ((MPJBaseMapper<T>) getBaseMapper()).selectByMapDeep(columnMap, property);
return ((MPJDeepMapper<T>) getBaseMapper()).selectByMapDeep(columnMap, property);
}
@ -142,7 +142,7 @@ public interface MPJDeepService<T> extends IService<T> {
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
*/
default T getOneDeep(Wrapper<T> queryWrapper) {
return ((MPJBaseMapper<T>) getBaseMapper()).selectOneDeep(queryWrapper);
return ((MPJDeepMapper<T>) getBaseMapper()).selectOneDeep(queryWrapper);
}
/**
@ -155,7 +155,7 @@ public interface MPJDeepService<T> extends IService<T> {
* @param property 需要关联的字段
*/
default <R> T getOneDeep(Wrapper<T> queryWrapper, SFunction<T, R>... property) {
return ((MPJBaseMapper<T>) getBaseMapper()).selectOneDeep(queryWrapper, Arrays.asList(property));
return ((MPJDeepMapper<T>) getBaseMapper()).selectOneDeep(queryWrapper, Arrays.asList(property));
}
/**
@ -169,7 +169,7 @@ public interface MPJDeepService<T> extends IService<T> {
* @param property 需要关联的字段
*/
default <R> T getOneDeep(Wrapper<T> queryWrapper, List<SFunction<T, R>> property) {
return ((MPJBaseMapper<T>) getBaseMapper()).selectOneDeep(queryWrapper, property);
return ((MPJDeepMapper<T>) getBaseMapper()).selectOneDeep(queryWrapper, property);
}
/**
@ -179,7 +179,7 @@ public interface MPJDeepService<T> extends IService<T> {
* @param throwEx 有多个 result 是否抛出异常
*/
default T getOneDeep(Wrapper<T> queryWrapper, boolean throwEx) {
return ((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapping(getOne(queryWrapper, throwEx), null);
return ((MPJDeepMapper<T>) getBaseMapper()).mpjQueryMapping(getOne(queryWrapper, throwEx), null);
}
/**
@ -192,7 +192,7 @@ public interface MPJDeepService<T> extends IService<T> {
* @param property 需要关联的字段
*/
default <R> T getOneDeep(Wrapper<T> queryWrapper, boolean throwEx, SFunction<T, R>... property) {
return ((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapping(getOne(queryWrapper, throwEx), Arrays.asList(property));
return ((MPJDeepMapper<T>) getBaseMapper()).mpjQueryMapping(getOne(queryWrapper, throwEx), Arrays.asList(property));
}
/**
@ -206,7 +206,7 @@ public interface MPJDeepService<T> extends IService<T> {
* @param property 需要关联的字段
*/
default <R> T getOneDeep(Wrapper<T> queryWrapper, boolean throwEx, List<SFunction<T, R>> property) {
return ((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapping(getOne(queryWrapper, throwEx), property);
return ((MPJDeepMapper<T>) getBaseMapper()).mpjQueryMapping(getOne(queryWrapper, throwEx), property);
}
/**
@ -215,7 +215,7 @@ public interface MPJDeepService<T> extends IService<T> {
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
*/
default Map<String, Object> getMapDeep(Wrapper<T> queryWrapper) {
return ((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapMapping(getMap(queryWrapper), currentModelClass(),
return ((MPJDeepMapper<T>) getBaseMapper()).mpjQueryMapMapping(getMap(queryWrapper), currentModelClass(),
null);
}
@ -228,7 +228,7 @@ public interface MPJDeepService<T> extends IService<T> {
* @param property 需要关联的字段
*/
default <R> Map<String, Object> getMapDeep(Wrapper<T> queryWrapper, SFunction<T, R>... property) {
return ((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapMapping(getMap(queryWrapper), currentModelClass(),
return ((MPJDeepMapper<T>) getBaseMapper()).mpjQueryMapMapping(getMap(queryWrapper), currentModelClass(),
Arrays.asList(property));
}
@ -242,7 +242,7 @@ public interface MPJDeepService<T> extends IService<T> {
* @param property 需要关联的字段
*/
default <R> Map<String, Object> getMapDeep(Wrapper<T> queryWrapper, List<SFunction<T, R>> property) {
return ((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapMapping(getMap(queryWrapper), currentModelClass(), property);
return ((MPJDeepMapper<T>) getBaseMapper()).mpjQueryMapMapping(getMap(queryWrapper), currentModelClass(), property);
}
/**
@ -251,7 +251,7 @@ public interface MPJDeepService<T> extends IService<T> {
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
*/
default List<T> listDeep(Wrapper<T> queryWrapper) {
return ((MPJBaseMapper<T>) getBaseMapper()).selectListDeep(queryWrapper);
return ((MPJDeepMapper<T>) getBaseMapper()).selectListDeep(queryWrapper);
}
/**
@ -263,7 +263,7 @@ public interface MPJDeepService<T> extends IService<T> {
* @param property 需要关联的字段
*/
default <R> List<T> listDeep(Wrapper<T> queryWrapper, SFunction<T, R>... property) {
return ((MPJBaseMapper<T>) getBaseMapper()).selectListDeep(queryWrapper, Arrays.asList(property));
return ((MPJDeepMapper<T>) getBaseMapper()).selectListDeep(queryWrapper, Arrays.asList(property));
}
/**
@ -276,7 +276,7 @@ public interface MPJDeepService<T> extends IService<T> {
* @param property 需要关联的字段
*/
default <R> List<T> listDeep(Wrapper<T> queryWrapper, List<SFunction<T, R>> property) {
return ((MPJBaseMapper<T>) getBaseMapper()).selectListDeep(queryWrapper, property);
return ((MPJDeepMapper<T>) getBaseMapper()).selectListDeep(queryWrapper, property);
}
/**
@ -285,7 +285,7 @@ public interface MPJDeepService<T> extends IService<T> {
* @see Wrappers#emptyWrapper()
*/
default List<T> listDeep() {
return ((MPJBaseMapper<T>) getBaseMapper()).selectListDeep(Wrappers.emptyWrapper());
return ((MPJDeepMapper<T>) getBaseMapper()).selectListDeep(Wrappers.emptyWrapper());
}
/**
@ -297,7 +297,7 @@ public interface MPJDeepService<T> extends IService<T> {
* @see Wrappers#emptyWrapper()
*/
default <R> List<T> listDeep(SFunction<T, R>... property) {
return ((MPJBaseMapper<T>) getBaseMapper()).selectListDeep(Wrappers.emptyWrapper(), Arrays.asList(property));
return ((MPJDeepMapper<T>) getBaseMapper()).selectListDeep(Wrappers.emptyWrapper(), Arrays.asList(property));
}
/**
@ -310,7 +310,7 @@ public interface MPJDeepService<T> extends IService<T> {
* @see Wrappers#emptyWrapper()
*/
default <R> List<T> listDeep(List<SFunction<T, R>> property) {
return ((MPJBaseMapper<T>) getBaseMapper()).selectListDeep(Wrappers.emptyWrapper(), property);
return ((MPJDeepMapper<T>) getBaseMapper()).selectListDeep(Wrappers.emptyWrapper(), property);
}
/**
@ -321,7 +321,7 @@ public interface MPJDeepService<T> extends IService<T> {
*/
default <E extends IPage<T>> E pageDeep(E page, Wrapper<T> queryWrapper) {
E e = page(page, queryWrapper);
((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapping(e.getRecords(), null);
((MPJDeepMapper<T>) getBaseMapper()).mpjQueryMapping(e.getRecords(), null);
return e;
}
@ -336,7 +336,7 @@ public interface MPJDeepService<T> extends IService<T> {
*/
default <R, E extends IPage<T>> E pageDeep(E page, Wrapper<T> queryWrapper, SFunction<T, R>... property) {
E e = page(page, queryWrapper);
((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapping(e.getRecords(), Arrays.asList(property));
((MPJDeepMapper<T>) getBaseMapper()).mpjQueryMapping(e.getRecords(), Arrays.asList(property));
return e;
}
@ -352,7 +352,7 @@ public interface MPJDeepService<T> extends IService<T> {
*/
default <R, E extends IPage<T>> E pageDeep(E page, Wrapper<T> queryWrapper, List<SFunction<T, R>> property) {
E e = page(page, queryWrapper);
((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapping(e.getRecords(), property);
((MPJDeepMapper<T>) getBaseMapper()).mpjQueryMapping(e.getRecords(), property);
return e;
}
@ -364,7 +364,7 @@ public interface MPJDeepService<T> extends IService<T> {
*/
default <E extends IPage<T>> E pageDeep(E page) {
E e = page(page);
((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapping(e.getRecords(), null);
((MPJDeepMapper<T>) getBaseMapper()).mpjQueryMapping(e.getRecords(), null);
return e;
}
@ -379,7 +379,7 @@ public interface MPJDeepService<T> extends IService<T> {
*/
default <R, E extends IPage<T>> E pageDeep(E page, SFunction<T, R>... property) {
E e = page(page);
((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapping(e.getRecords(), Arrays.asList(property));
((MPJDeepMapper<T>) getBaseMapper()).mpjQueryMapping(e.getRecords(), Arrays.asList(property));
return e;
}
@ -395,7 +395,7 @@ public interface MPJDeepService<T> extends IService<T> {
*/
default <R, E extends IPage<T>> E pageDeep(E page, List<SFunction<T, R>> property) {
E e = page(page);
((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapping(e.getRecords(), property);
((MPJDeepMapper<T>) getBaseMapper()).mpjQueryMapping(e.getRecords(), property);
return e;
}
@ -405,7 +405,7 @@ public interface MPJDeepService<T> extends IService<T> {
* @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
*/
default List<Map<String, Object>> listMapsDeep(Wrapper<T> queryWrapper) {
return ((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapMapping(listMaps(queryWrapper), currentModelClass(), null);
return ((MPJDeepMapper<T>) getBaseMapper()).mpjQueryMapMapping(listMaps(queryWrapper), currentModelClass(), null);
}
/**
@ -417,7 +417,7 @@ public interface MPJDeepService<T> extends IService<T> {
* @param property 需要关联的字段
*/
default <R> List<Map<String, Object>> listMapsDeep(Wrapper<T> queryWrapper, SFunction<T, R>... property) {
return ((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapMapping(listMaps(queryWrapper), currentModelClass(),
return ((MPJDeepMapper<T>) getBaseMapper()).mpjQueryMapMapping(listMaps(queryWrapper), currentModelClass(),
Arrays.asList(property));
}
@ -431,7 +431,7 @@ public interface MPJDeepService<T> extends IService<T> {
* @param property 需要关联的字段
*/
default <R> List<Map<String, Object>> listMapsDeep(Wrapper<T> queryWrapper, List<SFunction<T, R>> property) {
return ((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapMapping(listMaps(queryWrapper), currentModelClass(), property);
return ((MPJDeepMapper<T>) getBaseMapper()).mpjQueryMapMapping(listMaps(queryWrapper), currentModelClass(), property);
}
/**
@ -440,7 +440,7 @@ public interface MPJDeepService<T> extends IService<T> {
* @see Wrappers#emptyWrapper()
*/
default List<Map<String, Object>> listMapsDeep() {
return ((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapMapping(listMaps(), currentModelClass(), null);
return ((MPJDeepMapper<T>) getBaseMapper()).mpjQueryMapMapping(listMaps(), currentModelClass(), null);
}
/**
@ -452,7 +452,7 @@ public interface MPJDeepService<T> extends IService<T> {
* @see Wrappers#emptyWrapper()
*/
default <R> List<Map<String, Object>> listMapsDeep(SFunction<T, R>... property) {
return ((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapMapping(listMaps(), currentModelClass(), Arrays.asList(property));
return ((MPJDeepMapper<T>) getBaseMapper()).mpjQueryMapMapping(listMaps(), currentModelClass(), Arrays.asList(property));
}
/**
@ -465,7 +465,7 @@ public interface MPJDeepService<T> extends IService<T> {
* @see Wrappers#emptyWrapper()
*/
default <R> List<Map<String, Object>> listMapsDeep(List<SFunction<T, R>> property) {
return ((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapMapping(listMaps(), currentModelClass(), property);
return ((MPJDeepMapper<T>) getBaseMapper()).mpjQueryMapMapping(listMaps(), currentModelClass(), property);
}
/**
@ -476,7 +476,7 @@ public interface MPJDeepService<T> extends IService<T> {
*/
default <E extends IPage<Map<String, Object>>> E pageMapsDeep(E page, Wrapper<T> queryWrapper) {
E e = pageMaps(page, queryWrapper);
((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapMapping(e.getRecords(), currentModelClass(), null);
((MPJDeepMapper<T>) getBaseMapper()).mpjQueryMapMapping(e.getRecords(), currentModelClass(), null);
return e;
}
@ -491,7 +491,7 @@ public interface MPJDeepService<T> extends IService<T> {
*/
default <R, E extends IPage<Map<String, Object>>> E pageMapsDeep(E page, Wrapper<T> queryWrapper, SFunction<T, R>... property) {
E e = pageMaps(page, queryWrapper);
((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapMapping(e.getRecords(), currentModelClass(), Arrays.asList(property));
((MPJDeepMapper<T>) getBaseMapper()).mpjQueryMapMapping(e.getRecords(), currentModelClass(), Arrays.asList(property));
return e;
}
@ -507,7 +507,7 @@ public interface MPJDeepService<T> extends IService<T> {
*/
default <R, E extends IPage<Map<String, Object>>> E pageMapsDeep(E page, Wrapper<T> queryWrapper, List<SFunction<T, R>> property) {
E e = pageMaps(page, queryWrapper);
((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapMapping(e.getRecords(), currentModelClass(), property);
((MPJDeepMapper<T>) getBaseMapper()).mpjQueryMapMapping(e.getRecords(), currentModelClass(), property);
return e;
}
@ -519,7 +519,7 @@ public interface MPJDeepService<T> extends IService<T> {
*/
default <E extends IPage<Map<String, Object>>> E pageMapsDeep(E page) {
E e = pageMaps(page);
((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapMapping(e.getRecords(), currentModelClass(), null);
((MPJDeepMapper<T>) getBaseMapper()).mpjQueryMapMapping(e.getRecords(), currentModelClass(), null);
return e;
}
@ -534,7 +534,7 @@ public interface MPJDeepService<T> extends IService<T> {
*/
default <R, E extends IPage<Map<String, Object>>> E pageMapsDeep(E page, SFunction<T, R>... property) {
E e = pageMaps(page);
((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapMapping(e.getRecords(), currentModelClass(), Arrays.asList(property));
((MPJDeepMapper<T>) getBaseMapper()).mpjQueryMapMapping(e.getRecords(), currentModelClass(), Arrays.asList(property));
return e;
}
@ -550,7 +550,7 @@ public interface MPJDeepService<T> extends IService<T> {
*/
default <R, E extends IPage<Map<String, Object>>> E pageMapsDeep(E page, List<SFunction<T, R>> property) {
E e = pageMaps(page);
((MPJBaseMapper<T>) getBaseMapper()).mpjQueryMapMapping(e.getRecords(), currentModelClass(), property);
((MPJDeepMapper<T>) getBaseMapper()).mpjQueryMapMapping(e.getRecords(), currentModelClass(), property);
return e;
}
}

View File

@ -10,7 +10,6 @@ import com.baomidou.mybatisplus.core.toolkit.ArrayUtils;
import com.baomidou.mybatisplus.core.toolkit.ClassUtils;
import com.github.yulichang.mapper.MPJTableMapperHelper;
import com.github.yulichang.method.*;
import com.github.yulichang.method.mp.SelectOne;
import com.github.yulichang.toolkit.TableHelper;
import com.github.yulichang.toolkit.reflect.GenericTypeUtils;
import org.apache.ibatis.builder.MapperBuilderAssistant;
@ -43,11 +42,9 @@ public class MPJSqlInjector extends DefaultSqlInjector {
public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
List<AbstractMethod> list = Stream.of(
new Insert(),
new Delete(),
new DeleteByMap(),
new DeleteById(),
new DeleteBatchByIds(),
new Update(),
new UpdateById(),
new SelectById(),
new SelectBatchByIds(),
@ -63,8 +60,16 @@ public class MPJSqlInjector extends DefaultSqlInjector {
*/
@Override
public List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo) {
List<String> methodList = Arrays.asList("SelectOne", "SelectCount",
"SelectMaps", "SelectMapsPage", "SelectObjs", "SelectList", "SelectPage");
List<String> methodList = Arrays.asList(
"Update",
"Delete",
"SelectOne",
"SelectCount",
"SelectMaps",
"SelectMapsPage",
"SelectObjs",
"SelectList",
"SelectPage");
List<AbstractMethod> list = super.getMethodList(mapperClass, tableInfo);
list.removeIf(i -> methodList.contains(i.getClass().getSimpleName()));
list.addAll(getSelectMethod());
@ -107,13 +112,15 @@ public class MPJSqlInjector extends DefaultSqlInjector {
private List<AbstractMethod> getSelectMethod() {
List<AbstractMethod> list = new ArrayList<>();
list.add(new SelectOne());
list.add(new com.github.yulichang.method.mp.Delete());
list.add(new com.github.yulichang.method.mp.SelectOne());
list.add(new com.github.yulichang.method.mp.SelectCount());
list.add(new com.github.yulichang.method.mp.SelectMaps());
list.add(new com.github.yulichang.method.mp.SelectMapsPage());
list.add(new com.github.yulichang.method.mp.SelectObjs());
list.add(new com.github.yulichang.method.mp.SelectList());
list.add(new com.github.yulichang.method.mp.SelectPage());
list.add(new com.github.yulichang.method.mp.Update());
return list;
}

View File

@ -37,6 +37,21 @@ public class MPJTableInfo {
*/
private boolean hasMappingField;
/**
* 实例类 class
*/
private Class<?> entityClass;
/**
* 非数据库实体类
*/
private boolean isDto;
/**
* 是否循环
*/
private boolean isLoop;
/**
* mapperClass
*/

View File

@ -73,4 +73,12 @@ public abstract class MPJAbstractMethod extends AbstractMethod implements MPJBas
return SqlScriptUtils.convertIf("DISTINCT", "ew.selectDistinct", false);
}
@Override
protected String sqlFirst() {
try {
return super.sqlFirst();
} catch (Throwable e) {
return "";
}
}
}

View File

@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.sql.SqlScriptUtils;
import com.github.yulichang.config.ConfigProperties;
import com.github.yulichang.toolkit.JR;
import java.util.Objects;
@ -21,7 +22,7 @@ import static java.util.stream.Collectors.joining;
public interface MPJBaseMethod extends Constants {
default String mpjSqlWhereEntityWrapper(boolean newLine, TableInfo table) {
if (table.isWithLogicDelete()) {
if (JR.mpjHasLogic(table)) {
String sqlScript = getAllSqlWhere(table, true, true, WRAPPER_ENTITY_DOT);
sqlScript = SqlScriptUtils.convertIf(sqlScript, String.format("%s != null", WRAPPER_ENTITY), true);
sqlScript += NEWLINE;
@ -43,7 +44,7 @@ public interface MPJBaseMethod extends Constants {
sqlScript += (String.format("${%s.subLogicSql}", WRAPPER) + NEWLINE);
}
String s = SqlScriptUtils.convertIf("AND", WRAPPER_NONEMPTYOFNORMAL, true);
sqlScript += SqlScriptUtils.convertIf(s+String.format(" ${%s}", WRAPPER_SQLSEGMENT), String.format("%s != null and %s != '' and %s", WRAPPER_SQLSEGMENT, WRAPPER_SQLSEGMENT, WRAPPER_NONEMPTYOFWHERE), true);
sqlScript += SqlScriptUtils.convertIf(s + String.format(" ${%s}", WRAPPER_SQLSEGMENT), String.format("%s != null and %s != '' and %s", WRAPPER_SQLSEGMENT, WRAPPER_SQLSEGMENT, WRAPPER_NONEMPTYOFWHERE), true);
sqlScript = SqlScriptUtils.convertWhere(sqlScript) + NEWLINE;
sqlScript += SqlScriptUtils.convertIf(String.format(" ${%s}", WRAPPER_SQLSEGMENT), String.format("%s != null and %s != '' and %s", WRAPPER_SQLSEGMENT, WRAPPER_SQLSEGMENT, WRAPPER_EMPTYOFWHERE), true);
sqlScript = SqlScriptUtils.convertIf(sqlScript, String.format("%s != null", WRAPPER), true);
@ -60,7 +61,7 @@ public interface MPJBaseMethod extends Constants {
String filedSqlScript = tableInfo.getFieldList().stream()
.filter(i -> {
if (ignoreLogicDelFiled) {
return !(tableInfo.isWithLogicDelete() && i.isLogicDelete());
return !(JR.mpjHasLogic(tableInfo) && i.isLogicDelete());
}
return true;
})
@ -86,7 +87,7 @@ public interface MPJBaseMethod extends Constants {
if (fieldStrategy == FieldStrategy.NEVER) {
return null;
}
if (tableFieldInfo.isPrimitive() || fieldStrategy == FieldStrategy.IGNORED) {
if (JR.mpjIsPrimitive(tableFieldInfo) || fieldStrategy == FieldStrategy.IGNORED) {
return sqlScript;
}
if (fieldStrategy == FieldStrategy.NOT_EMPTY && tableFieldInfo.isCharSequence()) {
@ -102,7 +103,7 @@ public interface MPJBaseMethod extends Constants {
default String getLogicDeleteSql(TableInfo tableInfo, boolean startWithAnd, boolean isWhere) {
if (tableInfo.isWithLogicDelete()) {
if (JR.mpjHasLogic(tableInfo)) {
String logicDeleteSql = formatLogicDeleteSql(tableInfo, isWhere);
if (startWithAnd) {
logicDeleteSql = " AND " + logicDeleteSql;
@ -114,12 +115,12 @@ public interface MPJBaseMethod extends Constants {
default String formatLogicDeleteSql(TableInfo tableInfo, boolean isWhere) {
final String value = isWhere ? tableInfo.getLogicDeleteFieldInfo().getLogicNotDeleteValue() : tableInfo.getLogicDeleteFieldInfo().getLogicDeleteValue();
final String value = isWhere ? JR.mpjGetLogicField(tableInfo).getLogicNotDeleteValue() : JR.mpjGetLogicField(tableInfo).getLogicDeleteValue();
if (isWhere) {
if (NULL.equalsIgnoreCase(value)) {
return "${ew.alias}." + tableInfo.getLogicDeleteFieldInfo().getColumn() + " IS NULL";
return "${ew.alias}." + JR.mpjGetLogicField(tableInfo).getColumn() + " IS NULL";
} else {
return "${ew.alias}." + tableInfo.getLogicDeleteFieldInfo().getColumn() + EQUALS + String.format(tableInfo.getLogicDeleteFieldInfo().isCharSequence() ? "'%s'" : "%s", value);
return "${ew.alias}." + JR.mpjGetLogicField(tableInfo).getColumn() + EQUALS + String.format(JR.mpjGetLogicField(tableInfo).isCharSequence() ? "'%s'" : "%s", value);
}
}
final String targetStr = "${ew.alias}." + tableInfo.getLogicDeleteFieldInfo().getColumn() + EQUALS;
@ -133,5 +134,4 @@ public interface MPJBaseMethod extends Constants {
default String mpjSqlSelectColumns() {
return SqlScriptUtils.convertIf("DISTINCT", "ew.selectDistinct", false);
}
}

View File

@ -11,6 +11,20 @@ import java.util.stream.Collectors;
*/
public enum SqlMethod {
// /**
// * 修改
// */
/**
* 删除
*/
DELETE("delete", "根据 entity 条件删除记录", "<script>\nDELETE FROM %s %s %s\n</script>"),
/**
* 逻辑删除
*/
LOGIC_DELETE("delete", "根据 entity 条件逻辑删除记录", "<script>\nUPDATE %s %s %s %s\n</script>"),
/**
* 连表查询
*/

View File

@ -0,0 +1,35 @@
package com.github.yulichang.method.mp;
import com.baomidou.mybatisplus.core.metadata.MPJTableInfoHelper;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.core.toolkit.sql.SqlScriptUtils;
import com.github.yulichang.interfaces.MPJBaseJoin;
import org.apache.ibatis.mapping.MappedStatement;
/**
* Delete 兼容MP原生方法
*/
public class Delete extends com.baomidou.mybatisplus.core.injector.methods.Delete implements TableAlias {
public Delete() {
super();
}
@SuppressWarnings("unused")
public Delete(String name) {
super(name);
}
@Override
public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
return super.injectMappedStatement(mapperClass, modelClass,
MPJTableInfoHelper.copyAndSetTableName(tableInfo, getTableName(tableInfo)));
}
@Override
protected String sqlWhereEntityWrapper(boolean newLine, TableInfo table) {
return SqlScriptUtils.convertChoose(String.format("%s == null or !(%s instanceof %s)", Constants.WRAPPER, Constants.WRAPPER, MPJBaseJoin.class.getName()),
super.sqlWhereEntityWrapper(newLine, table), mpjSqlWhereEntityWrapper(newLine, table));
}
}

View File

@ -0,0 +1,35 @@
package com.github.yulichang.method.mp;
import com.baomidou.mybatisplus.core.metadata.MPJTableInfoHelper;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.core.toolkit.sql.SqlScriptUtils;
import com.github.yulichang.interfaces.MPJBaseJoin;
import org.apache.ibatis.mapping.MappedStatement;
/**
* Delete 兼容MP原生方法
*/
public class Update extends com.baomidou.mybatisplus.core.injector.methods.Update implements TableAlias {
public Update() {
super();
}
@SuppressWarnings("unused")
public Update(String name) {
super(name);
}
@Override
public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
return super.injectMappedStatement(mapperClass, modelClass,
MPJTableInfoHelper.copyAndSetTableName(tableInfo, getTableName(tableInfo)));
}
@Override
protected String sqlWhereEntityWrapper(boolean newLine, TableInfo table) {
return SqlScriptUtils.convertChoose(String.format("%s == null or !(%s instanceof %s)", Constants.WRAPPER, Constants.WRAPPER, MPJBaseJoin.class.getName()),
super.sqlWhereEntityWrapper(newLine, table), mpjSqlWhereEntityWrapper(newLine, table));
}
}

View File

@ -18,17 +18,12 @@ import java.util.function.Predicate;
import java.util.stream.Collectors;
/**
* 不推荐使用这wrapper
* 这种既有string又有lambda对开发人员并不友好
* <p>
* 推荐使用以下两个类 :
* String -> {@link MPJQueryWrapper<T>}
* lambda -> {@link com.github.yulichang.wrapper.MPJLambdaWrapper<T>}
* <p>
* MPJLambdaQueryWrapper
* 参考 -> {@link com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper}
*
* @author yulichang
* @see com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper
*/
@Deprecated
@SuppressWarnings("unused")
public class MPJLambdaQueryWrapper<T> extends AbstractLambdaWrapper<T, MPJLambdaQueryWrapper<T>>
implements Query<MPJLambdaQueryWrapper<T>, T, SFunction<T, ?>>, StringJoin<MPJLambdaQueryWrapper<T>, T> {

View File

@ -241,7 +241,6 @@ public class MPJQueryWrapper<T> extends AbstractWrapper<T, String, MPJQueryWrapp
/**
* 返回一个支持 lambda 函数写法的 wrapper
*/
@Deprecated
public MPJLambdaQueryWrapper<T> lambda() {
return new MPJLambdaQueryWrapper<>(getEntity(), getEntityClass(), from, sqlSelect, paramNameSeq, paramNameValuePairs,
expression, lastSql, sqlComment, sqlFirst, selectColumns, ignoreColumns);

View File

@ -0,0 +1,100 @@
package com.github.yulichang.relation;
import com.baomidou.mybatisplus.core.enums.SqlKeyword;
import com.baomidou.mybatisplus.core.metadata.MPJTableInfoHelper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.github.yulichang.base.mapper.wrapper.MappingQuery;
import com.github.yulichang.mapper.MPJTableFieldInfo;
import com.github.yulichang.mapper.MPJTableInfo;
import com.github.yulichang.toolkit.LambdaUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@SuppressWarnings("all")
public class Relation {
// private static final List EMPTY_LIST = new ArrayList<>();
public static <T> List<T> list(List<T> data, List<SFunction<T, ?>> property, boolean deep) {
if (CollectionUtils.isEmpty(data)) {
return data;
}
Class<?> entityClass = data.get(0).getClass();
MPJTableInfo tableInfo = MPJTableInfoHelper.getTableInfo(entityClass);
if (tableInfo.isHasMappingOrField()) {
boolean hasProperty = CollectionUtils.isNotEmpty(property);
List<String> listProperty = hasProperty ? property.stream().map(LambdaUtils::getName).collect(
Collectors.toList()) : null;
for (MPJTableFieldInfo fieldInfo : tableInfo.getFieldList()) {
if (!hasProperty || listProperty.contains(fieldInfo.getProperty())) {
List<Object> itemList = data.stream().map(fieldInfo::thisFieldGet).collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(itemList)) {
List<?> joinList = MappingQuery.mpjQueryList(fieldInfo.getJoinMapper(),
fieldInfo.isMappingEntity() && fieldInfo.isFieldIsMap(), SqlKeyword.IN,
fieldInfo.getJoinColumn(), itemList, fieldInfo);
data.forEach(i -> mpjBindData(i, fieldInfo, joinList));
fieldInfo.removeJoinField(joinList);
if (CollectionUtils.isEmpty(joinList)) {
// continue;
}
// //深度查询
// if (deep) {
//
// }
} else {
data.forEach(i -> fieldInfo.fieldSet(i, new ArrayList<>()));
}
}
}
}
return data;
}
/**
* 查询映射关系<br/>
* 对结果进行二次查询<br/>
* 可以自行查询然后在通过此方法进行二次查询<br/>
* list为null或空会查询全部映射关系<br/>
*
* @param t 第一次查询结果
*/
public static <T> T one(T t, List<SFunction<T, ?>> property, boolean deep) {
if (t == null) {
return null;
}
MPJTableInfo tableInfo = MPJTableInfoHelper.getTableInfo(t.getClass());
if (tableInfo.isHasMappingOrField()) {
boolean hasProperty = CollectionUtils.isNotEmpty(property);
List<String> list = hasProperty ? property.stream().map(LambdaUtils::getName).collect(
Collectors.toList()) : null;
for (MPJTableFieldInfo fieldInfo : tableInfo.getFieldList()) {
if (!hasProperty || list.contains(fieldInfo.getProperty())) {
Object obj = fieldInfo.thisFieldGet(t);
if (obj != null) {
List<?> joinList = MappingQuery.mpjQueryList(fieldInfo.getJoinMapper(),
fieldInfo.isFieldIsMap(), SqlKeyword.EQ, fieldInfo.getJoinColumn(), obj, fieldInfo);
mpjBindData(t, fieldInfo, joinList);
fieldInfo.removeJoinField(joinList);
}
}
}
}
return t;
}
public static <R> void mpjBindData(R t, MPJTableFieldInfo fieldInfo, List<?> joinList) {
if (fieldInfo.isMappingEntity()) {
List<?> list = joinList.stream().filter(j -> fieldInfo.joinFieldGet(j).equals(fieldInfo.thisFieldGet(t)))
.collect(Collectors.toList());
MPJTableFieldInfo.bind(fieldInfo, t, list);
}
if (fieldInfo.isMappingField()) {
MPJTableFieldInfo.bind(fieldInfo, t, joinList.stream().filter(j -> fieldInfo.joinFieldGet(j).equals(
fieldInfo.thisFieldGet(t))).map(fieldInfo::bindFieldGet).collect(Collectors.toList()));
}
}
}

View File

@ -0,0 +1,64 @@
package com.github.yulichang.toolkit;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import org.apache.ibatis.session.Configuration;
import java.lang.reflect.Field;
import java.util.Objects;
@SuppressWarnings("Convert2MethodRef")
public class JR {
@SuppressWarnings("JavaReflectionMemberAccess")
public static boolean mpjHasLogic(TableInfo tableInfo) {
return tryThrowable(() -> tableInfo.isWithLogicDelete(), () -> {
try {
Field field = TableInfo.class.getDeclaredField("logicDelete");
field.setAccessible(true);
return (boolean) field.get(tableInfo);
} catch (Exception ee) {
throw new RuntimeException(ee);
}
});
}
public static boolean mpjIsPrimitive(TableFieldInfo tableFieldInfo) {
return tryThrowable(() -> tableFieldInfo.isPrimitive(), () -> tableFieldInfo.getPropertyType().isPrimitive());
}
public static TableFieldInfo mpjGetLogicField(TableInfo tableInfo) {
return tryThrowable(() -> tableInfo.getLogicDeleteFieldInfo(), () -> tableInfo.getFieldList().stream().filter(f ->
Objects.nonNull(f.getLogicNotDeleteValue()) ||
Objects.nonNull(f.getLogicDeleteValue())).findFirst().orElse(null));
}
public static boolean mpjHasPK(TableInfo tableInfo) {
return tryThrowable(() -> tableInfo.havePK(), () -> Objects.nonNull(tableInfo.getKeyProperty()));
}
public static Configuration mpjGetConfiguration(TableInfo tableInfo) {
return tryThrowable(() -> tableInfo.getConfiguration(), () -> {
try {
Field field = TableInfo.class.getDeclaredField("configuration");
field.setAccessible(true);
return (Configuration) field.get(tableInfo);
} catch (Exception e) {
throw new RuntimeException(e);
}
});
}
private static <T> T tryThrowable(F<T> fn, F<T> orElse) {
try {
return fn.apply();
} catch (Throwable throwable) {
return orElse.apply();
}
}
@FunctionalInterface
public interface F<T> {
T apply();
}
}

View File

@ -1,5 +1,6 @@
package com.github.yulichang.toolkit;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.Constants;
@ -34,12 +35,13 @@ public class LogicInfoUtils implements Constants {
String logicStr;
TableInfo tableInfo = TableHelper.get(clazz);
Assert.notNull(tableInfo, "table not find by class <%s>", clazz.getSimpleName());
if (tableInfo.isWithLogicDelete() && Objects.nonNull(tableInfo.getLogicDeleteFieldInfo())) {
final String value = tableInfo.getLogicDeleteFieldInfo().getLogicNotDeleteValue();
TableFieldInfo logicField = JR.mpjGetLogicField(tableInfo);
if (JR.mpjHasLogic(tableInfo) && Objects.nonNull(logicField)) {
final String value = logicField.getLogicNotDeleteValue();
if (NULL.equalsIgnoreCase(value)) {
logicStr = " AND " + prefix + DOT + tableInfo.getLogicDeleteFieldInfo().getColumn() + " IS NULL";
logicStr = " AND " + prefix + DOT + logicField.getColumn() + " IS NULL";
} else {
logicStr = " AND " + prefix + DOT + tableInfo.getLogicDeleteFieldInfo().getColumn() + EQUALS + String.format(tableInfo.getLogicDeleteFieldInfo().isCharSequence() ? "'%s'" : "%s", value);
logicStr = " AND " + prefix + DOT + logicField.getColumn() + EQUALS + String.format(logicField.isCharSequence() ? "'%s'" : "%s", value);
}
} else {
logicStr = StringPool.EMPTY;

View File

@ -125,7 +125,7 @@ public final class ReflectionKit {
if (Objects.isNull(clazz)) {
return Collections.emptyList();
}
return CollectionUtils.computeIfAbsent(CLASS_FIELD_CACHE, clazz, k -> {
return computeIfAbsent(CLASS_FIELD_CACHE, clazz, k -> {
Field[] fields = k.getDeclaredFields();
List<Field> superFields = new ArrayList<>();
Class<?> currentClass = k.getSuperclass();
@ -197,4 +197,11 @@ public final class ReflectionKit {
return AccessController.doPrivileged(new SetAccessibleAction<>(object));
}
public static <K, V> V computeIfAbsent(Map<K, V> concurrentHashMap, K key, Function<? super K, ? extends V> mappingFunction) {
V v = concurrentHashMap.get(key);
if (v != null) {
return v;
}
return concurrentHashMap.computeIfAbsent(key, mappingFunction);
}
}

View File

@ -2,6 +2,7 @@ package com.github.yulichang.toolkit;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.baomidou.mybatisplus.core.toolkit.ClassUtils;
import java.util.Map;
import java.util.Objects;
@ -29,13 +30,24 @@ public class TableHelper {
}
}
@SuppressWarnings("ConstantConditions")
public static TableInfo get(Class<?> clazz) {
if (Objects.nonNull(clazz)) {
TableInfo tableInfo = TableInfoHelper.getTableInfo(clazz);
if (Objects.nonNull(tableInfo)) {
return tableInfo;
}
return TABLE_INFO_CACHE.get(clazz);
TableInfo info = TABLE_INFO_CACHE.get(clazz);
//尝试获取父类缓存
Class<?> currentClass = clazz;
while (Object.class != currentClass) {
currentClass = currentClass.getSuperclass();
info = TABLE_INFO_CACHE.get(ClassUtils.getUserClass(currentClass));
}
if (Objects.nonNull(info)) {
TABLE_INFO_CACHE.put(currentClass, info);
}
return info;
} else {
return null;
}

View File

@ -2,6 +2,7 @@ package com.github.yulichang.toolkit.support;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.github.yulichang.toolkit.JR;
import com.github.yulichang.toolkit.TableHelper;
import com.github.yulichang.wrapper.segments.SelectCache;
@ -29,7 +30,7 @@ public class ColumnCache {
TableInfo tableInfo = TableHelper.get(clazz);
Assert.notNull(tableInfo, "table not find by class <%s>", c.getSimpleName());
List<SelectCache> list = new ArrayList<>();
if (tableInfo.havePK()) {
if (JR.mpjHasPK(tableInfo)) {
list.add(new SelectCache(clazz, true, tableInfo.getKeyColumn(), tableInfo.getKeyType(), tableInfo.getKeyProperty(), null));
}
list.addAll(tableInfo.getFieldList().stream().map(f -> new SelectCache(clazz, false, f.getColumn(), f.getPropertyType(), f.getProperty(), f)).collect(Collectors.toList()));

View File

@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.github.yulichang.toolkit.JR;
import com.github.yulichang.toolkit.TableHelper;
import lombok.Getter;
import org.apache.ibatis.session.Configuration;
@ -56,7 +57,7 @@ public class SelectCache {
if (this.hasTypeHandle) {
TableInfo info = TableHelper.get(clazz);
Assert.notNull(info, "table not find by class <%s>", clazz.getSimpleName());
this.typeHandler = getTypeHandler(info.getConfiguration(), tableFieldInfo);
this.typeHandler = getTypeHandler(JR.mpjGetConfiguration(info), tableFieldInfo);
} else {
this.typeHandler = null;
}

View File

@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--suppress VulnerableLibrariesLocal -->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>mybatis-plus-join-test</artifactId>
<groupId>com.github.yulichang</groupId>
<version>1.4.2.2</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>test-springboot3-jdk17</artifactId>
<properties>
<springboot.version>3.0.2</springboot.version>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>${springboot.version}</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${springboot.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>6.0.5</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.1</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,14 @@
package com.yulichang.test.springboot3jdk17;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

View File

@ -0,0 +1,75 @@
package com.yulichang.test.springboot3jdk17.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.yulichang.test.springboot3jdk17.util.ThreadLocalUtils;
import org.apache.ibatis.builder.SqlSourceBuilder;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.sql.SQLException;
import java.util.Objects;
/**
* mybatis-plus配置
*/
@Configuration
public class MybatisPlusConfig {
/**
* 分页插件
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
PaginationInnerInterceptor page = new PaginationInnerInterceptor(DbType.H2);
page.setOptimizeJoin(false);
interceptor.addInnerInterceptor(page);
interceptor.addInnerInterceptor(new SqlInterceptor());
return interceptor;
}
/**
* 校验sql
*/
public static class SqlInterceptor implements InnerInterceptor {
@Override
public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
String sql = boundSql.getSql();
String s = ThreadLocalUtils.get();
if (StringUtils.isNotBlank(s) && !Objects.equals(formatSql(sql), formatSql(s))) {
System.err.println("执行sql: " + SqlSourceBuilder.removeExtraWhitespaces(sql));
System.err.println("预期sql: " + SqlSourceBuilder.removeExtraWhitespaces(s));
throw new RuntimeException("sql error");
}
InnerInterceptor.super.beforeQuery(executor, ms, parameter, rowBounds, resultHandler, boundSql);
}
private String formatSql(String sql) {
if (StringUtils.isBlank(sql)) {
return sql;
}
sql = sql.replaceAll("\n", "");
sql = sql.replaceAll("\r", "");
sql = sql.replaceAll("\t", "");
return dg(sql);
}
private String dg(String str) {
if (str.contains(" ")) {
str = str.replaceAll(" ", "");
return dg(str);
}
return str;
}
}
}

View File

@ -0,0 +1,26 @@
package com.yulichang.test.springboot3jdk17.dto;
import com.yulichang.test.springboot3jdk17.entity.AreaDO;
import lombok.Data;
import java.util.List;
@Data
public class AddressDTO {
private Integer id;
private Integer userId;
private Integer areaId;
private String tel;
private String address;
private Boolean del;
private List<AreaDO> areaList;
private AreaDO area;
}

View File

@ -0,0 +1,27 @@
package com.yulichang.test.springboot3jdk17.dto;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import lombok.experimental.Accessors;
@Data
@ToString
@Accessors(chain = true)
@EqualsAndHashCode
@TableName("area")
public class AreaDTO {
private Integer id;
private String province;
private String city;
private String area;
private String postcode;
private Boolean del;
}

View File

@ -0,0 +1,48 @@
package com.yulichang.test.springboot3jdk17.dto;
import com.yulichang.test.springboot3jdk17.entity.UserDO;
import com.yulichang.test.springboot3jdk17.enums.Sex;
import lombok.Data;
import lombok.ToString;
import java.util.List;
import java.util.Map;
/**
* userDTO
*/
@Data
@ToString
public class UserDTO {
/** user */
private Integer id;
/** user */
private String name;
/** user */
private Map<String,String> json;
/** user */
private Sex sex;
/** user */
private String headImg;
/** user */
private String userHeadImg;// headImg 别名测试
/** user_address */
private String tel;
/** user_address */
private String address;
/** user_address */
private String userAddress;
/** area */
private String province;
/** area */
private String city;
/** area */
private Map<String, String> area;
private List<AddressDTO> addressList;
private List<Integer> addressIds;
private List<UserDO> children;
}

View File

@ -0,0 +1,33 @@
package com.yulichang.test.springboot3jdk17.entity;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import lombok.experimental.Accessors;
import java.io.Serializable;
@Data
@ToString
@Accessors(chain = true)
@EqualsAndHashCode
@TableName("address")
public class AddressDO implements Serializable {
@TableId
private Integer id;
private Integer userId;
private Integer areaId;
private String tel;
private String address;
@TableLogic
private Boolean del;
}

View File

@ -0,0 +1,33 @@
package com.yulichang.test.springboot3jdk17.entity;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import lombok.experimental.Accessors;
import java.io.Serializable;
@Data
@ToString
@Accessors(chain = true)
@EqualsAndHashCode
@TableName("area")
public class AreaDO implements Serializable {
@TableId
private Integer id;
private String province;
private String city;
private String area;
private String postcode;
@TableLogic
private Boolean del;
}

View File

@ -0,0 +1,73 @@
package com.yulichang.test.springboot3jdk17.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import com.yulichang.test.springboot3jdk17.enums.Sex;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
@Data
@ToString
@Accessors(chain = true)
@EqualsAndHashCode
@TableName(value = "`user`", autoResultMap = true)
public class UserDO implements Serializable {
@TableId
private Integer id;
private Integer pid;
@TableField("`name`")
private String name;
@TableField(value = "`json`", typeHandler = JacksonTypeHandler.class)
private Map<String, String> json;
private Sex sex;
@TableField("head_img")
private String img;
private LocalDateTime createTime;
private Integer addressId;
private Integer addressId2;
@TableLogic
private Boolean del;
private Integer createBy;
@TableField(exist = false)
private String createName;
private Integer updateBy;
@TableField(exist = false)
private String updateName;
@TableField(exist = false)
private String alias;
@TableField(exist = false)
private List<UserDO> children;
@TableField(exist = false)
private List<AddressDO> addressList;
@TableField(exist = false)
private List<AddressDO> addressList2;
}

View File

@ -0,0 +1,31 @@
package com.yulichang.test.springboot3jdk17.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable;
@Data
@TableName("user_dto")
public class UserDto implements Serializable {
@TableId
private Integer id;
private Integer userId;
@TableField(exist = false)
private String userName;
private Integer createBy;
@TableField(exist = false)
private String createName;
private Integer updateBy;
@TableField(exist = false)
private String updateName;
}

View File

@ -0,0 +1,24 @@
package com.yulichang.test.springboot3jdk17.enums;
import com.baomidou.mybatisplus.annotation.EnumValue;
import lombok.Getter;
import lombok.ToString;
@Getter
@ToString
public enum Sex {
MAN(0, ""),
WOMAN(1, "");
@EnumValue
private final int code;
private final String des;
Sex(int code, String des) {
this.code = code;
this.des = des;
}
}

View File

@ -0,0 +1,9 @@
package com.yulichang.test.springboot3jdk17.mapper;
import com.yulichang.test.springboot3jdk17.entity.AddressDO;
import org.apache.ibatis.annotations.Mapper;
@Mapper
@SuppressWarnings("unused")
public interface AddressMapper extends MyBaseMapper<AddressDO> {
}

View File

@ -0,0 +1,9 @@
package com.yulichang.test.springboot3jdk17.mapper;
import com.yulichang.test.springboot3jdk17.entity.AreaDO;
import org.apache.ibatis.annotations.Mapper;
@Mapper
@SuppressWarnings("unused")
public interface AreaMapper extends MyBaseMapper<AreaDO> {
}

View File

@ -0,0 +1,14 @@
package com.yulichang.test.springboot3jdk17.mapper;
import com.github.yulichang.base.MPJBaseMapper;
import org.apache.ibatis.annotations.Mapper;
import java.io.Serializable;
import java.util.List;
@Mapper
@SuppressWarnings("unused")
public interface MyBaseMapper<T extends Serializable> extends MPJBaseMapper<T> {
int insertBatchSomeColumn(List<T> entityList);
}

View File

@ -0,0 +1,9 @@
package com.yulichang.test.springboot3jdk17.mapper;
import com.github.yulichang.base.MPJBaseMapper;
import com.yulichang.test.springboot3jdk17.entity.UserDto;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserDTOMapper extends MPJBaseMapper<UserDto> {
}

View File

@ -0,0 +1,9 @@
package com.yulichang.test.springboot3jdk17.mapper;
import com.yulichang.test.springboot3jdk17.entity.UserDO;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserMapper extends MyBaseMapper<UserDO> {
}

View File

@ -0,0 +1,8 @@
package com.yulichang.test.springboot3jdk17.service;
import com.github.yulichang.base.MPJBaseService;
import com.yulichang.test.springboot3jdk17.entity.UserDO;
public interface UserService extends MPJBaseService<UserDO> {
}

View File

@ -0,0 +1,12 @@
package com.yulichang.test.springboot3jdk17.service.impl;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.yulichang.test.springboot3jdk17.entity.UserDO;
import com.yulichang.test.springboot3jdk17.mapper.UserMapper;
import com.yulichang.test.springboot3jdk17.service.UserService;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl extends MPJBaseServiceImpl<UserMapper, UserDO> implements UserService {
}

View File

@ -0,0 +1,22 @@
package com.yulichang.test.springboot3jdk17.util;
public class ThreadLocalUtils {
private final static ThreadLocal<String> userThreadLocal = new ThreadLocal<>();
/**
* 设置数据到当前线程
*/
public static void set(String sql) {
userThreadLocal.set(sql);
}
/**
* 获取线程中的数据
*/
public static String get() {
String s = userThreadLocal.get();
set(null);
return s;
}
}

View File

@ -0,0 +1,28 @@
#file: noinspection SpringBootApplicationYaml
spring:
datasource:
driver-class-name: org.h2.Driver
url: jdbc:h2:mem:test
username: root
password: test
sql:
init:
schema-locations: classpath:db/schema.sql
data-locations: classpath:db/data.sql
mybatis-plus:
typeEnumsPackage: com.github.yulichang.test
global-config:
db-config:
logic-delete-field: del
logic-delete-value: true
logic-not-delete-value: false
banner: true
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# 打印 mybatis plus join banner
mybatis-plus-join:
banner: true
sub-table-logic: true
ms-cache: true

View File

@ -0,0 +1,91 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
DELETE FROM area;
INSERT INTO area (id, province, city, area, postcode, del) VALUES (10001, '北京市01', '北京01', '朝阳01', '80001', false);
INSERT INTO area (id, province, city, area, postcode, del) VALUES (10002, '北京市02', '北京02', '朝阳02', '80002', false);
INSERT INTO area (id, province, city, area, postcode, del) VALUES (10003, '北京市03', '北京03', '朝阳03', '80003', false);
INSERT INTO area (id, province, city, area, postcode, del) VALUES (10004, '北京市04', '北京04', '朝阳04', '80004', false);
INSERT INTO area (id, province, city, area, postcode, del) VALUES (10005, '北京市05', '北京05', '朝阳05', '80005', false);
INSERT INTO area (id, province, city, area, postcode, del) VALUES (10006, '北京市06', '北京06', '朝阳06', '80006', false);
INSERT INTO area (id, province, city, area, postcode, del) VALUES (10007, '北京市07', '北京07', '朝阳07', '80007', false);
INSERT INTO area (id, province, city, area, postcode, del) VALUES (10008, '北京市08', '北京08', '朝阳08', '80008', false);
INSERT INTO area (id, province, city, area, postcode, del) VALUES (10009, '北京市09', '北京09', '朝阳09', '80009', false);
INSERT INTO area (id, province, city, area, postcode, del) VALUES (10010, '北京市10', '北京10', '朝阳10', '80010', false);
INSERT INTO area (id, province, city, area, postcode, del) VALUES (10011, '北京市11', '北京11', '朝阳11', '80011', false);
INSERT INTO area (id, province, city, area, postcode, del) VALUES (10012, '北京市12', '北京12', '朝阳12', '80012', false);
INSERT INTO area (id, province, city, area, postcode, del) VALUES (10013, '北京市13', '北京13', '朝阳13', '80013', false);
INSERT INTO area (id, province, city, area, postcode, del) VALUES (10014, '北京市14', '北京14', '朝阳14', '80014', false);
INSERT INTO area (id, province, city, area, postcode, del) VALUES (10015, '北京市15', '北京15', '朝阳15', '80015', false);
INSERT INTO area (id, province, city, area, postcode, del) VALUES (10016, '北京市16', '北京16', '朝阳16', '80016', false);
INSERT INTO area (id, province, city, area, postcode, del) VALUES (10017, '北京市17', '北京17', '朝阳17', '80017', false);
INSERT INTO area (id, province, city, area, postcode, del) VALUES (10018, '北京市18', '北京18', '朝阳18', '80018', false);
INSERT INTO area (id, province, city, area, postcode, del) VALUES (10019, '北京市19', '北京19', '朝阳19', '80019', false);
INSERT INTO area (id, province, city, area, postcode, del) VALUES (10020, '北京市20', '北京20', '朝阳20', '80020', false);
INSERT INTO area (id, province, city, area, postcode, del) VALUES (10021, '北京市21', '北京21', '朝阳21', '80021', false);
INSERT INTO area (id, province, city, area, postcode, del) VALUES (10022, '北京市22', '北京22', '朝阳22', '80022', false);
DELETE FROM `user`;
INSERT INTO `user` (id, pid, `name`, `json`, `address_id`, address_id2 , sex, head_img, create_time, create_by, update_by, del) VALUES
( 1, 1, '张三 1', '{"id": 1,"name":"张三 1"}', 1, 2, 1, 'https://url-01', '2022-01-01 12:00:00', 1, 2, false),
( 2, 1, '张三 2', '{"id": 2,"name":"张三 2"}', 1, 2, 0, 'https://url-02', '2022-01-01 12:00:00', 2, 3, false),
( 3, 1, '张三 3', '{"id": 3,"name":"张三 3"}', 1, 2, 0, 'https://url-03', '2022-01-01 12:00:00', 3, 2, false),
( 4, 1, '张三 4', '{"id": 4,"name":"张三 4"}', 1, 2, 0, 'https://url-04', '2022-01-01 12:00:00', 9, 2, false),
( 5, 1, '张三 5', '{"id": 5,"name":"张三 5"}', 1, 2, 0, 'https://url-05', '2022-01-01 12:00:00', 1, 2, false),
( 6, 1, '张三 6', '{"id": 6,"name":"张三 6"}', 1, 2, 0, 'https://url-06', '2022-01-01 12:00:00', 1, 2, false),
( 7, 1, '张三 7', '{"id": 7,"name":"张三 7"}', 1, 2, 0, 'https://url-07', '2022-01-01 12:00:00', 1, 2, false),
( 8, 1, '张三 8', '{"id": 8,"name":"张三 8"}', 1, 2, 0, 'https://url-08', '2022-01-01 12:00:00', 1, 2, false),
( 9, 1, '张三 9', '{"id": 9,"name":"张三 9"}', 1, 2, 0, 'https://url-09', '2022-01-01 12:00:00', 1, 2, false),
(10, 1, '张三10', '{"id":10,"name":"张三10"}', 1, 2, 0, 'https://url-10', '2022-01-01 12:00:00', 1, 2, true ),
(11, 1, '张三11', '{"id":11,"name":"张三11"}', 1, 2, 0, 'https://url-11', '2022-01-01 12:00:00', 1, 2, true ),
(12, 1, '张三12', '{"id":12,"name":"张三12"}', 1, 2, 0, 'https://url-12', '2022-01-01 12:00:00', 1, 2, true ),
(13, 1, '张三13', '{"id":13,"name":"张三13"}', 1, 2, 0, 'https://url-13', '2022-01-01 12:00:00', 1, 2, true ),
(14, 2, '张三14', '{"id":14,"name":"张三14"}', 1, 2, 0, 'https://url-14', '2022-01-01 12:00:00', 1, 2, false),
(15, 2, '张三15', '{"id":15,"name":"张三15"}', 1, 2, 0, 'https://url-15', '2022-01-01 12:00:00', 1, 2, false),
(16, 2, '张三16', '{"id":16,"name":"张三16"}', 1, 2, 0, 'https://url-16', '2022-01-01 12:00:00', 1, 2, false),
(17, 2, '张三17', '{"id":17,"name":"张三17"}', 1, 2, 0, 'https://url-17', '2022-01-01 12:00:00', 1, 2, false),
(18, 2, '张三18', '{"id":18,"name":"张三18"}', 1, 2, 0, 'https://url-18', '2022-01-01 12:00:00', 1, 2, false),
(19, 2, '张三19', '{"id":19,"name":"张三19"}', 1, 2, 0, 'https://url-19', '2022-01-01 12:00:00', 1, 2, true ),
(20, 2, '张三20', '{"id":20,"name":"张三20"}', 1, 2, 0, 'https://url-20', '2022-01-01 12:00:00', 1, 2, true ),
(21, 2, '张三21', '{"id":21,"name":"张三21"}', 1, 2, 0, 'https://url-21', '2022-01-01 12:00:00', 1, 2, true ),
(22, 2, '张三22', '{"id":22,"name":"张三22"}', 1, 2, 0, 'https://url-22', '2022-01-01 12:00:00', 1, 2, true );
DELETE FROM address;
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES ( 1, 1, 10001, '10000000001', '朝阳01', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES ( 2, 1, 10002, '10000000002', '朝阳02', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES ( 3, 1, 10003, '10000000003', '朝阳03', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES ( 4, 1, 10004, '10000000004', '朝阳04', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES ( 5, 1, 10005, '10000000005', '朝阳05', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES ( 6, 1, 10006, '10000000006', '朝阳06', true );
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES ( 7, 1, 10007, '10000000007', '朝阳07', true );
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES ( 8, 1, 10008, '10000000008', '朝阳08', true );
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES ( 9, 1, 10009, '10000000009', '朝阳09', true );
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES (10,10, 10010, '10000000010', '朝阳10', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES (11,11, 10011, '10000000011', '朝阳11', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES (12,12, 10012, '10000000012', '朝阳12', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES (13,13, 10013, '10000000013', '朝阳13', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES (14,14, 10014, '10000000014', '朝阳14', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES (15,15, 10015, '10000000015', '朝阳15', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES (16,16, 10016, '10000000016', '朝阳16', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES (17,17, 10017, '10000000017', '朝阳17', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES (18,18, 10018, '10000000018', '朝阳18', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES (19,19, 10019, '10000000019', '朝阳19', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES (20,20, 10020, '10000000020', '朝阳20', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES (21,21, 10021, '10000000021', '朝阳21', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES (22,22, 10022, '10000000022', '朝阳22', false);
DELETE FROM user_dto;
INSERT INTO user_dto (id, user_id, create_by, update_by, del) VALUES
(1,1, 2, 3, false),
(2,1, 2, 3, false),
(3,1, 2, 3, false),
(4,1, 2, 3, false),
(5,2, 2, 3, false),
(6,2, 2, 3, false),
(7,2, 2, 3, false),
(8,2, 2, 3, false);

View File

@ -0,0 +1,58 @@
-- noinspection SqlDialectInspectionForFile
-- noinspection SqlNoDataSourceInspectionForFile
DROP TABLE IF EXISTS area;
create table area
(
id int auto_increment
primary key,
province varchar(255) null,
city varchar(255) null,
area varchar(255) null,
postcode varchar(255) null,
del bit
);
DROP TABLE IF EXISTS `user`;
create table `user`
(
id int auto_increment
primary key,
`pid` int not null,
`name` varchar(255) not null,
`json` varchar(255) not null,
`address_id` int not null,
`address_id2` int not null,
sex tinyint not null,
head_img varchar(255) not null,
create_time datetime not null,
create_by int not null,
update_by int not null,
del bit
);
DROP TABLE IF EXISTS address;
create table address
(
id int auto_increment
primary key,
user_id int null,
area_id int null,
tel varchar(255) null,
address varchar(255) null,
del bit
);
create table user_dto
(
id int auto_increment
primary key,
user_id int not null,
create_by int not null,
update_by int not null,
del bit null
);

View File

@ -0,0 +1,67 @@
package com.yulichang.test.springboot3jdk17;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.yulichang.test.springboot3jdk17.entity.UserDO;
import com.yulichang.test.springboot3jdk17.entity.UserDto;
import com.yulichang.test.springboot3jdk17.mapper.UserDTOMapper;
import com.yulichang.test.springboot3jdk17.mapper.UserMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
/**
* springboot3 & jdk17+
*/
@SuppressWarnings("unused")
@SpringBootTest
class UpdateWrapperTest {
@Autowired
private UserMapper userMapper;
@Autowired
private UserDTOMapper userDTOMapper;
/**
* 逻辑删除
*/
@Test
public void testUpdate() {
MPJLambdaWrapper<UserDO> wrapper = new MPJLambdaWrapper<UserDO>()
.eq(UserDO::getId, 1);
userMapper.delete(wrapper);
assert userMapper.selectById(1) == null;
}
/**
* 非逻辑删除
*/
@Test
public void testUpdate1() {
MPJLambdaWrapper<UserDto> wrapper = new MPJLambdaWrapper<>();
wrapper.eq(UserDto::getId, 1);
userDTOMapper.delete(wrapper);
assert userDTOMapper.selectById(1) == null;
}
/**
* 修改
*/
@Test
public void testUpdate2() {
// MPJLambdaWrapper<UserDto> wrapper = new MPJLambdaWrapper<UserDto>()
// .leftJoin(UserDO.class, UserDO::getId, UserDto::getUserId)
// .eq(UserDto::getId, 1);
MPJLambdaWrapper<UserDto> wrapper = new MPJLambdaWrapper<>();
wrapper.eq(UserDto::getId, 1);
userDTOMapper.update(new UserDto() {{
setUserId(2222);
}}, wrapper);
}
}