史上最简单的mybatis-plus快速入门

mybatis-plus快速入门

介绍:
Mybatis-Plus(简称MP)是一个Mybatis的增强工具,在Mybatis的基础上只做增强不做改变,为简化开发,提高效率而生。
数据库表:

-- 创建表
CREATE TABLE tbl_employee(
   id INT(11) PRIMARY KEY AUTO_INCREMENT,
   last_name VARCHAR(50),
   email VARCHAR(50),
   gender CHAR(1),
   age INT
);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Tom','[email protected]',1,22);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Jerry','[email protected]',0,25);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('Black','[email protected]',1,30);
INSERT INTO tbl_employee(last_name,email,gender,age) VALUES('White','[email protected]',0,35);

一:实体类的配置

mybatis-plus常用的实体类注解

@TableName:对数据表名注解
@TableId:表主键标识
@TableId(value = "id", type = IdType.AUTO):自增
@TableId(value = "id", type = IdType.ID_WORKER_STR):分布式全局唯一ID字符串类型
@TableId(value = "id", type = IdType.UUID)32UUID字符串
@TableField:表字段标识
@TableField(exist = false):表示该属性不为数据库表字段,但又是必须使用的。
@Version:乐观锁注解、标记
@EnumValue:通枚举类注解
@TableLogic:表字段逻辑处理注解(逻辑删除)
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("tbl_employee")
public class Employee {

    @TableId(value = "id",type= IdType.AUTO)
    private Integer id;
    @TableField("last_name")
    private String lastName;
    private String email;
    private Integer gender;
    private Integer age;
}

二:增删查改的实现

让编写的mapper接口继承BaseMapper接口

/**
 * 基于Mybatis‐plus实现: 让XxxMapper接口继承 BaseMapper接口即可.
 * BaseMapper : 泛型指定的就是当前Mapper接口所操作的实体类类型
 */
@Repository
public interface EmployeeMapper extends BaseMapper<Employee> {
    
}

测试:

@SpringBootTest
@RunWith(SpringRunner.class)
public class EmployeeMapperTest {

    @Autowired
    private EmployeeMapper employeeMapper;

    @Test
    public void select(){
        Object o = employeeMapper.selectById(1);
        System.out.println(o);
    }

    @Test
    public void insert(){
        Employee employee = new Employee(null, "xushu", "dasda", 1, 211);
        employeeMapper.insert(employee);
    }
    @Test
    public void update(){
        Employee employee = new Employee(4, "xushu", "dasda", 1, 211);
        employeeMapper.updateById(employee);
    }

    @Test
    public void delete(){
        Employee employee = new Employee(4, "xushu", "dasda", 1, 211);
        int i = employeeMapper.deleteById(4);
    }

    @Test
    public void selectList(){
        HashMap<String, Object> objectObjectHashMap = new HashMap<>();
        objectObjectHashMap.put("gender",1);
        List<Employee> employees = employeeMapper.selectByMap(objectObjectHashMap);
        System.out.println(employees);

    }


}

三:条件构造器Wrapper

史上最简单的mybatis-plus快速入门_第1张图片
(1)Wrapper :条件构造抽象类,最顶端父类,抽象类中提供3个方法以及其他方法.
(2)AbstractWrapper : 用于查询条件封装,生成 sql 的 where 条件,QueryWrapper(LambdaQueryWrapper) 和 UpdateWrapper(LambdaUpdateWrapper) 的父类用于生成 sql 的 where 条件, entity 属性也用于生成 sql 的 where 条件
(3)AbstractLambdaWrapper : Lambda 语法使用 Wrapper统一处理解析 lambda 获取 column。 (4)LambdaQueryWrapper :看名称也能明白就是用于Lambda语法使用的查询Wrapper (5)LambdaUpdateWrapper : Lambda 更新封装Wrapper
(6)QueryWrapper : Entity 对象封装操作类,不是用lambda语法,自身的内部属性 entity 也用于生成 where 条件 该类的重要方法:

具体用法请查该地址:mybatis-plus条件构造器
样例:

@Test
    public void selectWrapper(){
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();
        wrapper.
                between("age",18,30);
        List<Employee> list = employeeService.list(wrapper);
        System.out.println(employeeService.list(wrapper));
    }

    @Test
    public void updateWrapper(){
        UpdateWrapper<Employee> wrapper = new UpdateWrapper<>();
        wrapper.set("last_name","wang").eq("id",1);
        boolean update = employeeService.update(wrapper);
        System.out.println(update);
        selectWrapper();
    }

    // 使用lambda表达式查询

    @Test
    public void lambdaSelect(){
        QueryWrapper<Employee> wrapper = new QueryWrapper<>();

        wrapper.lambda()
                .select(Employee::getLastName,Employee::getAge)
                .eq(Employee::getLastName,"wang");

        System.out.println(employeeService.list(wrapper));
    }

