MyBatisPlus-黑马-笔记

MyBatisPlus


MybatisPlus(简称MP)是基于MyBatis框架基础上开发的增强型工具,旨在简化开发、提供效率。

入门案例

package com.itheima.dao;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.itheima.domain.User;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface UserDao extends BaseMapper<User> {
}

MP的特性:

  • 无侵入:只做增强不做改变,不会对现有工程产生影响
  • 强大的 CRUD 操作:内置通用 Mapper,少量配置即可实现单表CRUD 操作
  • 支持 Lambda:编写查询条件无需担心字段写错
  • 支持主键自动生成
  • 内置分页插件

标准数据层开发

标准CRUD使用

在这里插入图片描述

package com.itheima;

import com.itheima.dao.UserDao;
import com.itheima.domain.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

@SpringBootTest
class Myp01ApplicationTests {

    @Autowired
    private UserDao userDao;

    @Test
    void testSave(){
        User user = new User();
        user.setName("wyuy");
        user.setAge(18);
        user.setPassword("123456");
        user.setTel("400000000");
        userDao.insert(user);
    }

    @Test
    void testUpdate(){
        User user = new User();
        user.setId(1L);
        user.setName("666");
        userDao.updateById(user);
    }

    @Test
    void testGetById(){
        User user = userDao.selectById(2L);
        System.out.println(user);
    }

    @Test
    void testDelete(){
        userDao.deleteById(1543586654940942338L);
    }

    @Test
    void testGetAll() {
        List<User> userList = userDao.selectList(null);
        System.out.println(userList);
    }

}

 		<dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        ======================
//lombok
//@Setter
//@Getter
//@ToString
//@NoArgsConstructor
//@AllArgsConstructor
//@EqualsAndHashCode
@Data
public class User {
    private Long id;
    private String name;
    private String password;
    private Integer age;
    private String tel;

}

分页

    @Test
    void testGetByPage(){
        //1 创建IPage分页对象,设置分页参数,1为当前页码,3为每页显示的记录数
        IPage page = new Page(1,2);
        //2 执行分页查询
        userDao.selectPage(page,null);
        //3 获取分页结果
        System.out.println("当前页码值:"+page.getCurrent());
        System.out.println("每页显示数:"+page.getSize());
        System.out.println("一共多少页:"+page.getPages());
        System.out.println("一共多少条数据:"+page.getTotal());
        System.out.println("数据:"+page.getRecords());
    }
package com.itheima.config;

import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MpConfig {
    @Bean
    public MybatisPlusInterceptor mpInterceptor(){
        //1 创建MybatisPlusInterceptor拦截器对象
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        //2 添加分页拦截器
        mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        return mybatisPlusInterceptor;
    }
}

DQL编程控制

条件查询

@SpringBootTest
class Myp02ApplicationTests {

    @Autowired
    private UserDao userDao;

    @Test
    void testGetAll() {
        //方式一: 条件查询
        QueryWrapper qw = new QueryWrapper();
        qw.lt("age",18);
        List<User> userList = userDao.selectList(qw);
        System.out.println(userList);

//        //方式二: Lambda条件查询
        QueryWrapper<User> qw = new QueryWrapper<User>();
        qw.lambda().lt(User::getAge,10);
        List<User> userList = userDao.selectList(qw);
        System.out.println(userList);

        //方式三: Lambda条件查询
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
        lqw.lt(User::getAge,10);
        List<User> userList = userDao.selectList(lqw);
        System.out.println(userList);

        //多条件
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
        //10-30
        lqw.lt(User::getAge,30).gt(User::getAge,10);
        //<10  >30
        lqw.lt(User::getAge,10).or().gt(User::getAge,30);
        List<User> userList = userDao.selectList(lqw);
        System.out.println(userList);
    }

}

null判定

 //模拟页面传递过来的查询数据
        UserQuery uq = new UserQuery();
       // uq.setAge(10);
        uq.setAge2(30);

        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
//        lqw.lt(User::getAge,uq.getAge2());
        lqw.lt(null != uq.getAge2(),User::getAge,uq.getAge2());
        lqw.gt(null != uq.getAge(),User::getAge,uq.getAge());
//        lqw.gt(User::getAge,uq.getAge());
        List<User> userList = userDao.selectList(lqw);
        System.out.println(userList);

查询投影

//查询投影
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
        lqw.select(User::getId,User::getName,User::getAge);
        List<User> userList = userDao.selectList(lqw);
        System.out.println(userList);

        QueryWrapper<User> qw = new QueryWrapper<User>();
        qw.select("id","name","age");
        List<User> userList1 = userDao.selectList(qw);
        System.out.println(userList1);
