This commit is contained in:
ran.shang
2025-12-29 16:06:48 +08:00
parent b853edcfde
commit ee95dfa2c2
1600 changed files with 6997 additions and 7445 deletions

View File

@@ -0,0 +1,47 @@
package com.senmesh.mybatis.config;
import java.util.List;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.type.TypeHandlerRegistry;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import com.github.pagehelper.autoconfigure.PageHelperAutoConfiguration;
import com.senmesh.mybatis.handle.BaseEnumTypeHandler;
import com.senmesh.mybatis.interceptor.MyPageInterceptor;
import lombok.extern.slf4j.Slf4j;
/**
* @author guhong
* @date 2019/8/19
* 设置mapper扫描的包
*/
@Configuration
@Slf4j
public class MybatisConfig {
@Autowired
private List<SqlSessionFactory> sqlSessionFactoryList;
/**
* 添加自定义的分页插件,pageHelper 的分页插件PageInterceptor是用@PostConstruct添加的,自定义的应该在其后面添加
* 真正执行时顺序是反过来,先执行MyPageInterceptor,再执行 PageInterceptor
*
* 所以要保证 PageHelperAutoConfiguration 先执行
*/
@Autowired
public void addPageInterceptor(PageHelperAutoConfiguration pageHelperAutoConfiguration) {
MyPageInterceptor interceptor = new MyPageInterceptor();
for (SqlSessionFactory sqlSessionFactory : sqlSessionFactoryList) {
sqlSessionFactory.getConfiguration().addInterceptor(interceptor);
log.info("注册自定义分页插件成功");
// 取得类型转换注册器
TypeHandlerRegistry typeHandlerRegistry = sqlSessionFactory.getConfiguration().getTypeHandlerRegistry();
// 注册默认枚举转换器
typeHandlerRegistry.setDefaultEnumTypeHandler(BaseEnumTypeHandler.class);
}
}
}

View File

@@ -0,0 +1,35 @@
package com.senmesh.mybatis.converters;
import com.google.common.collect.Sets;
import com.senmesh.mybatis.handle.BaseEnum;
import java.util.Arrays;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.GenericConverter;
/**
* @description: baseEnum转换
* @author: chenyun.huang
* @create: 2021-04-01 11:52
**/
public class ObjectToBaseEnumConverter implements GenericConverter {
@Override
public Set<ConvertiblePair> getConvertibleTypes() {
return Sets.newHashSet(new ConvertiblePair(Integer.class, BaseEnum.class),new ConvertiblePair(String.class, BaseEnum.class));
}
@Override
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
if (Objects.isNull(source)){
return null;
}
Class<? extends BaseEnum> type = (Class<? extends BaseEnum>) targetType.getType();
BaseEnum[] enumConstants = type.getEnumConstants();
Map<Object, BaseEnum> collect = Arrays.stream(enumConstants)
.collect(Collectors.toMap(BaseEnum::getValue, v -> v, (v1, v2) -> v2));
return collect.get(source);
}
}

View File

@@ -0,0 +1,11 @@
package com.senmesh.mybatis.handle;
public interface BaseEnum<T> {
/**
* 获取枚举的值
*
* @return 枚举的值
*/
T getValue();
}

View File

