推荐:MyBatis Plus汇总
首先创建一个数据库表,如下图所示:
然后创建一个Spring Boot项目,pom.xml和配置如下:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.kaven</groupId> <artifactId>mybatis-plus</artifactId> <version>1.0-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.3.4.RELEASE</version> <relativePath/> </parent> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.4.0</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.49</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project> spring: application: name: mybatis-plus datasource: driver-class-name: com.mysql.jdbc.Driver username: root password: ITkaven@123 url: jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf-8&useSSL=false server: port: 8085 logging: level: root: warn com.kaven.mybatisplus.dao: trace pattern: console: '%p%m%n' mybatis-plus: mapper-locations: classpath:mappers/*.xml实体类User:
package com.kaven.mybatisplus.entity; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; @TableName("user") @Data public class User { @TableId private String id; @TableField("username") private String username; @TableField("password") private String password; @TableField("age") private Integer age; /** * 使用 @TableField(exist = false) ,表示该字段在数据库中不存在 ,所以不会插入数据库中 * 使用 transient 、 static 修饰属性也不会插入数据库中 */ @TableField(exist = false) private String phone; }Mapper接口UserMapper:
package com.kaven.mybatisplus.dao; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.kaven.mybatisplus.entity.User; import org.springframework.stereotype.Component; @Component public interface UserMapper extends BaseMapper<User> {}启动类:
package com.kaven.mybatisplus; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication @MapperScan(basePackages = "com.kaven.mybatisplus.dao") public class AppRun { public static void main(String[] args) { SpringApplication.run(AppRun.class , args); } }@MapperScan(basePackages = "com.kaven.mybatisplus.dao")这个一定要加上。
我们先在数据库中添加几行数据,方便演示。
查询username包含字符k,并且age要小于35。 package com.kaven.mybatisplus.dao; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.kaven.mybatisplus.entity.User; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.util.List; @RunWith(SpringRunner.class) @SpringBootTest public class UserMapperWrapperTest { @Autowired private UserMapper userMapper; @Test public void selectList(){ QueryWrapper<User> userQueryWrapper = new QueryWrapper<>(); // QueryWrapper<User> userQueryWrapper = Wrappers.query(); 和上面一样的效果 userQueryWrapper.like("username" , "k").lt("age" , 35); List<User> userList = userMapper.selectList(userQueryWrapper); userList.forEach(System.out::println); } }结果如下:
很明显,结果是正确的,MyBatis-Plus使用条件构造器进行查询非常简单,通过链式调用即可。 关键是 QueryWrapper<T>这个类,而它则继承了AbstractWrapper<T, String, QueryWrapper<T>>这个类。 AbstractWrapper<T, String, QueryWrapper<T>>的源码如下,其实就是实现了一些条件判断方法,自己可以去看一看。
package com.baomidou.mybatisplus.core.conditions; import com.baomidou.mybatisplus.core.conditions.interfaces.Compare; import com.baomidou.mybatisplus.core.conditions.interfaces.Func; import com.baomidou.mybatisplus.core.conditions.interfaces.Join; import com.baomidou.mybatisplus.core.conditions.interfaces.Nested; import com.baomidou.mybatisplus.core.conditions.segments.MergeSegments; import com.baomidou.mybatisplus.core.enums.SqlKeyword; import com.baomidou.mybatisplus.core.enums.SqlLike; import com.baomidou.mybatisplus.core.toolkit.*; import com.baomidou.mybatisplus.core.toolkit.sql.SqlUtils; import com.baomidou.mybatisplus.core.toolkit.sql.StringEscape; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.BiPredicate; import java.util.function.Consumer; import static com.baomidou.mybatisplus.core.enums.SqlKeyword.*; import static com.baomidou.mybatisplus.core.enums.WrapperKeyword.APPLY; import static java.util.stream.Collectors.joining; /** * 查询条件封装 * * @author hubin miemie HCL * @since 2017-05-26 */ @SuppressWarnings({"serial", "unchecked"}) public abstract class AbstractWrapper<T, R, Children extends AbstractWrapper<T, R, Children>> extends Wrapper<T> implements Compare<Children, R>, Nested<Children, Children>, Join<Children>, Func<Children, R> { /** * 占位符 */ protected final Children typedThis = (Children) this; /** * 必要度量 */ protected AtomicInteger paramNameSeq; protected Map<String, Object> paramNameValuePairs; protected SharedString lastSql; /** * SQL注释 */ protected SharedString sqlComment; /** * SQL起始语句 */ protected SharedString sqlFirst; /** * ß * 数据库表映射实体类 */ private T entity; protected MergeSegments expression; /** * 实体类型(主要用于确定泛型以及取TableInfo缓存) */ private Class<T> entityClass; @Override public T getEntity() { return entity; } public Children setEntity(T entity) { this.entity = entity; return typedThis; } protected Class<T> getEntityClass() { if (entityClass == null && entity != null) { entityClass = (Class<T>) entity.getClass(); } return entityClass; } public Children setEntityClass(Class<T> entityClass) { if (entityClass != null) { this.entityClass = entityClass; } return typedThis; } @Override public <V> Children allEq(boolean condition, Map<R, V> params, boolean null2IsNull) { if (condition && CollectionUtils.isNotEmpty(params)) { params.forEach((k, v) -> { if (StringUtils.checkValNotNull(v)) { eq(k, v); } else { if (null2IsNull) { isNull(k); } } }); } return typedThis; } @Override public <V> Children allEq(boolean condition, BiPredicate<R, V> filter, Map<R, V> params, boolean null2IsNull) { if (condition && CollectionUtils.isNotEmpty(params)) { params.forEach((k, v) -> { if (filter.test(k, v)) { if (StringUtils.checkValNotNull(v)) { eq(k, v); } else { if (null2IsNull) { isNull(k); } } } }); } return typedThis; } @Override public Children eq(boolean condition, R column, Object val) { return addCondition(condition, column, EQ, val); } @Override public Children ne(boolean condition, R column, Object val) { return addCondition(condition, column, NE, val); } @Override public Children gt(boolean condition, R column, Object val) { return addCondition(condition, column, GT, val); } @Override public Children ge(boolean condition, R column, Object val) { return addCondition(condition, column, GE, val); } @Override public Children lt(boolean condition, R column, Object val) { return addCondition(condition, column, LT, val); } @Override public Children le(boolean condition, R column, Object val) { return addCondition(condition, column, LE, val); } @Override public Children like(boolean condition, R column, Object val) { return likeValue(condition, LIKE, column, val, SqlLike.DEFAULT); } @Override public Children notLike(boolean condition, R column, Object val) { return likeValue(condition, NOT_LIKE, column, val, SqlLike.DEFAULT); } @Override public Children likeLeft(boolean condition, R column, Object val) { return likeValue(condition, LIKE, column, val, SqlLike.LEFT); } @Override public Children likeRight(boolean condition, R column, Object val) { return likeValue(condition, LIKE, column, val, SqlLike.RIGHT); } @Override public Children between(boolean condition, R column, Object val1, Object val2) { return doIt(condition, () -> columnToString(column), BETWEEN, () -> formatSql("{0}", val1), AND, () -> formatSql("{0}", val2)); } @Override public Children notBetween(boolean condition, R column, Object val1, Object val2) { return doIt(condition, () -> columnToString(column), NOT_BETWEEN, () -> formatSql("{0}", val1), AND, () -> formatSql("{0}", val2)); } @Override public Children and(boolean condition, Consumer<Children> consumer) { return and(condition).addNestedCondition(condition, consumer); } @Override public Children or(boolean condition, Consumer<Children> consumer) { return or(condition).addNestedCondition(condition, consumer); } @Override public Children nested(boolean condition, Consumer<Children> consumer) { return addNestedCondition(condition, consumer); } @Override public Children not(boolean condition, Consumer<Children> consumer) { return not(condition).addNestedCondition(condition, consumer); } @Override public Children or(boolean condition) { return doIt(condition, OR); } @Override public Children apply(boolean condition, String applySql, Object... value) { return doIt(condition, APPLY, () -> formatSql(applySql, value)); } @Override public Children last(boolean condition, String lastSql) { if (condition) { this.lastSql.setStringValue(StringPool.SPACE + lastSql); } return typedThis; } @Override public Children comment(boolean condition, String comment) { if (condition) { this.sqlComment.setStringValue(comment); } return typedThis; } @Override public Children first(boolean condition, String firstSql) { if (condition) { this.sqlFirst.setStringValue(firstSql); } return typedThis; } @Override public Children exists(boolean condition, String existsSql) { return doIt(condition, EXISTS, () -> String.format("(%s)", existsSql)); } @Override public Children notExists(boolean condition, String existsSql) { return not(condition).exists(condition, existsSql); } @Override public Children isNull(boolean condition, R column) { return doIt(condition, () -> columnToString(column), IS_NULL); } @Override public Children isNotNull(boolean condition, R column) { return doIt(condition, () -> columnToString(column), IS_NOT_NULL); } @Override public Children in(boolean condition, R column, Collection<?> coll) { return doIt(condition, () -> columnToString(column), IN, inExpression(coll)); } @Override public Children notIn(boolean condition, R column, Collection<?> coll) { return doIt(condition, () -> columnToString(column), NOT_IN, inExpression(coll)); } @Override public Children inSql(boolean condition, R column, String inValue) { return doIt(condition, () -> columnToString(column), IN, () -> String.format("(%s)", inValue)); } @Override public Children notInSql(boolean condition, R column, String inValue) { return doIt(condition, () -> columnToString(column), NOT_IN, () -> String.format("(%s)", inValue)); } @Override public Children groupBy(boolean condition, R... columns) { if (ArrayUtils.isEmpty(columns)) { return typedThis; } return doIt(condition, GROUP_BY, () -> columns.length == 1 ? columnToString(columns[0]) : columnsToString(columns)); } @Override public Children orderBy(boolean condition, boolean isAsc, R... columns) { if (ArrayUtils.isEmpty(columns)) { return typedThis; } SqlKeyword mode = isAsc ? ASC : DESC; for (R column : columns) { doIt(condition, ORDER_BY, () -> columnToString(column), mode); } return typedThis; } @Override public Children having(boolean condition, String sqlHaving, Object... params) { return doIt(condition, HAVING, () -> formatSqlIfNeed(condition, sqlHaving, params)); } @Override public Children func(boolean condition, Consumer<Children> consumer) { if (condition) { consumer.accept(typedThis); } return typedThis; } /** * 内部自用 * <p>NOT 关键词</p> */ protected Children not(boolean condition) { return doIt(condition, NOT); } /** * 内部自用 * <p>拼接 AND</p> */ protected Children and(boolean condition) { return doIt(condition, AND); } /** * 内部自用 * <p>拼接 LIKE 以及 值</p> */ protected Children likeValue(boolean condition, SqlKeyword keyword, R column, Object val, SqlLike sqlLike) { return doIt(condition, () -> columnToString(column), keyword, () -> formatSql("{0}", SqlUtils.concatLike(val, sqlLike))); } /** * 普通查询条件 * * @param condition 是否执行 * @param column 属性 * @param sqlKeyword SQL 关键词 * @param val 条件值 */ protected Children addCondition(boolean condition, R column, SqlKeyword sqlKeyword, Object val) { return doIt(condition, () -> columnToString(column), sqlKeyword, () -> formatSql("{0}", val)); } /** * 多重嵌套查询条件 * * @param condition 查询条件值 */ protected Children addNestedCondition(boolean condition, Consumer<Children> consumer) { if (condition) { final Children instance = instance(); consumer.accept(instance); return doIt(true, APPLY, instance); } return typedThis; } /** * 子类返回一个自己的新对象 */ protected abstract Children instance(); /** * 格式化SQL * * @param sqlStr SQL语句部分 * @param params 参数集 * @return sql */ protected final String formatSql(String sqlStr, Object... params) { return formatSqlIfNeed(true, sqlStr, params); } /** * <p> * 根据需要格式化SQL<br> * <br> * Format SQL for methods: EntityQ<T>.where/and/or...("name={0}", value); * ALL the {<b>i</b>} will be replaced with #{MPGENVAL<b>i</b>}<br> * <br> * ew.where("sample_name=<b>{0}</b>", "haha").and("sample_age ><b>{0}</b> * and sample_age<<b>{1}</b>", 18, 30) <b>TO</b> * sample_name=<b>#{MPGENVAL1}</b> and sample_age>#<b>{MPGENVAL2}</b> and * sample_age<<b>#{MPGENVAL3}</b><br> * </p> * * @param need 是否需要格式化 * @param sqlStr SQL语句部分 * @param params 参数集 * @return sql */ protected final String formatSqlIfNeed(boolean need, String sqlStr, Object... params) { if (!need || StringUtils.isBlank(sqlStr)) { return null; } if (ArrayUtils.isNotEmpty(params)) { for (int i = 0; i < params.length; ++i) { String genParamName = Constants.WRAPPER_PARAM + paramNameSeq.incrementAndGet(); sqlStr = sqlStr.replace(String.format("{%s}", i), String.format(Constants.WRAPPER_PARAM_FORMAT, Constants.WRAPPER, genParamName)); paramNameValuePairs.put(genParamName, params[i]); } } return sqlStr; } /** * 获取in表达式 包含括号 * * @param value 集合 */ private ISqlSegment inExpression(Collection<?> value) { return () -> value.stream().map(i -> formatSql("{0}", i)) .collect(joining(StringPool.COMMA, StringPool.LEFT_BRACKET, StringPool.RIGHT_BRACKET)); } /** * 必要的初始化 */ protected void initNeed() { paramNameSeq = new AtomicInteger(0); paramNameValuePairs = new HashMap<>(16); expression = new MergeSegments(); lastSql = SharedString.emptyString(); sqlComment = SharedString.emptyString(); sqlFirst = SharedString.emptyString(); } @Override public void clear() { entity = null; paramNameSeq.set(0); paramNameValuePairs.clear(); expression.clear(); lastSql.toEmpty(); sqlComment.toEmpty(); sqlFirst.toEmpty(); } /** * 对sql片段进行组装 * * @param condition 是否执行 * @param sqlSegments sql片段数组 * @return children */ protected Children doIt(boolean condition, ISqlSegment... sqlSegments) { if (condition) { expression.add(sqlSegments); } return typedThis; } @Override public String getSqlSegment() { return expression.getSqlSegment() + lastSql.getStringValue(); } @Override public String getSqlComment() { if (StringUtils.isNotBlank(sqlComment.getStringValue())) { return "/*" + StringEscape.escapeRawString(sqlComment.getStringValue()) + "*/"; } return null; } @Override public String getSqlFirst() { if (StringUtils.isNotBlank(sqlFirst.getStringValue())) { return StringEscape.escapeRawString(sqlFirst.getStringValue()); } return null; } @Override public MergeSegments getExpression() { return expression; } public Map<String, Object> getParamNameValuePairs() { return paramNameValuePairs; } /** * 获取 columnName */ protected String columnToString(R column) { return (String) column; } /** * 多字段转换为逗号 "," 分割字符串 * * @param columns 多字段 */ protected String columnsToString(R... columns) { return Arrays.stream(columns).map(this::columnToString).collect(joining(StringPool.COMMA)); } @Override @SuppressWarnings("all") public Children clone() { return SerializationUtils.clone(typedThis); } } 查询username包含字符k,并且age要大于等于25并且小于等于35、password不能为null。 package com.kaven.mybatisplus.dao; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.kaven.mybatisplus.entity.User; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.util.List; @RunWith(SpringRunner.class) @SpringBootTest public class UserMapperWrapperTest { @Autowired private UserMapper userMapper; @Test public void selectList2(){ QueryWrapper<User> userQueryWrapper = new QueryWrapper<>(); // QueryWrapper<User> userQueryWrapper = Wrappers.query(); 和上面一样的效果 userQueryWrapper.like("username" , "k") .between("age" , 25 , 35) .isNotNull("password"); List<User> userList = userMapper.selectList(userQueryWrapper); userList.forEach(System.out::println); } }结果如下:
很明显,结果也是正确的。
查询username首字符为k,或者age要大于等于20,再按照age降序排列,age相同时按照id升序排列。 package com.kaven.mybatisplus.dao; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.kaven.mybatisplus.entity.User; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.util.List; @RunWith(SpringRunner.class) @SpringBootTest public class UserMapperWrapperTest { @Autowired private UserMapper userMapper; @Test public void selectList3(){ QueryWrapper<User> userQueryWrapper = new QueryWrapper<>(); // QueryWrapper<User> userQueryWrapper = Wrappers.query(); 和上面一样的效果 userQueryWrapper.likeRight("username" , "k") .or() .ge("age" , 20) .orderByDesc("age") .orderByAsc("id"); List<User> userList = userMapper.selectList(userQueryWrapper); userList.forEach(System.out::println); } }结果如下:
很明显,结果也是正确的(id是字符串,不是整型)。
查询username首字符为k,或者(age要大于等于22并且小于等于40,并且password不能为null)。 package com.kaven.mybatisplus.dao; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.kaven.mybatisplus.entity.User; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.util.List; @RunWith(SpringRunner.class) @SpringBootTest public class UserMapperWrapperTest { @Autowired private UserMapper userMapper; @Test public void selectList4(){ QueryWrapper<User> userQueryWrapper = new QueryWrapper<>(); // QueryWrapper<User> userQueryWrapper = Wrappers.query(); 和上面一样的效果 userQueryWrapper.likeRight("username" , "k") .or(e -> e.between("age" , 22 , 40) .isNotNull("password")); List<User> userList = userMapper.selectList(userQueryWrapper); userList.forEach(System.out::println); } }结果如下:
很明显,结果也是正确的。
查询(age要大于等于22并且小于等于40,并且password不能为null)并且username首字符为k。这个例子不太好,看懂意思就行了。 package com.kaven.mybatisplus.dao; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.kaven.mybatisplus.entity.User; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.util.List; @RunWith(SpringRunner.class) @SpringBootTest public class UserMapperWrapperTest { @Autowired private UserMapper userMapper; @Test public void selectList5(){ QueryWrapper<User> userQueryWrapper = new QueryWrapper<>(); // QueryWrapper<User> userQueryWrapper = Wrappers.query(); 和上面一样的效果 userQueryWrapper.nested(e -> e.between("age" , 22 , 40) .isNotNull("password")) .and(e -> e.likeRight("username" , "k")); // and()其实没必要写,这里只是为了演示,因为这里sql默认就是按照and连接的 List<User> userList = userMapper.selectList(userQueryWrapper); userList.forEach(System.out::println); } }结果如下:
这里结果也是正确的。
从AbstractWrapper<T, String, QueryWrapper<T>>的源码也可以看到,or()、and()、nested()方法都可以传Consumer<T>类型的参数,这是一个函数式接口,想了解可以去看一下这篇博客。
Consumer 接口 、 Predicate 接口初使用
查询age属于[22 , 20 , 30 , 45]。 package com.kaven.mybatisplus.dao; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.kaven.mybatisplus.entity.User; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.util.Arrays; import java.util.List; @RunWith(SpringRunner.class) @SpringBootTest public class UserMapperWrapperTest { @Autowired private UserMapper userMapper; @Test public void selectList6(){ QueryWrapper<User> userQueryWrapper = new QueryWrapper<>(); // QueryWrapper<User> userQueryWrapper = Wrappers.query(); 和上面一样的效果 userQueryWrapper.in("age" , Arrays.asList(22 , 20 , 30 , 45)); List<User> userList = userMapper.selectList(userQueryWrapper); userList.forEach(System.out::println); } }结果如下:
同样结果也是正确的。
查询age属于[22 , 20 , 30 , 45],并且只输出一个。 package com.kaven.mybatisplus.dao; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.kaven.mybatisplus.entity.User; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.util.Arrays; import java.util.List; @RunWith(SpringRunner.class) @SpringBootTest public class UserMapperWrapperTest { @Autowired private UserMapper userMapper; @Test public void selectList7(){ QueryWrapper<User> userQueryWrapper = new QueryWrapper<>(); // QueryWrapper<User> userQueryWrapper = Wrappers.query(); 和上面一样的效果 userQueryWrapper.in("age" , Arrays.asList(22 , 20 , 30 , 45)).last("limit 1"); List<User> userList = userMapper.selectList(userQueryWrapper); userList.forEach(System.out::println); } }结果如下: 显然也是正确的。
我们这里先不讨论方法是否有sql注入的风险。
这就是MyBatis-Plus使用条件构造器进行查询,是不是很方便,这里只演示了查询的条件构造器,其他条件构造器也是差不多的用法,只是个别方法有区别而已,以后的MyBatis-Plus学习博客也只以查询方法进行介绍。
写博客是博主记录自己的学习过程,如果有错误,请指正,谢谢!