MyBatis-Plus视频教程网站https://www.imooc.com/learn/1130
以下是学习过程中的一些知识点记录。
第一章
- Mybatis-Plus(MP)在 MyBatis 的基础上只做增强不做改变,简化开发、提高效率。
- MyBatus的优势:
(1).SQL语句可以自由控制,更灵活,性能高
(2).SQL与代码分类,易于阅读和维护
(3).提高XML标签,支持编写动态SQL语句 - MyBatis的劣势:
(1).简单CRUD操作还需要些SQL语句
(2).XML中有大量的SQL要维护
(3).MyBatis自身功能很有限,但支持->>Plugin - JPA优势:
(1).JPA移植性比较好(JPQ)
(2).提供很多CRUD方法,开发效率高
(3).对象化程度更高 - MyBatis-Plus特性:
- 无侵入、损耗小、强大的CRUD操作
- 支持Lambda形式调用、支持多种数据库
- 支持主键自动生成、支持ActiveRecord模式
- 支持自定义全局通用操作、支持关键词自动转义
- 内置代码生成器、内置分页插件、内置性能分析插件
- 内置全局拦截插件、内置sql注入剥离器
- 引入Lombok的注解@Data可以帮助我们在实体类中自动增加getter、 setter方法使我们开发出错率降低。
- 使用MP的方法需要**mapper接口继承BaseMapper<T>,T是要操作的实体类。
第二章
- 在对数据库表进行新增操作时,如果没有设置id这个字段的值,MP会自动默认填充。
- 如果数据库表名和项目中实体类名不一致,可以在实体类中使用MP的注解@TableName("数据库表名")使它们对应起来。
@TableName("mp_user")
public class User{}
- 使用MP的注解@TableId可以设置某个实体类的某个变量对应数据库中某个表的主键。
@Table(value = "数据库主键名", type = IdType.AUTO)
private String id;
type是id的类型(可选):
public enum IdType {
AUTO(0),
NONE(1),
INPUT(2),
ID_WORKER(3),
UUID(4),
ID_WORKER_STR(5);
- @TableField("数据库字段名")注解,使用在实体类的变量上,使该变量与数据库中某个表的某个字段形成对应关系。
- 当实体类中的某个变量只做存放临时数据、不和数据库表中的字段做对应关系时,有三种解决方法:
1.在实体类的某个变量上添加“transient”关键字,表示该变量不参与序列化过程。
private transient String name;
2.添加“static”关键字。
private static String name;
3.使用@TableField(exist = false表示该变量不是数据库表中的字段)
@TableField(exist = false)
private String name;
第三章
MP的内置CURD方法(传入的参数名必须是数据库表中的字段名),使用这些方法就不需要再去写sql语句:
- selectById方法,根据id查询一条信息。
- selectBatchIds方法,可以传入多个id,查询返回一个列表list。
- selectByMap方法,传入一个Map集合,里面key的值是一个Object类型,那么key就可以存表字段,Object就可以存字段值。查询返回一个列表。
- AbstractWrapper条件构造器,一个抽象类,里面提供了许多查询条件的抽象方法,QueryWrapper是AbstractWrapper的一个子类。
- selectList方法,需要传入一个条件构造器对象,返回查询的记录列表。
- 比如“查询名字为王姓并且(年龄小于40或邮箱不为空)这么一个需求”,翻译成sql语句就是name like '王%' and (age<40 or email is not null),写成条件构造器的形式就是:
queryWrapper.likeRight("name","王").and(qw->qw.lt("age",40).or().isNotNull("email"));
其中的and方法需要传一个函数式接口,这里的类型是QueryWrapper,返回也是QueryWrapper类型,所以这里就使用了lambda表达式,箭头左边是形式参数,箭头右边是方法实现。
- 查询不列出全部字段,需要用到select()方法,括号里面写要查询的参数名(可一个或多个)。如果表中字段过多,可以在select方法的括号中进行逻辑处理select(实体类.class, 形参->!形参.getColumn().equals("字段名")&&....)
queryWrapper.select(实体类.class, 形参->!形参.getColumn().equals("字段名")&&....)
- 条件构造器中比如AbstractWrapper中有许多方法的第一个参数是一个boolean类型的condition,它的作用是执行条件,表示当前这个条件方法是否加入最后生成的sql语句中,如果是true就加入,false就不加入。
应用场景:提供给用户输入时的查询条件,用户可以选择输入或者不输入。 - 除了用条件构造器调用条件抽象方法外,还可以用实体类对象作为条件构造器方法的参数来设置查询条件。两种方法同时使用时互不干扰,这两种方法的条件会同时出现在sql语句中。
- 用实体类对象作为条件构造器方法的参数来设置查询条件是,条件都是等值怎么办,比如“查询名字为王姓”可以在实体类的name变量上添加@TableField注解括号里面
condition=SqlCondition.LIKE,SqlConditon里有定义好的常量,可以之间调用。
@TableField(condition=SqlCondition.LIKE)
private String name;
package com.baomidou.mybatisplus.annotation;
public class SqlCondition {
public static final String EQUAL = "%s=#{%s}";
public static final String NOT_EQUAL = "%s<>#{%s}";
public static final String LIKE = "%s LIKE CONCAT('%%',#{%s},'%%')";
public static final String LIKE_LEFT = "%s LIKE CONCAT('%%',#{%s})";
public static final String LIKE_RIGHT = "%s LIKE CONCAT(#{%s},'%%')";
public SqlCondition() {
}
}
- allEq(Map<R, V> params,boolean null2IsNull)方法中的第二个参数为ture时,则在map的value为null是调用isNull方法,为false是则忽略value为null。通俗说前者就是要查包含字段为空的结果,或者就是不查字段为空的结果。
- lambda条件构造器,创建对象三个方法:
1.LambdaQueryWrapper<T> lambdaQueryWrapper = new LambdaQueryWrapper<>();
2.LambdaQueryWrapper<T> lambdaQueryWrapper = new QueryWrapper.lambda();
3.LambdaQueryWrapper<T> lambdaQueryWrapper = Wrappers.<User>lambdaQuery(); - 比如使用lambdaQueryWrapper.like(User::getName, "王"),这样写可以防止字段名写错。
第四章
- 使用自定义sql时传入一个条件构造器时,需要在mapper抽象方法上添加注解,比如查询查询时添加:
@select("select * from user ${ew.customSqlSegment}")
List<User> selectAll(@Param(Constants.WRAPPER)Wrapper<User> wrapper);
- selectPage(),selectMapsPage()方法,第一个参数是传分页条件对象Page,第二个是传条件构造器对象,返回一个IPage接口对象,两者的区别是返回的IPage接口对象类型不一样,第一个是返回实体类型,第二个是返回Map类型。
IPage<T> selectPage(IPage<T> var1, @Param("ew") Wrapper<T> var2);
IPage<Map<String, Object>> selectMapsPage(IPage<T> var1, @Param("ew") Wrapper<T> var2);
第五章
- UpdateWrapper也是AbstractWrapper的一个子类,在MP自带的update()方法中用到了它。
- LambdaUpdateWrapper条件构造器也跟LambdaQueryWrapper类似。
- deleteByMap()方法,该方法传入一个Map,key代表字段名,value代表字段值,删除符合该键值对条件的记录。
- deleteBatchIds()方法,该方法传入一个id集合,批量删除记录。
- delete()方法,传入一个条件构造器,删除符号条件构造器里面的条件的记录。
第六章
- ActiveRecord(AR)模式,通过实体类对象直接对数据库表的增删改查。
- AR模式在MP中有两个具体的要求:
1.首先要继承Model<T>,继承后会报没有调用父类警告,这是要添加@EqualsAndHashCode(callSuper=false),添加serialVersionUID = 1L
@EqualsAndHashCode(callSuper=false)
public class User extends Model<T>{
private static final long serialVersionUID = 1L
....
}
2.必须存在对应原始的Mapper接口并继承BaseMapper。
public interface UserMapper extends BaseMapper<User>{}
- insertOrUpdate()方法,MP会先查询数据库中是否有该记录,如果有的话进行更新,没有的话进行插入。
- MP的主键策略定义在IdType枚举类中。
- 全局主键策略,当插入对象ID为空,才自动填充。有:
ID_WORKER、UUID、ID_WORKER_STR - 局部主键策略,通过@TableId(type=IdType.**)设置.
- MyBatis-plus的基本配置,参考官网https://mybatis.plus/config/
- 字段策略中的not_empty,当你传入的参数为null或为空字符串时自动忽略掉,不写进sql语句中。
第七章
- 通用Service,的getOne()方法,有两个参数,第一个是条件构造器对象,第二个是boolean类型,如果是true,查询结果多个会报错,而false的话就只报出警告,取第一个。