init
This commit is contained in:
47
src/main/java/com/newyetai/mybatis/config/MybatisConfig.java
Normal file
47
src/main/java/com/newyetai/mybatis/config/MybatisConfig.java
Normal file
@@ -0,0 +1,47 @@
|
||||
package com.newyetai.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.newyetai.mybatis.handle.BaseEnumTypeHandler;
|
||||
import com.newyetai.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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.newyetai.mybatis.converters;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
import com.newyetai.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);
|
||||
}
|
||||
}
|
||||
11
src/main/java/com/newyetai/mybatis/handle/BaseEnum.java
Normal file
11
src/main/java/com/newyetai/mybatis/handle/BaseEnum.java
Normal file
@@ -0,0 +1,11 @@
|
||||
package com.newyetai.mybatis.handle;
|
||||
|
||||
public interface BaseEnum<T> {
|
||||
|
||||
/**
|
||||
* 获取枚举的值
|
||||
*
|
||||
* @return 枚举的值
|
||||
*/
|
||||
T getValue();
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
package com.newyetai.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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package com.newyetai.mybatis.interceptor;
|
||||
|
||||
import com.github.pagehelper.Page;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.github.pagehelper.PageRowBounds;
|
||||
import com.newyetai.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.Objects;
|
||||
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) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user