MyBatis-Plus 学习之路

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

目录

一、环境准备

1.1 idea创建springboot项目

1.2 添加依赖

1.3 资源配置

1.4 实体类创建

1.5 dao接口

二、标准CRUD使用

2.1 基础增删改查的使用

2.2 分页制作

添加拦截器

测试

三、DQL编程控制

3.1 条件查询

3.1.1 多条件构建

3.1.2 null判定

3.2 查询投影

3.2.1 查询指定字段

 3.2.2 聚合查询

3.2.3 分组查询

3.3 条件查询 

3.3.1 等值查询

3.3.2 范围查询

3.3.3 模糊查询

3.3.4 排序查询

 3.4 映射匹配兼容性

 四、DML编程控制

4.1 id生成策略控制

4.2  多记录操作

4.3 逻辑删除

4.4 乐观锁

五、代码生成器

以上就是本次学习的总结!


一、环境准备

1.1 idea创建springboot项目

碰到了一个小问题,通过idea创建springboot时,连接超时

解决办法:使用https://start.aliyun.com  阿里云的脚手架即可

1.2 添加依赖

pom.xml 

        <!--mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!--mybatis-plus-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.1</version>
        </dependency>
        <!--Druid数据源-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.19</version>
        </dependency>
        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

1.3 资源配置

application.yml

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: 123456

1.4 实体类创建

@Data
public class User {
    private Long id;
    private String name;
    private String password;
    private Integer age;
    private String tel;
}

1.5 dao接口

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

到这里环境准备完毕

二、标准CRUD使用

2.1 基础增删改查的使用


@SpringBootTest
class MybatisplusStudyApplicationTests {

    @Autowired
    private UserDao userDao;

    /**
     * 查询所有
     */
    @Test
    void getAll() {
        List<User> users = userDao.selectList(null);
        System.out.println(users);
    }
    /**
     * 根据id查询
     */
    @Test
    void getById(){
        User user = userDao.selectById(1);
        System.out.println(user);
    }
    /**
     * 添加
     */
    @Test
    void add(){
        User user = new User();
        user.setName("pyh");
        user.setAge(18);
        user.setPassword("1234");
        user.setTel("12138");
        userDao.insert(user);
    }

    /**
     * 根据id删除
     */
    @Test
    void deleteById(){
        userDao.deleteById(1459813676565766146L);
    }

    /**
     * 修改
     */
    @Test
    void update(){
        User user = new User();
        user.setId(1L);
        user.setName("cat666");
        userDao.updateById(user);
    }

}

2.2 分页制作

添加拦截器

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

测试

    /**
     * 分页
     */
    @Test
    void getPage(){
        IPage<User> page = new Page<>(2,3);
        userDao.selectPage(page,null);
        long pages = page.getPages();
        List<User> records = page.getRecords();
        long size = page.getSize();
        long current = page.getCurrent();
        long total = page.getTotal();
        System.out.println("当前页: "+current);
        System.out.println("每页显示几条数据: "+size);
        System.out.println("一共有多少数据: "+total);
        System.out.println("一共多少页: "+pages);
        System.out.println("当前页的数据: "+records);
    }

三、DQL编程控制

3.1 条件查询

3.1.1 多条件构建

查询数据库表中,年龄在10岁到30岁之间的用户信息

User::getAget,为lambda表达式中的,类名::方法名

    @Test
    void getAge(){
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
        //查询数据库表中,年龄在10岁到30岁之间的用户信息
        lqw.gt(User::getAge,10).lt(User::getAge,30);
        List<User> users = userDao.selectList(lqw);
        System.out.println(users);
    }

查询数据库表中,年龄小于10或年龄大于30的数据

    @Test
    void getAge1(){
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
        //查询数据库表中,年龄小于10或年龄大于30的数据
        lqw.lt(User::getAge,10).or().gt(User::getAge,30);
        List<User> users = userDao.selectList(lqw);
        System.out.println(users);
    }

3.1.2 null判定

查询数据库表中,根据输入年龄范围来查询符合条件的记录

用户在输入值的时候,

如果只输入第一个框,说明要查询大于该年龄的用户

如果只输入第二个框,说明要查询小于该年龄的用户

如果两个框都输入了,说明要查询年龄在两个范围之间的用

    @Test
    void getNull(){
        Integer age1 = 10;
        Integer age2 = null;
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
        //如果 XXX 不为null 则执行
        lqw.gt(null!=age1,User::getAge,age1);
        lqw.lt(null!=age2,User::getAge,age2);
        List<User> users = userDao.selectList(lqw);
        System.out.println(users);
    }

