06 MyBatisPlus

lix_uan
• 阅读 101

SpringBoot整合MyBatisPlus

  • 手动添加MyBatisPlus起步依赖

    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.4.1</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.16</version>
    </dependency>
  • 制作实体类与表结构(类名与表名对应,属性名与字段名对应)

    create database if not exists mybatisplus_db character set utf8;
    use mybatisplus_db;
    CREATE TABLE user (
                id bigint(20) primary key auto_increment,
                name varchar(32) not null,
                password  varchar(32) not null,
                age int(3) not null ,
                tel varchar(32) not null
    );
    insert into user values(null,'tom','123456',12,'12345678910');
    insert into user values(null,'jack','123456',8,'12345678910');
    insert into user values(null,'jerry','123456',15,'12345678910');
    insert into user values(null,'tom','123456',9,'12345678910');
    insert into user values(null,'snake','123456',28,'12345678910');
    insert into user values(null,'张益达','123456',22,'12345678910');
    insert into user values(null,'张大炮','123456',16,'12345678910');
    @Data
    public class User {
        private Long id;
        private String name;
        private String password;
        private Integer age;
        private String tel;
    }
  • 设置Jdbc参数

    spring:
      datasource:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/mybatisplus_db?serverTimezone=UTC
        username: root
        password: root
  • 定义数据接口,继承BaseMapper

    @Mapper
    public interface UserDao extends BaseMapper<User> {
    }
  • 测试类中注入dao接口,测试功能

    @SpringBootTest
    public class Mybatisplus01QuickstartApplicationTests {
    
        @Autowired
        private UserDao userDao;
    
        @Test
        void testGetAll() {
            List<User> userList = userDao.selectList(null);
            System.out.println(userList);
        }
    }

标准数据层开发

CRUD操作

@SpringBootTest
class Mybatisplus01QuickstartApplicationTests {

    @Autowired
    private UserDao userDao;

    @Test
    void testSave() {
        User user = new User();
        user.setName("程序员");
        user.setPassword("lixuan");
        user.setAge(12);
        user.setTel("4006184000");
        userDao.insert(user);
    }

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

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

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


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

分页功能

  • 设置分页拦截器作为Spring管理的bean

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

    //分页查询
    @Test
    void testSelectPage(){
        //1 创建IPage分页对象,设置分页参数
        IPage<User> page=new Page<>(1,3);
        //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());
    }
  • 开启MyBatisPlus日志

    # 开启mp的日志(输出到控制台)
    mybatis-plus:
      configuration:
        log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

DQL编程控制

条件查询

  • 按条件查询

    QueryWrapper<User> qw=new QueryWrapper<>();
    qw.lt("age", 18);
    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);

组合条件

  • 并且关系(and)

    //并且关系
    LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
    //并且关系:10到30岁之间
    lqw.lt(User::getAge, 30).gt(User::getAge, 10);
    List<User> userList = userDao.selectList(lqw);
    System.out.println(userList);
  • 或者关系(or)

    //或者关系
    LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
    //或者关系:小于10岁或者大于30岁
    lqw.lt(User::getAge, 10).or().gt(User::getAge, 30);
    List<User> userList = userDao.selectList(lqw);
    System.out.println(userList);

NULL值处理

  • if语句控制条件追加

    Integer minAge=10;  //将来有用户传递进来,此处简化成直接定义变量了
    Integer maxAge=null;  //将来有用户传递进来,此处简化成直接定义变量了
    LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
    if(minAge!=null){
        lqw.gt(User::getAge, minAge);
    }
    if(maxAge!=null){
        lqw.lt(User::getAge, maxAge);
    }
    List<User> userList = userDao.selectList(lqw);
    userList.forEach(System.out::println);
  • 条件参数控制(链式编程)

    Integer minAge=10;  //将来有用户传递进来,此处简化成直接定义变量了
    Integer maxAge=null;  //将来有用户传递进来,此处简化成直接定义变量了
    LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
    //参数1:如果表达式为true,那么查询才使用该条件
    lqw.gt(minAge!=null,User::getAge, minAge)
       .lt(maxAge!=null,User::getAge, maxAge);
    List<User> userList = userDao.selectList(lqw);
    userList.forEach(System.out::println);

查询字段、分组、分页

  • 查询结果包含模型类中部分属性

    /*LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
    lqw.select(User::getId, User::getName, User::getAge);*/
    //或者
    QueryWrapper<User> lqw = new QueryWrapper<User>();
    lqw.select("id", "name", "age", "tel");
    List<User> userList = userDao.selectList(lqw);
    System.out.println(userList);
  • 查询结果包含模型类中未定义的属性

    QueryWrapper<User> lqw = new QueryWrapper<User>();
    lqw.select("count(*) as count, tel");
    lqw.groupBy("tel");
    List<Map<String, Object>> userList = userDao.selectMaps(lqw);
    System.out.println(userList);

