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>
<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>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
<version>4.3.0</version>
</dependency>
</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 extends Mapper{ List selectList(T entity, RowBounds rowBounds); default T getById(Long id) { return selectByPrimaryKey(id).orElse(null); } default <RE extends Serializable> RE getById(Long id,Class 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 returnClass) { Optional optional = selectOne(query); if(optional.isPresent()) { T t = optional.get(); return covert(t,returnClass); } return null; } default <RE extends Serializable> List select(T t,Class returnClass) { List ts = selectList(t); return covertList(ts,returnClass); } default <RE extends Serializable> Page selectPage(T t,Class returnClass) { Page ts = (Page) selectList(t); return (Page) covertList(ts,returnClass); } default <RE extends Serializable> Page selectPageByExample(Example example,Class returnClass) { Page ts = (Page) selectByExample(example); return (Page) covertList(ts,returnClass); } default <RE extends Serializable> List selectByExample(Example example,Class returnClass) { List ts = selectByExample(example); return covertList(ts,returnClass); } default <RE extends Serializable> RE selectOneByExample(Example example,Class returnClass) { Optional optional = selectOneByExample(example); if(optional.isPresent()) { T t = optional.get(); return covert(t,returnClass); } return null; } default <RE extends Serializable> RE selectOneByExampleLimitOne(Example example,Class returnClass) { T t = selectOneByExampleLimitOne(example); if(t != null) { return covert(t, returnClass); } return null; } default T selectOneByExampleLimitOne(Example example) { RowBounds rowBounds = new RowBounds(0, 1); List 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 ts = selectList(t,rowBounds); if(ObjectUtil.isNotEmpty(ts)) { return ts.get(0); } return null; } @SuppressWarnings("unchecked") default Class 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) clazz; } } return null; } default <RE extends Serializable> List covertList(List ts,Class returnClass){ List 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 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 lambdaWrapper() { return new LambdaExampleWrapper(BaseMapper.this, example()); }}
View Code
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;}
View Code
4、创建对应业务的mapper继承BaseMapper
import com.xxx.core.base.BaseMapper;import com.xxx.system.model.User;public interface UserMapper extends BaseMapper{}
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 { private final BaseMapper baseMapper; private final Example example; private Example.Criteria current; public LambdaExampleWrapper(BaseMapper baseMapper, Example example) { this.baseMapper = baseMapper; this.example = example; this.current = example.createCriteria(); } /** * or 一组条件 * * @return 条件 */ public LambdaExampleWrapper or() { this.current = this.example.or(); return this; } /** * 获取查询条件 */ public Example example() { return example; } /** * 清除条件,可重用 */ public LambdaExampleWrapper clear() { this.example.clear(); this.current = example.createCriteria(); return this; } /** * 指定查询列 * * @param fns 方法引用 */ @SafeVarargs public final LambdaExampleWrapper select(Fn... fns) { this.example.selectColumns(fns); return this; } /** * 排除指定查询列 * * @param fns 方法引用 */ @SafeVarargs public final LambdaExampleWrapper exclude(Fn... fns) { this.example.excludeColumns(fns); return this; } /** * 设置起始 SQL * * @param startSql 起始 SQL,添加到 SQL 前,注意防止 SQL 注入 */ public LambdaExampleWrapper startSql(String startSql) { this.example.setStartSql(startSql); return this; } /** * 设置结尾 SQL * * @param endSql 结尾 SQL,添加到 SQL 最后,注意防止 SQL 注入 */ public LambdaExampleWrapper endSql(String endSql) { this.example.setEndSql(endSql); return this; } /** * 通过方法引用方式设置排序字段 * * @param fn 排序列的方法引用 * @param order 排序方式 * @return Example */ public LambdaExampleWrapper orderBy(Fn fn, Example.Order order) { this.example.orderBy(fn, order); return this; } /** * 支持使用字符串形式来设置 order by,用以支持一些特殊的排序方案 * * @param orderByCondition 排序字符串(不会覆盖已有的排序内容) * @return Example */ public LambdaExampleWrapper orderBy(String orderByCondition) { this.example.orderBy(orderByCondition); return this; } /** * 支持使用字符串形式来设置 order by,用以支持一些特殊的排序方案 * * @param orderByCondition 排序字符串构造方法,比如通过数组集合循环拼接等 * @return Example */ public LambdaExampleWrapper orderBy(Supplier orderByCondition) { this.example.orderBy(orderByCondition); return this; } /** * 支持使用字符串形式来设置 order by,用以支持一些特殊的排序方案 * * @param useOrderBy 条件表达式,true使用,false不使用 字符串排序 * @param orderByCondition 排序字符串构造方法,比如通过数组集合循环拼接等 * @return Example */ public LambdaExampleWrapper orderBy(boolean useOrderBy, Supplier orderByCondition) { return useOrderBy ? this.orderBy(orderByCondition) : this; } /** * 通过方法引用方式设置排序字段,升序排序 * * @param fns 排序列的方法引用 * @return Example */ @SafeVarargs public final LambdaExampleWrapper orderByAsc(Fn... fns) { this.example.orderByAsc(fns); return this; } /** * 通过方法引用方式设置排序字段,降序排序 * * @param fns 排序列的方法引用 * @return Example */ @SafeVarargs public final LambdaExampleWrapper orderByDesc(Fn... fns) { this.example.orderByDesc(fns); return this; } /** * 设置 distince */ public LambdaExampleWrapper distinct() { this.example.setDistinct(true); return this; } /** * 设置更新字段和值 * * @param useSet 表达式条件, true 使用,false 不使用 * @param setSql "column = value" */ public LambdaExampleWrapper set(boolean useSet, String setSql) { return useSet ? set(setSql) : this; } /** * 设置更新字段和值 * * @param setSql "column = value" */ public LambdaExampleWrapper set(String setSql) { this.example.set(setSql); return this; } /** * 设置更新字段和值 * * @param useSet 表达式条件, true 使用,false 不使用 * @param fn 字段 * @param value 值 */ public LambdaExampleWrapper set(boolean useSet, Fn fn, Object value) { return useSet ? set(fn, value) : this; } /** * 设置更新字段和值 * * @param useSet 表达式条件, true 使用,false 不使用 * @param fn 字段 * @param supplier 值构造函数 */ public LambdaExampleWrapper set(boolean useSet, Fn fn, Supplier
View Code
7、补一个swagger2 to swagger3的注解映射
@ApiModel(value = "") -> @Schema(title = "")@ApiModelProperty(value = "") -> @Schema(description = "")@Api(tags = "") -> @Tag(name = "")@ApiOperation(value = "", tags = {""}) -> @Operation(summary = "", tags = "")