3.2 查询投影

3.2.1 查询指定字段

查询name和age

    @Test
    void querySpecifiedField(){
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
        //通过select来设置查询指定字段名
        lqw.select(User::getName,User::getAge);
        List<User> users = userDao.selectList(lqw);
        System.out.println(users);
    }

 3.2.2 聚合查询

需求:聚合函数查询,完成count、max、min、avg、sum的使用

count:总记录数

max:最大值

min:最小值

avg:平均值

sum:求和

    @Test
    void aggregateQuery(){
        //聚合函数不能使用Lambda表达式
        QueryWrapper<User> qw = new QueryWrapper<>();
        //总数
//        qw.select("count(*) as count");
        //最大年龄
//        qw.select("max(age) as maxAge");
        //最小年龄
        qw.select("min(age) as minAge");
        //平均年龄
        qw.select("avg(age) as avgAge");
        //求和
        qw.select("sum(age) as sumAge");
        List<Map<String, Object>> maps = userDao.selectMaps(qw);
        System.out.println(maps);
    }

3.2.3 分组查询

    @Test
    void getGroup(){
        QueryWrapper<User> qw = new QueryWrapper<>();
        //根据电话号码分组
        qw.select("count(*) as count,tel");
        qw.groupBy("tel");
        List<Map<String, Object>> maps = userDao.selectMaps(qw);
        System.out.println(maps);
    }

值得注意的点就是

1.当使用聚合函数和分组查询时不能使用Lambda表达式

2.当涉及到复杂的查询时,MP实现不了可以使用Mybatis的方式进行实现

3.3 条件查询 

除开以上的条件查询,MP还封装了大量的查询条件方法

3.3.1 等值查询

根据用户名和密码查询用户信息

    @Test
    void getUser(){
//        根据用户名和密码查询用户信息
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
        lqw.eq(User::getName,"dog").eq(User::getPassword,123456);
        User user = userDao.selectOne(lqw);
        System.out.println(user);
    }

3.3.2 范围查询

    @Test
    void rangeQuery(){
//        对年龄进行范围查询,使用lt()、le()、gt()、ge()、between()进行范围查询
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
        //lt是小于 le是小于等于
//        lqw.lt(User::getAge,9);
//        lqw.le(User::getAge,9);

        //gt()是大于 ge()是大于等于
//        lqw.gt(User::getAge,9);
//        lqw.ge(User::getAge,9);

        //between()两者之间
        lqw.between(User::getAge,9,30);
        List<User> users = userDao.selectList(lqw);
        System.out.println(users);
    }

3.3.3 模糊查询

    @Test
    void fuzzyQuery(){
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
        //两边都加%号
//        lqw.like(User::getName,"j");
        //左边加%号
//        lqw.likeLeft(User::getName,"j");
        //右边加%号
        lqw.likeRight(User::getName,"j");
        List<User> users = userDao.selectList(lqw);
        System.out.println(users);
    }

3.3.4 排序查询

    @Test
    void sortQuery(){
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
        /**
         * condition :条件,返回boolean,
         当condition为true,进行排序,如果为false,则不排序
         * isAsc:是否为升序,true为升序,false为降序
         * columns:需要操作的列
         */
        lqw.orderBy(true,false,User::getAge);
        List<User> users = userDao.selectList(lqw);
        System.out.println(users);
    }

 运行效果

 3.4 映射匹配兼容性

问题1:当表的字段名和实体类的属性名不一致应该怎么办

 

 MybatisPlus 就给我们提供了一个@TableField注解 解决这个问题  value="pwd"

@Data
public class User {
    private Long id;
    private String name;
    @TableField(value = "pwd")
    private String password;
    private Integer age;
    private String tel;
}

问题2:编码中添加了数据库中未定义的属性

我们可以使用@TableField(exist = false) 来解决这个问题

@Data
public class User {
    private Long id;
    private String name;
    @TableField(value = "pwd")
    private String password;
    private Integer age;
    private String tel;

    @TableField(exist = false)
    private Integer sex;
}

问题3:当我们查询一些一些表中数据时,有些字段是不想被查询到的

我们可以使用select属性来设置

@Data
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 sex;
}

 总结:

@TableField注解

value:设置数据库表字段名称

exist:设置属性在数据库表字段中是否存在,默认为true,此属性不能与value合并使用

select:设置属性是否参与查询,此属性与select()映射配置不冲突

 问题4:当表名与实体类名不一样时怎么办?