查询条件

  • 用户登录(eq匹配)

    LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
    //等同于=
    lqw.eq(User::getName, "Jerry").eq(User::getPassword, "jerry");
    User loginUser = userDao.selectOne(lqw);
    System.out.println(loginUser);
  • 购物设定价格区间、户籍设定年龄区间(le ge匹配 或 between匹配)

    LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
    //范围查询 lt le gt ge eq between
    lqw.between(User::getAge, 10, 30);
    List<User> userList = userDao.selectList(lqw);
    System.out.println(userList);
  • 查信息,搜索新闻(非全文检索版:like匹配)

    LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>();
    //模糊匹配 like
    lqw.likeLeft(User::getName, "J");
    List<User> userList = userDao.selectList(lqw);
    System.out.println(userList);
  • 统计报表(分组查询聚合函数)

    QueryWrapper<User> qw = new QueryWrapper<User>();
    qw.select("gender","count(*) as nums");
    qw.groupBy("gender");
    List<Map<String, Object>> maps = userDao.selectMaps(qw);
    System.out.println(maps);

字段映射与表名映射

@Data
@TableName("tbl_user")
public class User {
    /*
        id为Long类型,因为数据库中id为bigint类型,
        并且mybatis有自己的一套id生成方案,生成出来的id必须是Long类型
     */
    private Long id;
    private String name;
    @TableField(value = "pwd",select = false)
    private String password;
    private Integer age;
    private String tel;
    @TableField(exist = false) //表示online字段不参与CRUD操作
    private Boolean online;
}

DML编程控制

id生成策略控制(Insert)

  • @TableId注解

    @TableId(type = IdType.AUTO)
    private Long id;
  • 全局策略配置

    mybatis-plus:
      global-config:
        db-config:
          id-type: assign_id
          table-prefix: tbl_

多记录操作(批量Delete/Select)

  • 按照主键删除多条记录

    //删除指定多条数据
    List<Long> list = new ArrayList<>();
    list.add(1402551342481838081L);
    list.add(1402553134049501186L);
    list.add(1402553619611430913L);
    
    userDao.deleteBatchIds(list);
  • 根据主键查询多条记录

    //查询指定多条数据
    List<Long> list = new ArrayList<>();
    list.add(1L);
    list.add(3L);
    list.add(4L);
    
    List<User> users = userDao.selectBatchIds(list);
    users.forEach(System.out::println);
  • 逻辑删除(Delete/Update)

    • 数据库表中添加逻辑删除标记字段deleted

    • 实体类中添加对应字段,并设定当前字段为逻辑删除标记字段

      @Data
      public class User {    
          //逻辑删除字段,标记当前记录是否被删除
          @TableLogic
          private Integer deleted;   
      }
    • 配置逻辑删除字面值

      mybatis-plus:
        global-config:
          db-config:
            table-prefix: tbl_
            # 逻辑删除字段名
            logic-delete-field: deleted
            # 逻辑删除字面值:未删除为0
            logic-not-delete-value: 0
            # 逻辑删除字面值:删除为1
            logic-delete-value: 1

乐观锁(Update)

  • 实体类中添加对应字段

    @Data
    public class User {
        @Version
        private Integer version;
    }
  • 配置乐观锁拦截器实现锁机制对应的动态SQL语句拼装

    @Configuration
    public class MpConfig {
        @Bean
        public MybatisPlusInterceptor mpInterceptor() {
            //1.定义Mp拦截器
            MybatisPlusInterceptor mpInterceptor = new MybatisPlusInterceptor();
    
            //2.添加乐观锁拦截器
            mpInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
    
            return mpInterceptor;
        }
    }
  • 使用乐观锁机制在修改前必须先获取到对应数据的verion方可正常进行

    User user = userDao.selectById(3L);     //version=3
        User user2 = userDao.selectById(3L);    //version=3
        user2.setName("Jock aaa");
        userDao.updateById(user2);              //version=>4
        user.setName("Jock bbb");
        userDao.updateById(user);               //verion!=3

代码生成器

  • 添加代码生成器相关依赖,其他依赖自行添加

    <!--代码生成器-->
    <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>
  • 编写代码生成器类

    public class Generator {
        public static void main(String[] args) {
            //1. 创建代码生成器对象,执行生成代码操作
            AutoGenerator autoGenerator = new AutoGenerator();
    
            //2. 数据源相关配置:读取数据库中的信息,根据数据库表结构生成代码
            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("root");
            autoGenerator.setDataSource(dataSource);
    
             //3. 执行生成操作
            autoGenerator.execute();
        }
    }
    

开发者自定义配置

  • 设置全局配置

    //设置全局配置
    GlobalConfig globalConfig = new GlobalConfig();
    globalConfig.setOutputDir(System.getProperty("user.dir")+"/MyBatisPlus_02/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("cn.lixuan");   //设置生成的包名,与代码所在位置不冲突,二者叠加组成完整路径
    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);
评论区
推荐文章

暂无数据

lix_uan
lix_uan
Lv1
学无止境,即刻前行
7
文章
3
粉丝
0
获赞