springboot3 集成mybatis 和通用mapper
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引用
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.1.2</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <artifactId>spring-boot-starter-tomcat</artifactId> <groupId>org.springframework.boot</groupId> </exclusion> </exclusions> </dependency> <!-- web 容器使用 undertow 性能更强 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-undertow</artifactId> </dependency> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>1.4.7</version> </dependency>
<!-- 以前的tkmapper 不支持springboot3.x,此版本是支持boo3.x及boot2.x版本的 -->
<!-- 具体查看https://mapper.mybatis.io/--> <dependency> <groupId>io.mybatis</groupId> <artifactId>mybatis-mapper</artifactId> <version>2.1.1</version> </dependency>
<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>3.0.2</version> </dependency>
<!-- openapi、 swagger3、knife4j配置,适用boot3 -->
<!-- https://doc.xiaominfo.com -->
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
<version>4.3.0</version>
</dependency>
<!-- openapi配置 -->
</dependencies>
2、新建自己的BaseMapper
import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.List; import java.util.Optional; 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 io.mybatis.mapper.Mapper; import io.mybatis.mapper.example.Example; import io.mybatis.mapper.example.LambdaExampleWrapper; public interface BaseMapper<T> extends Mapper<T,Long>{ List<T> selectList(T entity, RowBounds rowBounds); default T getById(Long id) { return selectByPrimaryKey(id).orElse(null); } default <RE extends Serializable> RE getById(Long id,Class<RE> returnClass) { T t = getById(id); if(t != null) { return covert(t,returnClass); } return null; } default T one(T query) { return selectOne(query).orElse(null); } default <RE extends Serializable> RE one(T query,Class<RE> returnClass) { Optional<T> optional = selectOne(query); if(optional.isPresent()) { T t = optional.get(); return covert(t,returnClass); } return null; } default <RE extends Serializable> List<RE> select(T t,Class<RE> returnClass) { List<T> ts = selectList(t); return covertList(ts,returnClass); } default <RE extends Serializable> Page<RE> selectPage(T t,Class<RE> returnClass) { Page<T> ts = (Page<T>) selectList(t); return (Page<RE>) covertList(ts,returnClass); } default <RE extends Serializable> Page<RE> selectPageByExample(Example<T> example,Class<RE> returnClass) { Page<T> ts = (Page<T>) selectByExample(example); return (Page<RE>) covertList(ts,returnClass); } default <RE extends Serializable> List<RE> selectByExample(Example<T> example,Class<RE> returnClass) { List<T> ts = selectByExample(example); return covertList(ts,returnClass); } default <RE extends Serializable> RE selectOneByExample(Example<T> example,Class<RE> returnClass) { Optional<T> optional = selectOneByExample(example); if(optional.isPresent()) { T t = optional.get(); return covert(t,returnClass); } return null; } default <RE extends Serializable> RE selectOneByExampleLimitOne(Example<T> example,Class<RE> returnClass) { T t = selectOneByExampleLimitOne(example); if(t != null) { return covert(t, returnClass); } return null; } default T selectOneByExampleLimitOne(Example<T> example) { RowBounds rowBounds = new RowBounds(0, 1); List<T> ts = selectByExample(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 = selectList(t,rowBounds); if(ObjectUtil.isNotEmpty(ts)) { return ts.get(0); } return null; } @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.copy(t, response); } catch (Exception e) { e.printStackTrace(); } return response; } return null; } //自带的wrapper()个人觉得还缺点东西,就自己复制了一份出来微调了,根据情况使用,不需要就删除,需要对应的代码在下方 default LambdaExampleWrapper<T> lambdaWrapper() { return new LambdaExampleWrapper<>(BaseMapper.this, example()); } }
3、新建表模型,注意注解使用和以前版本有区别,但是兼容一些之前javax.persistence的一些基本注解
import java.util.Date; import io.mybatis.provider.Entity; import lombok.Data; @Data @Entity.Table("system_user") public class User { @Entity.Column(id = true,insertable = false,updatable = false) private Long id; /** * 姓名 */ private String realname; /** * 手机号 */ private String mobile; /** * 密码 */ private String password; /** * 身份证号 */ private String idcard; /** * 头像 */ private String avatar; /** * 最后登录时间 */ private String lastLoginIp; /** * 最后登录时间 */ private Date lastLoginTime; /** * 创建人 */ private Long createBy; /** * 创建时间 */ private Date createTime; /** * 修改人 */ private Long updateBy; /** * update_time */ private Date updateTime; }
4、创建对应业务的mapper继承BaseMapper
import com.xxx.core.base.BaseMapper; import com.xxx.system.model.User; public interface UserMapper extends BaseMapper<User>{ }
5、启动类扫描自己的mapper目录 @MapperScan
import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCaching; import org.springframework.context.annotation.ComponentScan; import org.springframework.scheduling.annotation.EnableScheduling; @EnableCaching @EnableScheduling @SpringBootApplication @MapperScan(basePackages="com.xxx.*.mapper") @ComponentScan(basePackages = { "com.xxx.*.config", "com.xxx.*.controller", "com.xxx.*.job" }) public class OperateApiStarted { public static void main(String[] args) { SpringApplication.run(OperateApiStarted.class, args); } }
6、创建io.mybatis.mapper.example.LambdaExampleWrapper
package io.mybatis.mapper.example; import java.io.Serializable; import java.util.Arrays; import java.util.List; import java.util.function.Function; import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; import org.apache.ibatis.exceptions.TooManyResultsException; import org.apache.ibatis.session.RowBounds; import com.github.pagehelper.Page; import com.xxx.BaseMapper; import com.xxx.BeanUtil; import io.mybatis.common.util.Assert; import io.mybatis.mapper.fn.Fn; public class LambdaExampleWrapper<T> { private final BaseMapper<T> baseMapper; private final Example<T> example; private Example.Criteria<T> current; public LambdaExampleWrapper(BaseMapper<T> baseMapper, Example<T> example) { this.baseMapper = baseMapper; this.example = example; this.current = example.createCriteria(); } /** * or 一组条件 * * @return 条件 */ public LambdaExampleWrapper<T> or() { this.current = this.example.or(); return this; } /** * 获取查询条件 */ public Example<T> example() { return example; } /** * 清除条件,可重用 */ public LambdaExampleWrapper<T> clear() { this.example.clear(); this.current = example.createCriteria(); return this; } /** * 指定查询列 * * @param fns 方法引用 */ @SafeVarargs public final LambdaExampleWrapper<T> select(Fn<T, Object>... fns) { this.example.selectColumns(fns); return this; } /** * 排除指定查询列 * * @param fns 方法引用 */ @SafeVarargs public final LambdaExampleWrapper<T> exclude(Fn<T, Object>... fns) { this.example.excludeColumns(fns); return this; } /** * 设置起始 SQL * * @param startSql 起始 SQL,添加到 SQL 前,注意防止 SQL 注入 */ public LambdaExampleWrapper<T> startSql(String startSql) { this.example.setStartSql(startSql); return this; } /** * 设置结尾 SQL * * @param endSql 结尾 SQL,添加到 SQL 最后,注意防止 SQL 注入 */ public LambdaExampleWrapper<T> endSql(String endSql) { this.example.setEndSql(endSql); return this; } /** * 通过方法引用方式设置排序字段 * * @param fn 排序列的方法引用 * @param order 排序方式 * @return Example */ public LambdaExampleWrapper<T> orderBy(Fn<T, Object> fn, Example.Order order) { this.example.orderBy(fn, order); return this; } /** * 支持使用字符串形式来设置 order by,用以支持一些特殊的排序方案 * * @param orderByCondition 排序字符串(不会覆盖已有的排序内容) * @return Example */ public LambdaExampleWrapper<T> orderBy(String orderByCondition) { this.example.orderBy(orderByCondition); return this; } /** * 支持使用字符串形式来设置 order by,用以支持一些特殊的排序方案 * * @param orderByCondition 排序字符串构造方法,比如通过数组集合循环拼接等 * @return Example */ public LambdaExampleWrapper<T> orderBy(Supplier<String> orderByCondition) { this.example.orderBy(orderByCondition); return this; } /** * 支持使用字符串形式来设置 order by,用以支持一些特殊的排序方案 * * @param useOrderBy 条件表达式,true使用,false不使用 字符串排序 * @param orderByCondition 排序字符串构造方法,比如通过数组集合循环拼接等 * @return Example */ public LambdaExampleWrapper<T> orderBy(boolean useOrderBy, Supplier<String> orderByCondition) { return useOrderBy ? this.orderBy(orderByCondition) : this; } /** * 通过方法引用方式设置排序字段,升序排序 * * @param fns 排序列的方法引用 * @return Example */ @SafeVarargs public final LambdaExampleWrapper<T> orderByAsc(Fn<T, Object>... fns) { this.example.orderByAsc(fns); return this; } /** * 通过方法引用方式设置排序字段,降序排序 * * @param fns 排序列的方法引用 * @return Example */ @SafeVarargs public final LambdaExampleWrapper<T> orderByDesc(Fn<T, Object>... fns) { this.example.orderByDesc(fns); return this; } /** * 设置 distince */ public LambdaExampleWrapper<T> distinct() { this.example.setDistinct(true); return this; } /** * 设置更新字段和值 * * @param useSet 表达式条件, true 使用,false 不使用 * @param setSql "column = value" */ public LambdaExampleWrapper<T> set(boolean useSet, String setSql) { return useSet ? set(setSql) : this; } /** * 设置更新字段和值 * * @param setSql "column = value" */ public LambdaExampleWrapper<T> set(String setSql) { this.example.set(setSql); return this; } /** * 设置更新字段和值 * * @param useSet 表达式条件, true 使用,false 不使用 * @param fn 字段 * @param value 值 */ public LambdaExampleWrapper<T> set(boolean useSet, Fn<T, Object> fn, Object value) { return useSet ? set(fn, value) : this; } /** * 设置更新字段和值 * * @param useSet 表达式条件, true 使用,false 不使用 * @param fn 字段 * @param supplier 值构造函数 */ public LambdaExampleWrapper<T> set(boolean useSet, Fn<T, Object> fn, Supplier<Object> supplier) { return useSet ? set(fn, supplier.get()) : this; } /** * 设置更新字段和值 * * @param fn 字段 * @param value 值 */ public LambdaExampleWrapper<T> set(Fn<T, Object> fn, Object value) { this.example.set(fn, value); return this; } /** * 指定字段为 null * * @param useCondition 表达式条件, true 使用,false 不使用 * @param fn 字段对应的 get 方法引用 */ public LambdaExampleWrapper<T> isNull(boolean useCondition, Fn<T, Object> fn) { return useCondition ? isNull(fn) : this; } /** * 指定字段为 null * * @param fn 字段对应的 get 方法引用 */ public LambdaExampleWrapper<T> isNull(Fn<T, Object> fn) { this.current.addCriterion(fn.toColumn() + " IS NULL"); return this; } /** * 指定字段不为 null * * @param useCondition 表达式条件, true 使用,false 不使用 * @param fn 字段对应的 get 方法引用 */ public LambdaExampleWrapper<T> isNotNull(boolean useCondition, Fn<T, Object> fn) { return useCondition ? isNotNull(fn) : this; } /** * 指定字段不为 null * * @param fn 字段对应的 get 方法引用 */ public LambdaExampleWrapper<T> isNotNull(Fn<T, Object> fn) { this.current.addCriterion(fn.toColumn() + " IS NOT NULL"); return this; } /** * 字段 = 值 * * @param useCondition 表达式条件, true 使用,false 不使用 * @param fn 字段对应的 get 方法引用 * @param value 值 */ public LambdaExampleWrapper<T> eq(boolean useCondition, Fn<T, Object> fn, Object value) { return useCondition ? eq(fn, value) : this; } /** * 字段 = 值 * * @param useCondition 表达式条件, true 使用,false 不使用 * @param fn 字段对应的 get 方法引用 * @param supplier 值构造函数 */ public LambdaExampleWrapper<T> eq(boolean useCondition, Fn<T, Object> fn, Supplier<Object> supplier) { return useCondition ? eq(fn, supplier.get()) : this; } /** * 字段 = 值 * * @param fn 字段对应的 get 方法引用 * @param value 值 */ public LambdaExampleWrapper<T> eq(Fn<T, Object> fn, Object value) { this.current.addCriterion(fn.toColumn() + " =", value); return this; } /** * 字段 != 值 * * @param useCondition 表达式条件, true 使用,false 不使用 * @param fn 字段对应的 get 方法引用 * @param supplier 值构造函数 */ public LambdaExampleWrapper<T> ne(boolean useCondition, Fn<T, Object> fn, Supplier<Object> supplier) { return useCondition ? ne(fn, supplier.get()) : this; } /** * 字段 != 值 * * @param useCondition 表达式条件, true 使用,false 不使用 * @param fn 字段对应的 get 方法引用 * @param value 值 */ public LambdaExampleWrapper<T> ne(boolean useCondition, Fn<T, Object> fn, Object value) { return useCondition ? ne(fn, value) : this; } /** * 字段 != 值 * * @param fn 字段对应的 get 方法引用 * @param value 值 */ public LambdaExampleWrapper<T> ne(Fn<T, Object> fn, Object value) { this.current.addCriterion(fn.toColumn() + " <>", value); return this; } /** * 字段 > 值 * * @param useCondition 表达式条件, true 使用,false 不使用 * @param fn 字段对应的 get 方法引用 * @param supplier 值构造函数 */ public LambdaExampleWrapper<T> gt(boolean useCondition, Fn<T, Object> fn, Supplier<Object> supplier) { return useCondition ? gt(fn, supplier.get()) : this; } /** * 字段 > 值 * * @param useCondition 表达式条件, true 使用,false 不使用 * @param fn 字段对应的 get 方法引用 * @param value 值 */ public LambdaExampleWrapper<T> gt(boolean useCondition, Fn<T, Object> fn, Object value) { return useCondition ? gt(fn, value) : this; } /** * 字段 > 值 * * @param fn 字段对应的 get 方法引用 * @param value 值 */ public LambdaExampleWrapper<T> gt(Fn<T, Object> fn, Object value) { this.current.addCriterion(fn.toColumn() + " >", value); return this; } /** * 字段 >= 值 * * @param useCondition 表达式条件, true 使用,false 不使用 * @param fn 字段对应的 get 方法引用 * @param supplier 值构造函数 */ public LambdaExampleWrapper<T> ge(boolean useCondition, Fn<T, Object> fn, Supplier<Object> supplier) { return useCondition ? ge(fn, supplier.get()) : this; } /** * 字段 >= 值 * * @param useCondition 表达式条件, true 使用,false 不使用 * @param fn 字段对应的 get 方法引用 * @param value 值 */ public LambdaExampleWrapper<T> ge(boolean useCondition, Fn<T, Object> fn, Object value) { return useCondition ? ge(fn, value) : this; } /** * 字段 >= 值 * * @param fn 字段对应的 get 方法引用 * @param value 值 */ public LambdaExampleWrapper<T> ge(Fn<T, Object> fn, Object value) { this.current.addCriterion(fn.toColumn() + " >=", value); return this; } /** * 字段 < 值 * * @param useCondition 表达式条件, true 使用,false 不使用 * @param fn 字段对应的 get 方法引用 */ public LambdaExampleWrapper<T> lt(boolean useCondition, Fn<T, Object> fn, Supplier<Object> supplier) { return useCondition ? lt(fn, supplier.get()) : this; } /** * 字段 < 值 * * @param useCondition 表达式条件, true 使用,false 不使用 * @param fn 字段对应的 get 方法引用 * @param value 值 */ public LambdaExampleWrapper<T> lt(boolean useCondition, Fn<T, Object> fn, Object value) { return useCondition ? lt(fn, value) : this; } /** * 字段 < 值 * * @param fn 字段对应的 get 方法引用 * @param value 值 */ public LambdaExampleWrapper<T> lt(Fn<T, Object> fn, Object value) { this.current.addCriterion(fn.toColumn() + " <", value); return this; } /** * 字段 <= 值 * * @param useCondition 表达式条件, true 使用,false 不使用 * @param fn 字段对应的 get 方法引用 * @param value 值 */ public LambdaExampleWrapper<T> le(boolean useCondition, Fn<T, Object> fn, Object value) { return useCondition ? le(fn, value) : this; } /** * 字段 <= 值 * * @param useCondition 表达式条件, true 使用,false 不使用 * @param fn 字段对应的 get 方法引用 * @param supplier 值构造函数 */ public LambdaExampleWrapper<T> le(boolean useCondition, Fn<T, Object> fn, Supplier<Object> supplier) { return useCondition ? le(fn, supplier.get()) : this; } /** * 字段 <= 值 * * @param fn 字段对应的 get 方法引用 * @param value 值 */ public LambdaExampleWrapper<T> le(Fn<T, Object> fn, Object value) { this.current.addCriterion(fn.toColumn() + " <=", value); return this; } /** * 字段 in (值集合) * * @param useCondition 表达式条件, true 使用,false 不使用 * @param fn 字段对应的 get 方法引用 * @param values 值集合 */ @SuppressWarnings("rawtypes") public LambdaExampleWrapper<T> in(boolean useCondition, Fn<T, Object> fn, Iterable values) { return useCondition ? in(fn, values) : this; } /** * 字段 in (值集合) * * @param useCondition 表达式条件, true 使用,false 不使用 * @param fn 字段对应的 get 方法引用 * @param supplier 值集合构造函数 */ @SuppressWarnings("rawtypes") public LambdaExampleWrapper<T> in(boolean useCondition, Fn<T, Object> fn, Supplier<Iterable> supplier) { return useCondition ? in(fn, supplier.get()) : this; } /** * 字段 in (值集合) * * @param fn 字段对应的 get 方法引用 * @param values 值集合 */ @SuppressWarnings("rawtypes") public LambdaExampleWrapper<T> in(Fn<T, Object> fn, Iterable values) { this.current.addCriterion(fn.toColumn() + " IN", values); return this; } /** * 字段 not in (值集合) * * @param useCondition 表达式条件, true 使用,false 不使用 * @param fn 字段对应的 get 方法引用 * @param values 值集合 */ @SuppressWarnings("rawtypes") public LambdaExampleWrapper<T> notIn(boolean useCondition, Fn<T, Object> fn, Iterable values) { return useCondition ? notIn(fn, values) : this; } /** * 字段 not in (值集合) * * @param useCondition 表达式条件, true 使用,false 不使用 * @param fn 字段对应的 get 方法引用 * @param supplier 值集合构造函数 */ @SuppressWarnings("rawtypes") public LambdaExampleWrapper<T> notIn(boolean useCondition, Fn<T, Object> fn, Supplier<Iterable> supplier) { return useCondition ? notIn(fn, supplier.get()) : this; } /** * 字段 not in (值集合) * * @param fn 字段对应的 get 方法引用 * @param values 值集合 */ @SuppressWarnings("rawtypes") public LambdaExampleWrapper<T> notIn(Fn<T, Object> fn, Iterable values) { this.current.addCriterion(fn.toColumn() + " NOT IN", values); return this; } /** * 字段 between value1 and value 2 * * @param useCondition 表达式条件, true 使用,false 不使用 * @param fn 字段对应的 get 方法引用 * @param value1 值1 * @param value2 值2 */ public LambdaExampleWrapper<T> between(boolean useCondition, Fn<T, Object> fn, Object value1, Object value2) { return useCondition ? between(fn, value1, value2) : this; } /** * 字段 between value1 and value 2 * * @param useCondition 表达式条件, true 使用,false 不使用 * @param fn 字段对应的 get 方法引用 * @param supplier1 值1构造函数 * @param supplier2 值2构造函数 */ public LambdaExampleWrapper<T> between(boolean useCondition, Fn<T, Object> fn, Supplier<Object> supplier1, Supplier<Object> supplier2) { return useCondition ? between(fn, supplier1.get(), supplier2.get()) : this; } /** * 字段 between value1 and value 2 * * @param fn 字段对应的 get 方法引用 * @param value1 值1 * @param value2 值2 */ public LambdaExampleWrapper<T> between(Fn<T, Object> fn, Object value1, Object value2) { this.current.addCriterion(fn.toColumn() + " BETWEEN", value1, value2); return this; } /** * 字段 not between value1 and value 2 * * @param useCondition 表达式条件, true 使用,false 不使用 * @param fn 字段对应的 get 方法引用 * @param value1 值1 * @param value2 值2 */ public LambdaExampleWrapper<T> notBetween(boolean useCondition, Fn<T, Object> fn, Object value1, Object value2) { return useCondition ? notBetween(fn, value1, value2) : this; } /** * 字段 not between value1 and value 2 * * @param useCondition 表达式条件, true 使用,false 不使用 * @param fn 字段对应的 get 方法引用 * @param supplier1 值1构造函数 * @param supplier2 值2构造函数 */ public LambdaExampleWrapper<T> notBetween(boolean useCondition, Fn<T, Object> fn, Supplier<Object> supplier1, Supplier<Object> supplier2) { return useCondition ? notBetween(fn, supplier1.get(), supplier2.get()) : this; } /** * 字段 not between value1 and value 2 * * @param fn 字段对应的 get 方法引用 * @param value1 值1 * @param value2 值2 */ public LambdaExampleWrapper<T> notBetween(Fn<T, Object> fn, Object value1, Object value2) { this.current.addCriterion(fn.toColumn() + " NOT BETWEEN", value1, value2); return this; } /** * 字段 like %值% * * @param useCondition 表达式条件, true 使用,false 不使用 * @param fn 字段对应的 get 方法引用 * @param value 值,两侧自动添加 % */ public LambdaExampleWrapper<T> contains(boolean useCondition, Fn<T, Object> fn, String value) { return useCondition ? contains(fn, value) : this; } /** * 字段 like %值% * * @param useCondition 表达式条件, true 使用,false 不使用 * @param fn 字段对应的 get 方法引用 * @param supplier 值构造函数,两侧自动添加 % */ public LambdaExampleWrapper<T> contains(boolean useCondition, Fn<T, Object> fn, Supplier<String> supplier) { return useCondition ? contains(fn, supplier.get()) : this; } /** * 字段 like %值% * * @param fn 字段对应的 get 方法引用 * @param value 值,两侧自动添加 % */ public LambdaExampleWrapper<T> contains(Fn<T, Object> fn, String value) { this.current.addCriterion(fn.toColumn() + " LIKE", "%" + value + "%"); return this; } /** * 字段 like 值%,匹配 value 为前缀的值 * * @param useCondition 表达式条件, true 使用,false 不使用 * @param fn 字段对应的 get 方法引用 * @param value 值,右侧自动添加 % */ public LambdaExampleWrapper<T> startsWith(boolean useCondition, Fn<T, Object> fn, String value) { return useCondition ? startsWith(fn, value) : this; } /** * 字段 like 值%,匹配 value 为前缀的值 * * @param useCondition 表达式条件, true 使用,false 不使用 * @param fn 字段对应的 get 方法引用 * @param supplier 值构造函数,右侧自动添加 % */ public LambdaExampleWrapper<T> startsWith(boolean useCondition, Fn<T, Object> fn, Supplier<String> supplier) { return useCondition ? startsWith(fn, supplier.get()) : this; } /** * 字段 like 值%,匹配 value 为前缀的值 * * @param fn 字段对应的 get 方法引用 * @param value 值,右侧自动添加 % */ public LambdaExampleWrapper<T> startsWith(Fn<T, Object> fn, String value) { this.current.addCriterion(fn.toColumn() + " LIKE", value + "%"); return this; } /** * 字段 like %值,匹配 value 为后缀的值 * * @param useCondition 表达式条件, true 使用,false 不使用 * @param fn 字段对应的 get 方法引用 * @param value 值,左侧自动添加 % */ public LambdaExampleWrapper<T> endsWith(boolean useCondition, Fn<T, Object> fn, String value) { return useCondition ? endsWith(fn, value) : this; } /** * 字段 like %值,匹配 value 为后缀的值 * * @param useCondition 表达式条件, true 使用,false 不使用 * @param fn 字段对应的 get 方法引用 * @param supplier 值构造函数,左侧自动添加 % */ public LambdaExampleWrapper<T> endsWith(boolean useCondition, Fn<T, Object> fn, Supplier<String> supplier) { return useCondition ? endsWith(fn, supplier.get()) : this; } /** * 字段 like %值,匹配 value 为后缀的值 * * @param fn 字段对应的 get 方法引用 * @param value 值,左侧自动添加 % */ public LambdaExampleWrapper<T> endsWith(Fn<T, Object> fn, String value) { this.current.addCriterion(fn.toColumn() + " LIKE", "%" + value); return this; } /** * 字段 like 值 * * @param useCondition 表达式条件, true 使用,false 不使用 * @param fn 字段对应的 get 方法引用 * @param value 值,需要指定 '%'(多个), '_'(单个) 模糊匹配 */ public LambdaExampleWrapper<T> like(boolean useCondition, Fn<T, Object> fn, String value) { return useCondition ? like(fn, value) : this; } /** * 字段 like 值 * * @param useCondition 表达式条件, true 使用,false 不使用 * @param fn 字段对应的 get 方法引用 * @param supplier 值构造函数,需要指定 '%'(多个), '_'(单个) 模糊匹配 */ public LambdaExampleWrapper<T> like(boolean useCondition, Fn<T, Object> fn, Supplier<String> supplier) { return useCondition ? like(fn, supplier.get()) : this; } /** * 字段 like 值 * * @param fn 字段对应的 get 方法引用 * @param value 值,需要指定 '%'(多个), '_'(单个) 模糊匹配 */ public LambdaExampleWrapper<T> like(Fn<T, Object> fn, String value) { this.current.addCriterion(fn.toColumn() + " LIKE", value); return this; } /** * 字段 not like 值 * * @param useCondition 表达式条件, true 使用,false 不使用 * @param fn 字段对应的 get 方法引用 * @param value 值,需要指定 % 模糊匹配 */ public LambdaExampleWrapper<T> notLike(boolean useCondition, Fn<T, Object> fn, String value) { return useCondition ? notLike(fn, value) : this; } /** * 字段 not like 值 * * @param useCondition 表达式条件, true 使用,false 不使用 * @param fn 字段对应的 get 方法引用 * @param supplier 值构造函数,需要指定 % 模糊匹配 */ public LambdaExampleWrapper<T> notLike(boolean useCondition, Fn<T, Object> fn, Supplier<String> supplier) { return useCondition ? notLike(fn, supplier.get()) : this; } /** * 字段 not like 值 * * @param fn 字段对应的 get 方法引用 * @param value 值,需要指定 % 模糊匹配 */ public LambdaExampleWrapper<T> notLike(Fn<T, Object> fn, String value) { this.current.addCriterion(fn.toColumn() + " NOT LIKE", value); return this; } /** * 添加任意条件,条件一定是后端使用的,需要自己防止 SQL 注入 * * @param useCondition 表达式条件, true 使用,false 不使用 * @param condition 任意条件,例如 "length(countryname)<5" */ public LambdaExampleWrapper<T> anyCondition(boolean useCondition, String condition) { return useCondition ? anyCondition(condition) : this; } /** * 添加任意条件,条件一定是后端使用的,需要自己防止 SQL 注入 * * @param condition 任意条件,例如 "length(countryname)<5" */ public LambdaExampleWrapper<T> anyCondition(String condition) { this.current.andCondition(condition); return this; } /** * 手写左边条件,右边用value值 * * @param useCondition 表达式条件, true 使用,false 不使用 * @param condition 例如 "length(countryname)=" * @param value 例如 5 */ public LambdaExampleWrapper<T> anyCondition(boolean useCondition, String condition, Object value) { return useCondition ? anyCondition(condition, value) : this; } /** * 手写左边条件,右边用value值 * * @param useCondition 表达式条件, true 使用,false 不使用 * @param condition 例如 "length(countryname)=" * @param supplier 任意条件值的构造函数 */ public LambdaExampleWrapper<T> anyCondition(boolean useCondition, String condition, Supplier<Object> supplier) { return useCondition ? anyCondition(condition, supplier.get()) : this; } /** * 手写左边条件,右边用value值 * * @param condition 例如 "length(countryname)=" * @param value 例如 5 */ public LambdaExampleWrapper<T> anyCondition(String condition, Object value) { this.current.andCondition(condition, value); return this; } /** * 嵌套 or 查询,数组多个条件直接使用 or,单个条件中为 and * * @param orParts 条件块 */ @SafeVarargs public final LambdaExampleWrapper<T> or(Function<Example.OrCriteria<T>, Example.OrCriteria<T>>... orParts) { if (orParts != null && orParts.length > 0) { this.current.andOr(Arrays.stream(orParts).map(orPart -> orPart.apply(example.orPart())).collect(Collectors.toList())); } return this; } /** * 根据当前条件删除 */ public int delete() { return baseMapper.deleteByExample(example); } /** * 将符合当前查询条件的数据更新为 {@link #set(String)} 和 {@link #set(Fn, Object)} 设置的值 */ public int update() { Assert.notEmpty(example.getSetValues(), "必须通过 set 方法设置更新的列和值"); return baseMapper.updateByExampleSetValues(example); } /** * 将符合当前查询条件的数据更新为提供的值, {@link #set(String)} 和 {@link #set(Fn, Object)} 设置的值无效 * * @param t 要更新的值 */ public int update(T t) { return baseMapper.updateByExample(t, example); } /** * 将符合当前查询条件的数据更新为提供的值,不更新 null 的值 * * @param t 要更新的值 */ public int updateSelective(T t) { return baseMapper.updateByExampleSelective(t, example); } /** * 根据当前查询条件查询 */ public List<T> list() { return baseMapper.selectByExample(example); } /** * 根据当前查询条件查询,返回 Stream */ public Stream<T> stream() { return list().stream(); } /** * 根据当前查询条件查询出一个结果,当存在多个符合条件的结果时会抛出异常 {@link TooManyResultsException} */ public T one() { return baseMapper.selectOneByExample(example).orElse(null); } /** * 根据当前查询条件查询出第一个结果,通过 {@link RowBounds} 实现 */ public T first() { return baseMapper.selectByExample(example, new RowBounds(0, 1)).stream().findFirst().orElse(null); } /** * 根据当前查询条件查询出前 n 个结果,通过 {@link RowBounds} 实现 * * @param n 结果数 */ public List<T> top(int n) { return baseMapper.selectByExample(example, new RowBounds(0, n)); } /** * 查询符合当前条件的结果数 */ public long count() { return baseMapper.countByExample(example); } public <RE extends Serializable> List<RE> list(Class<RE> returnClass){ List<T> ts = list(); 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(); 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 <RE extends Serializable> RE one(Class<RE> returnClass){ T t = one(); if(t != null) { return BeanUtil.copy(t, returnClass); } return null; } public <RE extends Serializable> List<RE> top(Integer limit,Class<RE> returnClass){ List<T> ts = top(limit); List<RE> res = BeanUtil.copys(ts, returnClass); return res; } public <RE extends Serializable> RE first(Class<RE> returnClass) { T t = first(); if(t != null) { return BeanUtil.copy(t, returnClass); } return null; } }
7、补一个swagger2 to swagger3的注解映射
@ApiModel(value = "") -> @Schema(title = "") @ApiModelProperty(value = "") -> @Schema(description = "") @Api(tags = "") -> @Tag(name = "") @ApiOperation(value = "", tags = {""}) -> @Operation(summary = "", tags = "")