MP给我们提供了@TableName注解去解决这个问题

@Data
@TableName("tb_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 sex;
}

 四、DML编程控制

4.1 id生成策略控制

@TableId(type = IdType.AUTO)//使用数据库ID自增
  • NONE: 不设置id生成策略

  • INPUT:用户手工输入id

  • ASSIGN_ID:雪花算法生成id(可兼容数值型与字符串型)

  • ASSIGN_UUID:以UUID生成算法作为id生成策略

4.2  多记录操作

根据id批量删除

    @Test
    void testDelete(){
        List<Long> list = new ArrayList<>();
        list.add(5l);
        list.add(6L);
        list.add(7L);
        userDao.deleteBatchIds(list);
    }

根据id批量查询

    @Test
    void testSelect(){
        List<Long> list = new ArrayList<>();
        list.add(1L);
        list.add(2L);
        list.add(3L);
        List<User> users = userDao.selectBatchIds(list);
        System.out.println(users);
    }

4.3 逻辑删除

问题:当我们需要对某一条数据进行删除,但又不希望该数据走物理上真正的删除,该数据仍然在数据库中进行保留,但查询时却没有该数据

例子:涉及到离职员工的业绩报表

 1.我们给数据库添加一列名为 deleted

2.给实体类添加字段名  并添加@TableLogic注解

@Data
@TableName("tb_user")
public class User {
    @TableId(type = IdType.AUTO)
    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 sex;

    @TableLogic(value = "0",delval = "1")//value是正常数据的值 delval是删除数据的值
    private Integer deleted;
}

3.运行删除方法

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

结果:tom的deleted值已经变为1 且该删除方法实际已经变为update方法

执行的sql如下

 我们再执行查询方法看是否还能查询出id=1 的数据

通过日志看到已经没有id为1的数据 且SQL语句增加了一个where deleted=1的条件

4.4 乐观锁

1.给表添加一列 version

 2.实体类中添加对应的属性

@Data
@TableName("tb_user")
public class User {
    @TableId(type = IdType.AUTO)
    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 sex;

    @TableLogic(value = "0",delval = "1")//value是正常数据的值 delval是删除数据的值
    private Integer deleted;

    @Version
    private Integer version;
}

3.添加拦截器

@Configuration
public class MybatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor mpi(){
        //1 创建MybatisPlusInterceptor拦截器对象
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        //2 添加分页拦截器
        mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        //3 添加乐观锁拦截器
        mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return mybatisPlusInterceptor;
    }
}

4.执行update方法

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

5.结果

通过sql语句可以看出

 拿到表中的version,然后拿version当条件在将version加1更新回到数据库表中,这样就避免了冲突

五、代码生成器

1.导入依赖

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.pyh</groupId>
    <artifactId>mybatisplus_generator</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>mybatisplus_generator</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.3.7.RELEASE</spring-boot.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.4.2</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--代码生成器-->
        <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>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.19</version>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.3.7.RELEASE</version>
                <configuration>
                    <mainClass>com.pyh.MybatisplusGeneratorApplication</mainClass>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

 2.创建代码生成类

package com.pyh;

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")+"/mybatisplus_generator/src/main/java");    //设置代码生成位置
        globalConfig.setOpen(false);    //设置生成完毕后是否打开生成代码所在的目录
        globalConfig.setAuthor("PYH");    //设置作者
        globalConfig.setFileOverride(true);     //设置是否覆盖原始生成的文件
        globalConfig.setMapperName("%sDao");    //设置数据层接口名,%s为占位符,指代模块名称
        globalConfig.setIdType(IdType.ASSIGN_ID);   //设置Id生成策略
        autoGenerator.setGlobalConfig(globalConfig);

        //设置包名相关配置
        PackageConfig packageInfo = new PackageConfig();
        packageInfo.setParent("com.pyh");   //设置生成的包名,与代码所在位置不冲突,二者叠加组成完整路径
        packageInfo.setEntity("domain");    //设置实体类包名
        packageInfo.setMapper("dao");   //设置数据层包名
        autoGenerator.setPackageInfo(packageInfo);

        //策略设置
        StrategyConfig strategyConfig = new StrategyConfig();
        strategyConfig.setInclude("tb_user");  //设置当前参与生成的表名,参数为可变参数
        strategyConfig.setTablePrefix("tb_");  //设置数据库表的前缀名称,模块名 = 数据库表名 - 前缀名  例如: 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.运行后效果图

 该代码也可走官网获取

代码生成器(历史版本) | MyBatis-Plus

以上就是本次学习的总结!

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>