springboot 接入通用tkmapper和pagehelper,boot starter版,mysql5.7,boot2.7.9
xml版本查看:https://www.cnblogs.com/binz/p/6564490.html
springboot3.x以前的版本查看 https://www.cnblogs.com/binz/p/17421063.html
springboot3.x查看 https://www.cnblogs.com/binz/p/17654403.html
1、pom文件引入
<dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>1.4.6</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.27</version> </dependency> <dependency> <groupId>tk.mybatis</groupId> <artifactId>mapper-spring-boot-starter</artifactId> <version>4.2.2</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.11</version> </dependency> <dependency> <groupId>tk.mybatis</groupId> <artifactId>mapper-base</artifactId> <version>1.0.0</version> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> </dependency>
2、yuml配置文件
mapper:
enum-as-simple-type: true #开启枚举转字符串
mybatis:
mapper-locations: classpath*:mapper/*Mapper.xml
type-aliases-package: com.xxx.*.model
configuration:
map-underscore-to-camel-case: true #开启驼峰下划线互转
3、再启动配置或者在有@Configuration注解的类上添加@MapperScan(basePackages="com.xxxx.*.mapper"),例如
import org.springframework.context.annotation.Configuration;
import tk.mybatis.spring.annotation.MapperScan; @Configuration @MapperScan(basePackages="com.xxxx.*.mapper") public class MapperBeanInit { }
4、创建BaseMapper合并多个常用mapper
import java.io.Serializable; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.List; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.session.RowBounds; import com.github.pagehelper.Page; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ReflectUtil; import tk.mybatis.mapper.additional.select.SelectByPropertyMapper; import tk.mybatis.mapper.common.Mapper; import tk.mybatis.mapper.common.special.InsertListMapper; import tk.mybatis.mapper.lambda.WrapperLambdaDelete; import tk.mybatis.mapper.lambda.WrapperLambdaQuery; import tk.mybatis.mapper.lambda.WrapperLambdaUpdate; import tk.mybatis.mapper.weekend.Fn; import tk.mybatis.mapper.weekend.Weekend; public interface BaseMapper<T> extends Mapper<T>, InsertListMapper<T>,SelectByPropertyMapper<T>{ default <RE extends Serializable> RE selectByPrimaryKey(Object key,Class<RE> returnClass) { T t = selectByPrimaryKey(key); return covert(t,returnClass); } default <RE extends Serializable> RE selectOne(T t,Class<RE> returnClass) { t = selectOne(t); return covert(t,returnClass); } default <RE extends Serializable> List<RE> select(T t,Class<RE> returnClass) { List<T> ts = select(t); return covertList(ts,returnClass); } default <RE extends Serializable> Page<RE> selectPage(T t,Class<RE> returnClass) { Page<T> ts = (Page<T>) select(t); return (Page<RE>) covertList(ts,returnClass); } default <RE extends Serializable> Page<RE> selectPageByExample(Object example,Class<RE> returnClass) { Page<T> ts = (Page<T>) selectByExample(example); return (Page<RE>) covertList(ts,returnClass); } default <RE extends Serializable> List<RE> selectAll(Class<RE> returnClass) { List<T> ts = selectAll(); return covertList(ts,returnClass); } default <RE extends Serializable> List<RE> selectByExample(Object example,Class<RE> returnClass) { List<T> ts = selectByExample(example); return covertList(ts,returnClass); } default <RE extends Serializable> RE selectOneByExample(Object example,Class<RE> returnClass) { T ts = selectOneByExample(example); return covert(ts,returnClass); } default <RE extends Serializable> RE selectOneByExampleLimitOne(Weekend<T> example,Class<RE> returnClass) { RowBounds rowBounds = new RowBounds(0, 1); List<T> ts = selectByExampleAndRowBounds(example, rowBounds); List<RE> covertList = covertList(ts,returnClass); if(ObjectUtil.isNotEmpty(covertList)) { return covertList.get(0); } return null; } default T selectOneByExampleLimitOne(Weekend<T> example) { RowBounds rowBounds = new RowBounds(0, 1); List<T> ts = selectByExampleAndRowBounds(example, rowBounds); if(ObjectUtil.isNotEmpty(ts)) { return ts.get(0); } return null; } default T selectOneByLimitOne(T t) { RowBounds rowBounds = new RowBounds(0, 1); List<T> ts = selectByRowBounds(t,rowBounds); if(ObjectUtil.isNotEmpty(ts)) { return ts.get(0); } return null; } default <RE extends Serializable> List<RE> selectByProperty(@Param("fn") Fn<T, ?> fn, @Param("value") Object value,Class<RE> returnClass){ List<T> ts = selectByProperty(fn, value); return covertList(ts, returnClass); } default <RE extends Serializable> RE selectOneByProperty(@Param("fn") Fn<T, ?> fn, @Param("value") Object value,Class<RE> returnClass){ T t = selectOneByProperty(fn, value); return covert(t, returnClass); } default <RE extends Serializable> List<RE> selectInByProperty(Fn<T, ?> fn, List<?> values,Class<RE> returnClass) { List<T> ts = selectInByProperty(fn, values); return covertList(ts, returnClass); } @SuppressWarnings("unchecked") default Class<T> thisTClass() { Class<?> class1 = getClass(); Class<?> interfaces = class1.getInterfaces()[0]; Type[] genericInterfaces = interfaces.getGenericInterfaces(); Type type = genericInterfaces[0]; if( type instanceof ParameterizedType){ ParameterizedType pType = (ParameterizedType) type; Type clazz = pType.getActualTypeArguments()[0]; if( clazz instanceof Class<?> ){ return (Class<T>) clazz; } } return null; } default <RE extends Serializable> List<RE> covertList(List<T> ts,Class<RE> returnClass){ List<RE> responses; if(ts instanceof Page) { responses = new Page<>(); }else { responses = new ArrayList<>(); } for (T t : ts) { responses.add(covert(t,returnClass)); } return responses; } default <RE extends Serializable> RE covert(T t , Class<RE> returnClass) { if(t != null) { RE response = null; try { response = ReflectUtil.newInstanceIfPossible(returnClass); BeanUtil.copyProperties(t, response); } catch (Exception e) { e.printStackTrace(); } return response; } return null; } //以下是我自己扩展的,类似于mybatisplus用法,不需要可以删除,在通用mapper新版已经直接提供类似用法,https://mapper.mybatis.io/ default WrapperLambdaQuery<T> lambdaQuery(){ return new WrapperLambdaQuery<T>(this,thisTClass()); } default WrapperLambdaUpdate<T> lambdaUpdate(){ return new WrapperLambdaUpdate<T>(this,thisTClass()); } default WrapperLambdaDelete<T> lambdaDelete(){ return new WrapperLambdaDelete<T>(this,thisTClass()); } }
5、使用示例
@Service public class UserServiceImpl implements UserService{ @Autowired private UserMapper userMapper; @Override public UserVO getById(Long userId) { return userMapper.selectByPrimaryKey(userId, UserVO.class); } @Override public UserVO getById_plus(Long userId) { return userMapper.lambdaQuery().eq(User::getId, userId).one(UserVO.class); } }
6、其他扩展类FnGet、WrapperLambda、WrapperLambdaQuery、WrapperLambdaUpdate、WrapperLambdaDelete,新建并放入包tk.mybatis.mapper.lambda
FnGet
package tk.mybatis.mapper; import java.util.ArrayList; import java.util.List; import tk.mybatis.mapper.weekend.Fn; import tk.mybatis.mapper.weekend.reflection.Reflections; /** * 获取get,is方法的属性 */ public class FnGet{ public static <T,R> String fieldName(Fn<T,R> fn) { return Reflections.fnToFieldName(fn); } @SafeVarargs public static <T,R> String[] fieldNames(Fn<T,R> ... fns) { List<String> fields = new ArrayList<>(fns.length); for (Fn<T,R> fn : fns) { fields.add(fieldName(fn)); } return fields.toArray(new String[] {}); } }
WrapperLambda
import com.xxx.BaseMapper; import cn.hutool.core.util.StrUtil; import tk.mybatis.mapper.weekend.Fn; import tk.mybatis.mapper.weekend.Weekend; import tk.mybatis.mapper.weekend.WeekendCriteria; import tk.mybatis.mapper.weekend.reflection.Reflections; class WrapperLambda<T,W extends WrapperLambda<T,W>> { private W w; protected Weekend<T> exampe; protected BaseMapper<T> mapper; protected WeekendCriteria<T,Object> weekendCriteria; protected Class<T> entityClass; WrapperLambda(BaseMapper<T> mapper,Class<T> entityClass){ this.mapper = mapper; this.exampe = Weekend.of(entityClass); this.entityClass = entityClass; this.weekendCriteria = exampe.weekendCriteria(); } public void setW(W w) { this.w = w; } public W eq(Fn<T, Object> fn, Object value) { weekendCriteria.andEqualTo(Reflections.fnToFieldName(fn), value); return w; } public W ne(Fn<T, Object> fn, Object value) { weekendCriteria.andNotEqualTo(Reflections.fnToFieldName(fn), value); return w; } public W isNull(Fn<T, Object> fn) { weekendCriteria.andIsNull(Reflections.fnToFieldName(fn)); return w; } public W isNotNull(Fn<T, Object> fn) { weekendCriteria.andIsNotNull(Reflections.fnToFieldName(fn)); return w; } /** * 大于 */ public W gt(Fn<T, Object> fn, Object value) { weekendCriteria.andGreaterThan(Reflections.fnToFieldName(fn), value); return w; } /** * 大于等于 */ public W ge(Fn<T, Object> fn, Object value) { weekendCriteria.andGreaterThanOrEqualTo(Reflections.fnToFieldName(fn), value); return w; } /** * 小于 */ public W lt(Fn<T, Object> fn, Object value) { weekendCriteria.andLessThan(Reflections.fnToFieldName(fn), value); return w; } /** * 小于等于 */ public W le(Fn<T, Object> fn, Object value) { weekendCriteria.andLessThanOrEqualTo(Reflections.fnToFieldName(fn), value); return w; } public W in(Fn<T, Object> fn, @SuppressWarnings("rawtypes") Iterable values) { weekendCriteria.andIn(Reflections.fnToFieldName(fn), values); return w; } public W notIn(Fn<T, Object> fn, @SuppressWarnings("rawtypes") Iterable values) { weekendCriteria.andNotIn(Reflections.fnToFieldName(fn), values); return w; } public W between(Fn<T, Object> fn, Object value1, Object value2) { weekendCriteria.andBetween(Reflections.fnToFieldName(fn), value1, value2); return w; } public W notBetween(Fn<T, Object> fn, Object value1, Object value2) { weekendCriteria.andNotBetween(Reflections.fnToFieldName(fn), value1, value2); return w; } public W leftLike(Fn<T, Object> fn, String value) { if(StrUtil.isNotBlank(value)) { weekendCriteria.andLike(Reflections.fnToFieldName(fn), "%" + value); } return w; } public W rightLike(Fn<T, Object> fn, String value) { if(StrUtil.isNotBlank(value)) { weekendCriteria.andLike(Reflections.fnToFieldName(fn), value + "%"); } return w; } public W like(Fn<T, Object> fn, String value) { if(StrUtil.isNotBlank(value)) { weekendCriteria.andLike(Reflections.fnToFieldName(fn),"%" + value +"%"); } return w; } public W notLike(Fn<T, Object> fn, String value) { if(StrUtil.isNotBlank(value)) { weekendCriteria.andNotLike(Reflections.fnToFieldName(fn),"%" + value +"%"); } return w; } public W orIsNull(Fn<T, Object> fn) { weekendCriteria.orIsNull(Reflections.fnToFieldName(fn)); return w; } public W orIsNotNull(Fn<T, Object> fn) { weekendCriteria.orIsNotNull(Reflections.fnToFieldName(fn)); return w; } /** * 或者相等 */ public W orEq(Fn<T, Object> fn, Object value) { weekendCriteria.orEqualTo(Reflections.fnToFieldName(fn), value); return w; } /** * 或者不等于 */ public W orNe(Fn<T, Object> fn, Object value) { weekendCriteria.orNotEqualTo(Reflections.fnToFieldName(fn), value); return w; } /** * 或者大于 */ public W orGt(Fn<T, Object> fn, Object value) { weekendCriteria.orGreaterThan(Reflections.fnToFieldName(fn), value); return w; } /** * 或者大于等于 */ public W orGe(Fn<T, Object> fn, Object value) { weekendCriteria.orGreaterThanOrEqualTo(Reflections.fnToFieldName(fn), value); return w; } /** * 或者小于 */ public W orLt(Fn<T, Object> fn, Object value) { weekendCriteria.orLessThan(Reflections.fnToFieldName(fn), value); return w; } /** * 或者小于等于 */ public W orLe(Fn<T, Object> fn, Object value) { weekendCriteria.orLessThanOrEqualTo(Reflections.fnToFieldName(fn), value); return w; } public W orIn(Fn<T, Object> fn, @SuppressWarnings("rawtypes") Iterable values) { weekendCriteria.orIn(Reflections.fnToFieldName(fn), values); return w; } public W orNotIn(Fn<T, Object> fn, @SuppressWarnings("rawtypes") Iterable values) { weekendCriteria.orNotIn(Reflections.fnToFieldName(fn), values); return w; } public W orBetween(Fn<T, Object> fn, Object value1, Object value2) { weekendCriteria.orBetween(Reflections.fnToFieldName(fn), value1, value2); return w; } public W orNotBetween(Fn<T, Object> fn, Object value1, Object value2) { weekendCriteria.orNotBetween(Reflections.fnToFieldName(fn), value1, value2); return w; } public W orLike(Fn<T, Object> fn, String value) { if(StrUtil.isNotBlank(value)) { weekendCriteria.orLike(Reflections.fnToFieldName(fn),"%" + value +"%"); } return w; } public W orNotLike(Fn<T, Object> fn, String value) { if(StrUtil.isNotBlank(value)) { weekendCriteria.orNotLike(Reflections.fnToFieldName(fn),"%" + value +"%"); } return w; } public W and(W wrapperLambda){ exampe.and(wrapperLambda.weekendCriteria); return w; } public W or(W wrapperLambda){ exampe.or(wrapperLambda.weekendCriteria); return w; } }
WrapperLambdaQuery
import java.io.Serializable; import java.util.List; import org.apache.ibatis.session.RowBounds; import com.xxx.BaseMapper; import com.xxx.BeanUtil; import com.github.pagehelper.Page; import tk.mybatis.mapper.FnGet; import tk.mybatis.mapper.weekend.Fn; import tk.mybatis.mapper.weekend.reflection.Reflections; public final class WrapperLambdaQuery<T> extends WrapperLambda<T,WrapperLambdaQuery<T>>{ public WrapperLambdaQuery(BaseMapper<T> mapper,Class<T> entityClass){ super(mapper, entityClass); setW(this); } /** * 排除查询字段,优先级低于 selectProperties * * @param fns 属性名的可变参数 * @return */ @SafeVarargs public final <R> WrapperLambdaQuery<T> excludeProperties(Fn<T, R>... fns) { String[] properties = FnGet.fieldNames(fns); exampe.excludeProperties(properties); return this; } /** * 指定要查询的属性列 - 这里会自动映射到表字段 * * @param fns * @return */ @SafeVarargs public final <R> WrapperLambdaQuery<T> selectProperties(Fn<T, R>... fns) { String[] properties = FnGet.fieldNames(fns); exampe.selectProperties(properties); return this; } public WrapperLambdaQuery<T> orderBy(Fn<T, ?> fn) { exampe.orderBy(Reflections.fnToFieldName(fn)); return this; } public WrapperLambdaQuery<T> orderDescBy(Fn<T, ?> fn) { exampe.orderBy(Reflections.fnToFieldName(fn)).desc(); return this; } public List<T> list(){ return mapper.selectByExample(exampe); } public Page<T> listPage(){ List<T> ts = mapper.selectByExample(exampe); Page<T> pageRes = new Page<>(); pageRes.addAll(ts); if(ts instanceof Page) { pageRes.setTotal(((Page<T>) ts).getTotal()); return pageRes; } return pageRes; } public <RE extends Serializable> List<RE> list(Class<RE> returnClass){ List<T> ts = mapper.selectByExample(exampe); List<RE> res = BeanUtil.copys(ts, returnClass); if(ts instanceof Page) { Page<RE> pageRes = new Page<>(); pageRes.addAll(res); pageRes.setTotal(((Page<T>) ts).getTotal()); return pageRes; } return res; } public <RE extends Serializable> Page<RE> listPage(Class<RE> returnClass){ List<T> ts = (List<T>) mapper.selectByExample(exampe); List<RE> res = BeanUtil.copys(ts, returnClass); Page<RE> pageRes = new Page<>(); pageRes.addAll(res); if(ts instanceof Page) { pageRes.setTotal(((Page<T>) ts).getTotal()); return pageRes; } return pageRes; } public T one(){ return mapper.selectOneByExample(exampe); } public <RE extends Serializable> RE one(Class<RE> returnClass){ T one = one(); if(one == null) { return null; } return BeanUtil.copy(one, returnClass); } public List<T> listLimit(Integer limit){ RowBounds rowBounds = new RowBounds(0, limit); List<T> ts = mapper.selectByExampleAndRowBounds(exampe,rowBounds); return ts; } public <RE extends Serializable> List<RE> listLimit(Integer limit,Class<RE> returnClass){ List<T> ts = listLimit(limit); List<RE> res = BeanUtil.copys(ts, returnClass); return res; } public T oneLimit(){ List<T> ts = listLimit(1); return ts.isEmpty() ? null : ts.get(0); } public <RE extends Serializable> RE oneLimit(Class<RE> returnClass){ T t = oneLimit(); if(t == null) { return null; } return BeanUtil.copy(t, returnClass); } public int count(){ return mapper.selectCountByExample(exampe); } }
WrapperLambdaUpdate
import java.util.function.BiConsumer; import com.xxx.BaseException; import com.xxx.BaseMapper; import cn.hutool.core.util.ReflectUtil; public final class WrapperLambdaUpdate<T> extends WrapperLambda<T,WrapperLambdaUpdate<T>>{ private T entity; public WrapperLambdaUpdate(BaseMapper<T> mapper, Class<T> entityClass) { super(mapper, entityClass); setW(this); } /** * * @param fn Entity::setXXXX * @param value 要设置的值 * @return */ public <V> WrapperLambdaUpdate<T> set(BiConsumer<T, V> fn, V value){ if(this.entity == null) { this.entity = ReflectUtil.newInstanceIfPossible(entityClass); } fn.accept(entity, value); return this; } public WrapperLambdaUpdate<T> and(WrapperLambdaUpdate<T> wrapperLambda){ exampe.and(wrapperLambda.weekendCriteria); return this; } public WrapperLambdaUpdate<T> or(WrapperLambdaUpdate<T> wrapperLambda){ exampe.or(wrapperLambda.weekendCriteria); return this; } public Integer update() { if(this.entity == null) { throw new BaseException("请先调用set方法传入要修改的值,或者调用update(t)"); } return mapper.updateByExampleSelective(this.entity, exampe); } public Integer update(T t) { if(this.entity != null) { throw new BaseException("请先删除set方法"); } return mapper.updateByExampleSelective(t, exampe); } public Integer updateAndNull(T t) { if(this.entity != null) { throw new BaseException("请先删除set方法"); } return mapper.updateByExample(t, exampe); } }
WrapperLambdaDelete
import com.xxx.BaseMapper; public final class WrapperLambdaDelete<T> extends WrapperLambda<T,WrapperLambdaDelete<T>>{ public WrapperLambdaDelete(BaseMapper<T> mapper, Class<T> entityClass) { super(mapper, entityClass); setW(this); } public Integer delete() { return mapper.deleteByExample(exampe); } }