四:全局id生成策略

在yaml文件中使用配置

mybatis-plus:
  configuration:
  // 开启驼峰命名法
    map-underscore-to-camel-case: true
  global-config:
    db-config:
    // 设置全局的主键自增,不需要给每一个都配置
      id-type: auto

测试样例

   @Test
    public void insertWrapper(){
        Employee employee = new Employee(null,"hei","dasd",1,32);
        employeeService.save(employee);
        System.out.println(employee);
    }

五:MyBatis-Plus逻辑删除

物理删除: 在删除的时候直接将数据从数据库干掉DELTE
逻辑删除: 从逻辑层面控制删除,通常会在表里添加一个逻辑删除的字段比如 enabled 、is_delete ,数据默认是有效的(值为1), 当用户删除时将数据修改UPDATE 0, 在查询的时候就只查where enabled=1.

方法一:在数据库中增加一个判断是否删除的字段

@TableLogic()
    private Integer enabled;

mybatis-plus对于是否删除的默认判断:0是未删除,1是已删除 由于不太符合常用的规则,可以自定义是否删除的标志

/**
     * 未删除的数据为1,已删除的数据为0
     */
    @TableLogic(value = "1",delval = "0")
    private Integer enabled;

方法二:在yaml文件中配置是否删除

mybatis-plus:
  configuration:
    map-underscore-to-camel-case: true
  global-config:
    db-config:
      id-type: auto
      logic-delete-field: enabled  #判断是否删除的字段,逻辑删除的字段
      logic-not-delete-value: 1  #没有删除1
      logic-delete-value: 0   #已删除是0

六:MyBatis-Plus自动填充

在表中添加 create_date和modify_date两个字段,如何做到自动填充数据
方法一:不建议使用
设置create_date、modify_date的默认值为CURRENT_TIMESTA-MP
方法二:使用mybatis-plus带的注解@TableField

 // 创建时间,希望在添加数据的时候填充:当前时间
    @TableField(value = "create_date",fill = FieldFill.INSERT)
    private Date createDate;

    // 修改时间:希望在修改数据和添加数据的时候填充
    @TableField(value = "modify_date",fill = FieldFill.INSERT_UPDATE)
    private Date modifyDate;

添加一个配置类MyMetaObjectHandler用于设置填充的时间

@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
    @Override
    public void insertFill(MetaObject metaObject) {
        // 插入时:创建时间和修改时间
        this.setFieldValByName("createDate",new Date(),metaObject);
        this.setFieldValByName("modifyDate",new Date(),metaObject);
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        this.setFieldValByName("modifyDate",new Date(),metaObject);


    }
}

七:MyBatis-Plus执行SQL分析打印

SQL分析打印:可以查看SQL的执行时间,最大的好处时显示除mybatis执行的sql的具体语句
样例:

2022-04-16 18:31:17.425 DEBUG 22096 --- [           main] c.e.q.mapper.EmployeeMapper.update       : ==> Parameters: black(String), 2055(String), 1(Integer), 98(Integer), 2022-04-16 18:31:16.959(Timestamp), 10(Integer)
 Consume Time:351 ms 2022-04-16 18:31:17
 Execute SQLUPDATE tbl_employee SET last_name='black', email='2055', gender=1, age=98, modify_date='2022-04-16T18:31:16.959+0800' WHERE enabled=1 AND (id = 10)

第一步:添加依赖

>
            >p6spy>
            >p6spy>
            >3.9.1>
        >

第二步:更改yaml中的配置
将url和driver-class-name更改

spring:
  datasource:
    url: jdbc:p6spy:mysql://localhost:3306/mybatis_plus?characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
    username: root
    password: root
    driver-class-name: com.p6spy.engine.spy.P6SpyDriver
    type: com.alibaba.druid.pool.DruidDataSource

第三步:添加一个spy.properties文件