QueryWrapper<User> qw = new QueryWrapper<User>();
        //计数
        qw.select("count(*) as count, tel");
        //分组
        qw.groupBy("tel");
        List<Map<String,Object>> userList2 = userDao.selectMaps(qw);
        System.out.println(userList2);
@SpringBootTest
class Mybatisplus02DqlApplicationTests {
@Autowired
private UserDao userDao;
@Test
void testGetAll(){
QueryWrapper<User> lqw = new QueryWrapper<User>();
//lqw.select("count(*) as count");
//SELECT count(*) as count FROM user
//lqw.select("max(age) as maxAge");
//SELECT max(age) as maxAge FROM user
//lqw.select("min(age) as minAge");
//SELECT min(age) as minAge FROM user
//lqw.select("sum(age) as sumAge");
//SELECT sum(age) as sumAge FROM user
lqw.select("avg(age) as avgAge");
//SELECT avg(age) as avgAge FROM user
List<Map<String, Object>> userList = userDao.selectMaps(lqw);
System.out.println(userList);
}
}

查询条件

等值查询

//条件查询
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
        lqw.eq(User::getName,"Jerry").eq(User::getPassword,"jerry");
        User user = userDao.selectOne(lqw);
        System.out.println(user);

范围查询

// 范围查询
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
        //使用lt()、le()、gt()、ge()、between()进行范围查询
        lqw.between(User::getAge,10,30);
        List<User> userList = userDao.selectList(lqw);
        System.out.println(userList);
  • gt():大于(>)
  • ge():大于等于(>=)
  • lt():小于(<)
  • lte():小于等于(<=)
  • between():between? and ?

模糊查询

 // 模糊查询
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
        lqw.like(User::getName,"J");
        List<User> userList = userDao.selectList(lqw);
        System.out.println(userList);
  • like():前后加百分号,如 %J%
  • likeLeft():前面加百分号,如 %J
  • likeRight():后面加百分号,如 J%

映射匹配兼容性

  • 问题1:表字段与编码属性设计不同步
    MP给我们提供了一个注解@TableField ,使用该注解可以实现模型类属性名和表的列名之间的映射关
  • 问题2:编码中添加了数据库中未定义的属性
    具体的解决方案用到的还是@TableField 注解,它有一个属性叫exist ,设置该字段是否在数据库表中存在,如果设置为false则不存在,生成sql语句查询的时候,就不会再查询该字段了。
  • 问题3:采用默认查询开放了更多的字段查看权限
    解决方案是@TableField 注解的一个属性叫select ,该属性设置默认是否需要查询该字段的值,true(默认值)表示默认查询该字段,false表示默认不查询该字段。
  • 问题4:表名与编码开发设计不同步
    解决方案是使用MP提供的另外一个注解@TableName 来设置表与模型类之间的对应关系。
package com.itheima.domain;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

@Data
@TableName("tbl_user")
public class User {
    private Long id;
    private String name;
    @TableField(value = "pwd",select = false)
    private String password;
    private Integer age;
    private String tel;
    @TableField(exist = false)
    private Integer online;
}

DML编程控制

id生成策略控制

  • NONE:不设置id生成策略,MP不自动生成,约等于INPUT,所以这两种方式都需要用户手动设置,但是手动设置第一个问题是容易出现相同的ID造成主键冲突,为了保证主键不冲突就需要做很多判定,实现起来比较复杂
  • AUTO:数据库ID自增,这种策略适合在数据库服务器只有1台的情况下使用,不可作为分布式ID使用
  • ASSIGN_UUID:可以在分布式的情况下使用,而且能够保证唯一,但是生成的主键是32位的字符串,长度过长占用空间而且还不能排序,查询性能也慢
  • ASSIGN_ID:可以在分布式的情况下使用,生成的是Long类型的数字,可以排序性能也高,但是生成的策略和服务器时间有关,如果修改了系统时间就有可能导致出现重复主键
  • 综上所述,每一种主键策略都有自己的优缺点,根据自己项目业务的实际情况来选择使用才是最明 智的选择。
package com.itheima.domain;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

@Data
@TableName("tbl_user")
public class User {
//    @TableId(type = IdType.AUTO)
//    @TableId(type = IdType.INPUT)
    @TableId(type = IdType.ASSIGN_ID)
    private Long id;
    private String name;
    @TableField(value="pwd",select=false)
    private String password;
    private Integer age;
    private String tel;
    @TableField(exist=false)
    private Integer online;
}