@@ -0,0 +1,103 @@
package com.senmesh.mybatis.handle;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.Objects;
/**
* @description: 通用枚举转换
* @author: chenyun.huang
* @create: 2020-04-14 20:00
**/
@MappedJdbcTypes(value = JdbcType.VARCHAR, includeNullJdbcType = true)
@MappedTypes({BaseEnum.class})
public class BaseEnumTypeHandler<E extends Enum<?> & BaseEnum> extends BaseTypeHandler<E> {
/**
* 枚举的class
*/
private Class<E> type;
/**
* 枚举的每个子类枚
*/
private E[] enums;
/**
* 一定要有默认的构造函数,不然抛出 not found method 异常
*/
public BaseEnumTypeHandler() {
}
/**
* 设置配置文件设置的转换类以及枚举类内容,供其他方法更便捷高效的实现
*
* @param type 配置文件中设置的转换类
*/
public BaseEnumTypeHandler(Class<E> type) {
if (type == null) {
throw new IllegalArgumentException("Type argument cannot be null");
}
this.type = type;
this.enums = type.getEnumConstants();
if (this.enums == null) {
throw new IllegalArgumentException(type.getSimpleName()
+ " does not represent an enum type.");
}
}
@Override
public void setNonNullParameter(PreparedStatement ps, int i, E parameter,
JdbcType jdbcType) throws SQLException {
/*
* BaseTypeHandler已经帮我们做了parameter的null判断
* 数据库存储的是枚举的值,所以我们这里使用 value , 如果需要存储 name,可以自定义修改
*/
if (jdbcType == null) {
Object value = parameter.getValue();
ps.setString(i, Objects.toString(value));
} else {
ps.setObject(i, parameter.getValue(), jdbcType.TYPE_CODE);
}
}
@Override
public E getNullableResult(ResultSet rs, String columnName)
throws SQLException {
return locateEnumStatus(rs.getString(columnName));
}
@Override
public E getNullableResult(ResultSet rs, int columnIndex)
throws SQLException {
return locateEnumStatus(rs.getString(columnIndex));
}
@Override
public E getNullableResult(CallableStatement cs, int columnIndex)
throws SQLException {
return locateEnumStatus(cs.getString(columnIndex));
}
/**
* 枚举类型转换,由于构造函数获取了枚举的子类 enums,让遍历更加高效快捷,
* <p>
* 我将取出来的值 全部转换成字符串 进行比较,
*
* @param value 数据库中存储的自定义value属性
* @return value 对应的枚举类
*/
private E locateEnumStatus(String value) {
return Arrays.stream(enums)
.filter(e -> Objects.toString(e.getValue()).equals(value))
.findFirst()
.orElse(null);
}
}

View File

@@ -0,0 +1,87 @@
package com.senmesh.mybatis.interceptor;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageRowBounds;
import com.senmesh.common.dto.IPage;
import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import java.util.List;
import java.util.Map;
import java.util.Properties;
/**
* @author guhong
* @date 2019/8/19
*/
@Intercepts({
@Signature(type = Executor.class, method = "query",
args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),
@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class,
RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class}),})
public class MyPageInterceptor implements Interceptor {
@SuppressWarnings({"unchecked", "rawtypes"})
@Override
public Object intercept(Invocation invocation) throws Throwable {
Object[] args = invocation.getArgs();
Object parameter = args[1];
IPage<?> page = null;
if (parameter instanceof IPage) {
page = (IPage<?>) parameter;
} else if (parameter instanceof Map) {
for (Map.Entry<String, Object> entry : ((Map<String, Object>) parameter).entrySet()) {
Object value = entry.getValue();
if (value instanceof IPage) {
page = (IPage) value;
break;
}
}
}
PageRowBounds pageRowBounds = null;
if (page != null && page.getNeedPage() && page.getPageSize() > 0) {
pageRowBounds =
new PageRowBounds(page.getPageSize() * (page.getPageNo() - 1), page.getPageSize());
pageRowBounds.setCount(true);
args[2] = pageRowBounds;
}
// 判断pageSize=0,兼容老版本=0不分页
Page pageHelperPage = PageHelper.getLocalPage();
if (pageHelperPage != null && pageHelperPage.getPageSize() == 0) {
PageHelper.clearPage();
}
Object value = invocation.proceed();
if (page != null && page.getNeedPage() && page.getPageSize() > 0) {
page.setPageResult(pageRowBounds.getTotal().intValue(), (List)value);
}
return value;
}
@Override
public Object plugin(Object target) {
if (target instanceof Executor) {
return Plugin.wrap(target, this);
} else {
return target;
}
}
@Override
public void setProperties(Properties properties) {
}
}