#3.2.1以上使用
modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory
#3.2.1以下使用或者不配置
#modulelist=com.p6spy.engine.logging.P6LogFactory,com.p6spy.engine.outage.P6OutageFactory
# 自定义日志打印
logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger
#日志输出到控制台
appender=com.baomidou.mybatisplus.extension.p6spy.StdoutLogger
# 使用日志系统记录 sql
#appender=com.p6spy.engine.spy.appender.Slf4JLogger
# 设置 p6spy driver 代理
deregisterdrivers=true
# 取消JDBC URL前缀
useprefix=true
# 配置记录 Log 例外,可去掉的结果集有error,info,batch,debug,statement,commit,rollback,result,resultset.
excludecategories=info,debug,result,commit,resultset
# 日期格式
dateformat=yyyy-MM-dd HH:mm:ss
# 实际驱动可多个
#driverlist=org.h2.Driver
# 是否开启慢SQL记录
outagedetection=true
# 慢SQL记录标准 2 秒
outagedetectioninterval=2

注意!

driver-class-name 为 p6spy 提供的驱动类
url 前缀为 jdbc:p6spy 跟着冒号为对应数据库连接地址
打印出 sql 为 null,在 excludecategories 增加 commit
批量操作不打印 sql,去除 excludecategories 中的 batch
批量操作打印重复的问题请使用 MybatisPlusLogFactory (3.2.1 新增)
该插件有性能损耗,不建议生产环境使用。

八:MyBatis-Plus乐观锁

第一:什么是乐观锁 悲观锁:
悲观锁,正如其名,具有强烈的独占和排他特性。它指的是对数据被外界(包括本系统当前的其他事 务,以及来自外部系统的事务处理)修改持保守态度。因此,在整个数据处理过程中,将数据处于锁定状态。 假设功能并发量非常大,就需要使用synchronized来处理高并发下产生线程不安全问题, 会使其他线程进行挂起等待从 而影响系统吞吐量 。
乐观锁:乐观锁是相对悲观锁而言的,乐观锁假设数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正 式对数据的冲突与否进行检测,如果发现冲突了,则返回给用户错误的信息,让用户决定如何去做。乐观锁适用于读操作多的场 景,这样可以提高程序的吞吐量。 假设功能产生并发几率极少,采用乐观锁版本机制对比, 如果有冲突 返回给用户错 误的信息

1.mybatis的配置

@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
    MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
    interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
    return interceptor;
}

2在实体类的字段上加上@Version注解

@Version
private Integer version;

样例:

    @Test
    public void testCAS(){

        // 线程1 age50 version1
        Employee employee1 = employeeService.getById(1);


        // 线程2 age50 version 1
        Employee employee2 = employeeService.getById(1);

        employee1.setAge(100);
        employee2.setAge(50);

        System.out.println(employeeService.updateById(employee1));

        System.out.println(employeeService.updateById(employee2));

    }

九:MyBatis-Plus分页

直接在启动类中增加就可

@Configuration
@MapperScan("scan.your.mapper.package")
public class MybatisPlusConfig {

    /**
     * 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题(该属性会在旧插件移除后一同移除)
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2));
        return interceptor;
    }

    @Bean
    public ConfigurationCustomizer configurationCustomizer() {
        return configuration -> configuration.setUseDeprecatedExecutor(false);
    }
}

xml文件配置

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.example.quickstart.mapper.EmployeeMapper">
    <select id="getByGender" resultType="com.example.quickstart.pojo.Employee">
        SELECT  * FROM  tbl_employee
    </select>

    <select id="selectAll" resultType="com.example.quickstart.pojo.Employee">
        SELECT  * FROM tbl_employee
    </select>
</mapper>

mapper层(持久层)

/**
 * 基于Mybatis‐plus实现: 让XxxMapper接口继承 BaseMapper接口即可.
 * BaseMapper : 泛型指定的就是当前Mapper接口所操作的实体类类型
 */
@Repository
public interface EmployeeMapper extends BaseMapper<Employee> {
    IPage<Employee> getByGender(IPage page);

    List<Employee> selectAll();
}

样例测试

    @Test
    public void xmlPage(){
        IPage<Employee> iPage = new Page<>(5,1);
        IPage<Employee> page = employeeMapper.getByGender(iPage);
        System.out.println(page.getSize());
        List<Employee> records = page.getRecords();
        System.out.println(page.getPages());
        System.out.println(records);
    }

测试:

    @Test
    public void page(){
        IPage<Employee> iPage = new Page<>(1,3);
        IPage<Employee> page = employeeImplService.page(iPage);

        List<Employee> records = page.getRecords();
        for (Employee record: records){
            System.out.println(record);
        }
        System.out.println(page.getPages());

    }

你可能感兴趣的:(mybatis,mybatis,mybatis-plus)