# mp日志
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  global-config:
   banner: false
   db-config:
    id-type: assign_id
    table-prefix: tbl_

多记录操作

@Test
    void testDelete(){
        List<Long> list = new ArrayList<>();
        list.add(1543586654940942339L);
        list.add(1543586654940942340L);
        list.add(1543849463314489346L);
        userDao.deleteBatchIds(list);

		list.add(1L);
        list.add(2L);
        list.add(3L);
        userDao.selectBatchIds(list);
    }

逻辑删除

 //逻辑删除字段,标记当前记录是否删除
    @TableLogic(value = "0",delval = "1")
    private Integer deleted;
    logic-delete-field: deleted
    logic-delete-value: 1
    logic-not-delete-value: 0

乐观锁

package com.itheima.domain;

import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;

@Data
//@TableName("tbl_user")
public class User {
//    @TableId(type = IdType.AUTO)
//    @TableId(type = IdType.INPUT)
//    @TableId(type = IdType.ASSIGN_ID)
    private Long id;
    private String name;
    @TableField(value="pwd",select=false)
    private String password;
    private Integer age;
    private String tel;
    @TableField(exist=false)
    private Integer online;
    //逻辑删除字段,标记当前记录是否删除
//    @TableLogic(value = "0",delval = "1")
    private Integer deleted;

    @Version
    private Integer version;
}

拦截器

@Configuration
public class MpConfig {
    @Bean
    public MybatisPlusInterceptor mpInterceptor(){
        MybatisPlusInterceptor mpInterceptor = new MybatisPlusInterceptor();
        mpInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return mpInterceptor;
    }
}

模拟

//模拟
        User user = userDao.selectById(3L); //version=3

        User user2 = userDao.selectById(3L);//version=3
        //2.将要修改的属性逐一设置进去
        user.setName("Jockaaa");
        userDao.updateById(user);

        user2.setName("Jockbbb");
        userDao.updateById(user2);

代码生成器实现

<!--代码生成器-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.4.1</version>
        </dependency>
        <!--velocity模板引擎-->
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>2.3</version>
        </dependency>
package com.itheima;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;

public class CodeGenerator {
    public static void main(String[] args) {
        //1.获取代码生成器的对象
        AutoGenerator autoGenerator = new AutoGenerator();
//设置数据库相关配置
        DataSourceConfig dataSource = new DataSourceConfig();
        dataSource.setDriverName("com.mysql.cj.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/mybatisplus_db? serverTimezone=UTC");
                dataSource.setUsername("root");
        dataSource.setPassword("123456");
        autoGenerator.setDataSource(dataSource);
//设置全局配置
        GlobalConfig globalConfig = new GlobalConfig();
        globalConfig.setOutputDir(System.getProperty("user.dir")+"/myp_04/src/main/java"); //设置代码生成位置
                globalConfig.setOpen(false); //设置生成完毕后是否打开生成代码所在的目录
        globalConfig.setAuthor("黑马程序员"); //设置作者
        globalConfig.setFileOverride(true); //设置是否覆盖原始生成的文件
        globalConfig.setMapperName("%sDao"); //设置数据层接口名,%s为占位符,指代模块名称
        globalConfig.setIdType(IdType.ASSIGN_ID); //设置Id生成策略
        autoGenerator.setGlobalConfig(globalConfig);
//设置包名相关配置
        PackageConfig packageInfo = new PackageConfig();
        packageInfo.setParent("com.aaa"); //设置生成的包名,与代码所在位置不冲突,二者叠加组成完整路径
        packageInfo.setEntity("domain"); //设置实体类包名
        packageInfo.setMapper("dao"); //设置数据层包名
        autoGenerator.setPackageInfo(packageInfo);
//策略设置
        StrategyConfig strategyConfig = new StrategyConfig();
        strategyConfig.setInclude("tbl_user"); //设置当前参与生成的表名,参数为可变参数
        strategyConfig.setTablePrefix("tbl_"); //设置数据库表的前缀名称,模块名 =数据库表名 - 前缀名 例如: User = tbl_user - tbl_
        strategyConfig.setRestControllerStyle(true); //设置是否启用Rest风格
        strategyConfig.setVersionFieldName("version"); //设置乐观锁字段名
        strategyConfig.setLogicDeleteFieldName("deleted"); //设置逻辑删除字段名
        strategyConfig.setEntityLombokModel(true); //设置是否启用lombok
        autoGenerator.setStrategy(strategyConfig);
//2.执行生成操作
        autoGenerator.execute();
    }
}

在这里插入图片描述


评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值