• 一篇文章带你搞懂MybatisPlus


    mybatis-plus

    配置

     
            <dependency>
                <groupId>com.baomidougroupId>
                <artifactId>mybatis-plus-boot-starterartifactId>
                <version>3.2.0version>
            dependency>
            
            <dependency>
                <groupId>com.baomidougroupId>
                <artifactId>mybatis-plus-generatorartifactId>
                <version>3.5.1version>
            dependency>
            
            <dependency>
                <groupId>org.freemarkergroupId>
                <artifactId>freemarkerartifactId>
                <version>2.3.31version>
            dependency>
            
            <dependency>
                <groupId>mysqlgroupId>
                <artifactId>mysql-connector-javaartifactId>
                <version>5.1.46version>
            dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    server:
      port: 8080
    spring:
      datasource:
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://localhost:3306/java100?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false
        username: root
        password: 123456
    mybatis-plus:
      configuration:
        # mybatis-plus 日志打印
        log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
        # 设置mybatis-Plus的全局配置
      global-config:
        db-config:
          # 设置统一的主键生成策略
          id-type:
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    实体注解

    @TableName("t_user")
    //当表名和实体类类型不一致时,在实体类类型上添加@TableName("t_user"),标识实体类对应的表
    
    @TableId(value = "uid",type = IdType.AUTO)
    //Mybatis-plus底层只认为id是主键,会为其使用雪花算法生成值,uid,tid这些都不会。
    //该注解可将属性对应的字段指定为主键,同时若属性名和字段名不对应,则使用注解的value属性指定主键的字段名
    //type属性用于设置主键生成策略,常用的有两种IdType.ASSIGN_ID(默认)、IdType.AUTO
    //IdType.ASSIGN_ID(默认):基于雪花算法的策略生成数据id,与数据库id是否设置自增无关
    //IdType.AUTO:使用数据库的自增策略,注意,该类型请确保数据库设置了id自增,否则无效
    //也可以在yml配置文件中设置统一的主键生成策略
    
    @TableField("user_name")
    //设置属性对应的字段名
    
    @TableLogic
    //设置该字段表示逻辑删除,此时使用delete进行删除数据则不会真的删除数据库的数据,只会改变所要删除数据的该字段的值
    //使用这个后,当前的逻辑删除会自动转换为修改操作,当前的查询功能会自动转换为查询未被逻辑删除的数据
    
    @Version //标识乐观锁版本号字段
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    Mybatis-plus底层只认为id是主键,会为其使用雪花算法生成值,uid,tid这些都不会。因此我们需要指定id的名字。

    常用yml

    server:
      port: 1314
    spring:
      datasource:
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://localhost:3306/java100?characterEncoding=utf-8&&userSSL=true
        username: root
        password: 123456
    mybatis-plus:
      configuration:
        # mybatis-plus 日志打印
        log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
      # 设置mybatis-Plus的全局配置
      global-config:
        db-config:
          # 设置实体类表的统一前缀
          table-prefix: t_
          # 设置统一的主键生成策略
          id-type: auto
      # 配置类型别名所对应的包名
      type-aliases-package: com.example.mybatispx.pojo
      # 扫描通枚举类的包
      type-enums-package: com.example.mybatispx.enums
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    wapper条件构造器

    查询

    		@Test
        public void test01(){
            //查询用户名包含a,年龄在20到30之间,邮箱信息不为null的用户信息
            QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
            //注意:column参数应该填字段名,而不是属性名
            queryWrapper.like("user_name","a")	//模糊查询
                        .between("age",20,30)		//范围查询
                        .isNotNull("email");
            List<User> list = userMapper.selectList(queryWrapper);
            list.forEach(System.out::println);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    排序

    		@Test
        public void test02(){
            //查询用户信息,按照年龄的降序排序,若年龄相同,则按照id升序排序
            QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
            queryWrapper.orderByDesc("age")     //降序
                        .orderByAsc("uid");     //升序
            List<User> list = userMapper.selectList(queryWrapper);
            list.forEach(System.out::println);
    
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    删除

    		@Test
        public void test03(){
            //删除邮箱地址为null的用户信息
            QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
            queryWrapper.isNull("email");
            int result = userMapper.delete(queryWrapper);
            System.out.println("result:"+result);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    修改

    queryWrapper
     @Test
        public void test04(){
            //将(年龄大于20并且用户名中包含有a)或邮箱为null的用户信息修改
            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
            //连续使用"."默认为AND连接,但本次条件中有或者,因此使用or()转换
            queryWrapper.gt("age",20)   //大于
                        .like("user_name","a")
                        .or()
                        .isNull("email");
            User user = new User();
            user.setName("xiao");
            user.setEmail("test@atguigu.com");
            int result = userMapper.update(user, queryWrapper);
            System.out.println("result:"+result);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

        @Test
        public void test05(){
            //将用户名包含有a并且(年龄大于20或邮箱为null)的用户信息修改
            //lambda中的条件优先执行
            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
            queryWrapper.like("user_name","a")
                        .and(i->i.gt("age",20).or().isNull("email"));
            User user = new User();
            user.setName("xiao");
            user.setEmail("test05@atguigu.com");
            int result = userMapper.update(user, queryWrapper);
            System.out.println("result:"+result);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    UpdateWrapper
    		@Test
        public void test08(){
            //将企业名中包含有a并且(年龄大于20或者邮箱不为null)的用户信息修改
            UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
            updateWrapper.like("user_name","a")
                         .and(i->i.gt("age",20).or().isNotNull("email"));
            updateWrapper.set("user_name","xiaohei").set("email","abc@atguigu.com");
            int result = userMapper.update(null, updateWrapper);
            System.out.println("result:"+result);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    查询部分字段

        @Test
        public void test06(){
            //查询所有用户的用户名、年龄、邮箱信息
            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
            queryWrapper.select("user_name","age","email");
            List<Map<String, Object>> maps = userMapper.selectMaps(queryWrapper);
            maps.forEach(System.out::println);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    子查询

        @Test
        public void test07(){
            //查询id小于等于4的用户信息,这样查询只是示范下子查询,这种操作可以进行跨表查询
            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
            queryWrapper.inSql("uid","select uid from user where uid <= 4");
            List<User> list = userMapper.selectList(queryWrapper);
            list.forEach(System.out::println);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    注意

    gt 大于

    lt 小于

    ge 大于等于

    le 小于等于

    组装条件

    test09、test10和test11实现一样的效果

    		@Test
        public void test09(){
            String username = "";
            Integer ageBegin = 20;
            Integer ageEnd = 30;
            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
            if(StringUtils.isNotBlank(username));{   //判断某个字符串是否不为空字符串,不为null,不为空白符
                queryWrapper.like("user_name",username);
            }
            if (ageBegin != null){
                queryWrapper.ge("age",ageBegin);
            }
            if (ageEnd != null){
                queryWrapper.le("age",ageEnd);
            }
            List<User> list = userMapper.selectList(queryWrapper);
            list.forEach(System.out::println);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
        @Test
        public void test10(){
            String username = "";
            Integer ageBegin = 20;
            Integer ageEnd = 30;
            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
            queryWrapper.like(StringUtils.isNotBlank(username),"user_name",username)
                        .ge(ageBegin != null,"age",ageBegin)
                        .le(ageEnd != null,"age",ageEnd);
            List<User> list = userMapper.selectList(queryWrapper);
            list.forEach(System.out::println);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    LambdaQueryWrapper
        @Test
        public void test11(){
            String username = "";
            Integer ageBegin = 20;
            Integer ageEnd = 30;
            LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.like(StringUtils.isNotBlank(username), User::getName, username)	//防止字段名写错
                        .ge(ageBegin != null, User::getAge, ageBegin)
                        .le(ageEnd != null, User::getAge, ageEnd);
            List<User> list = userMapper.selectList(queryWrapper);
            list.forEach(System.out::println);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    LambdaUpdateWrapper
    
        @Test
        public void test12(){
            //将企业名中包含有a并且(年龄大于20或者邮箱为null)的用户信息修改
            LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.like(User::getName,"a")
                    .and(i->i.gt(User::getAge,20).or().isNotNull(User::getEmail));
            updateWrapper.set(User::getName, "xiaohei").set(User::getEmail, "abc@atguigu.com");
            int result = userMapper.update(null, updateWrapper);
            System.out.println("result:"+result);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    wapper总结
    QueryWrapper和UpdateWrapper的区别
    • QueryWrapper在修改数据时需要通过具体的实体对象设置修改的内容
    • UpdateWrapper在修改数据时可以直接使用.set()来设置修改的字段和内容

    QueryWrapper、UpdateWrapper和LambdaQueryWrapper、LambdaUpdateWrapper的区别
    • QueryWrapper、UpdateWrapper的条件使用的是数据库字段名,LambdaQueryWrapper、LambdaUpdateWrapper使用的是get方法
    • LambdaQueryWrapper、LambdaUpdateWrapper中可以放判断条件

    分页

    分页插件

    配置类

    @Configuration
    //用于扫描mapper接口所在的包
    @MapperScan("com.bai.mybatisplus.mapper")
    public class MyBatisPlusConfig {
        @Bean
        public MybatisPlusInterceptor mybatisPlusInterceptor(){
            MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
          	//添加分页插件
            interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
            return interceptor;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    分页读数据

    		@Test
        public void testPage(){
            //设置分页参数
            Page<User> page = new Page<>(1,3);  //current:当前页   size:每页显示条数
            userMapper.selectPage(page, null);
            System.out.println(page);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    		@Test
        public void testPage(){
            //设置分页参数
            Page<User> page = new Page<>(3,3);  //current:当前页   size:每页显示条数
            userMapper.selectPage(page, null);
            System.out.println(page);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    从运行的日志中可以看出,mybatis-plus的分页查询会先查出总条数,然后根据分页参数计算出当前页从第几个索引开始查。

    自定义分页功能

    UserMapper.java

    @Repository
    public interface UserMapper extends BaseMapper<User> {
        /**
         * 通过年龄查询用户信息并分页
         * @param page MyBatis-Plus多提供的分页对象,必须位于第一个参数位置
         * @param age
         * @return
         */
        Page<User> selectPageVo(@Param("page") Page<User> page, @Param("age") Integer age);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    UserMapper.xml

    		<select id="selectPageVo" resultType="User">
            select uid,user_name,age,email from user where age > #{age}
        select>
    
    • 1
    • 2
    • 3

    Application.yml (注意resultType的User进行了配置,所以不用写前缀)

    mybatis-plus:
      #配置类型别名所对应的包
      type-aliases-package: com.bai.mybatisplus.pojo
    
    • 1
    • 2
    • 3

    Test

     		@Test
        public void testPageVo(){
            Page<User> page = new Page<>(2,3);
            userMapper.selectPageVo(page,20);
            System.out.println(page.getRecords());
            System.out.println(page.getPages());    //总页数
            System.out.println(page.hasNext());
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    枚举

    枚举类举例

    @Getter
    public enum SexEnum{
        MALE(1,"男"),
        FEMALE(2, "女");
    
        @EnumValue  //  将注解所标识的属性的值存储懂数据库中
        private Integer sex;
        private String sexName;
    
        SexEnum(Integer sex, String sexName) {
            this.sex = sex;
            this.sexName = sexName;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    配置

    mybatis-plus:
      #扫描通用枚举的包
      type-enums-package: com.bai.mybatisplus.enums
    
    • 1
    • 2
    • 3

    代码生成器

    配置

            <dependency>
                <groupId>com.baomidougroupId>
                <artifactId>mybatis-plus-generatorartifactId>
                <version>3.5.1version>
            dependency>
            <dependency>
                <groupId>org.freemarkergroupId>
                <artifactId>freemarkerartifactId>
                <version>2.3.31version>
            dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    执行代码

    public class FastAutoGeneratorTest {
        public static void main(String[] args) {
            FastAutoGenerator.create("jdbc:mysql://127.0.0.1:3306/mybatis_plus? characterEncoding=utf-8&userSSL=false", "root", "123456")
                            .globalConfig(builder -> {
                                builder.author("atguigu") // 设置作者
                                        //.enableSwagger() // 开启 swagger 模式
                                        .fileOverride() // 覆盖已生成文件
                                        .outputDir("/Users/mac/workspace/mybatis_plus"); // 指定输出目录
                            })
                            .packageConfig(builder -> {
                                builder.parent("com.bai") // 设置父包名
                                        .moduleName("mybatisplus") // 设置父包模块名
                                        .pathInfo(Collections.singletonMap(OutputFile.mapperXml, "D://mybatis_plus"));// 设置mapperXml生成路径
                            })
                            .strategyConfig(builder -> {
                                builder.addInclude("user") // 设置需要生成的表名
                                        .addTablePrefix("t_", "c_"); // 设置过滤表前缀
                            })
                            .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker 引擎模板,默认的是Velocity引擎模板
                            .execute();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    mybatisX

    配置

     
            <dependency>
                <groupId>com.baomidougroupId>
                <artifactId>mybatis-plus-coreartifactId>
                <version>3.1.1version>
            dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    下载插件

    ⚠️

    该插件依靠表生成代码,因此先要连接数据库(傻瓜下一步,遇到下载就点下载)

    Name:连接名称

    Host:连接地址

    User/Password:账户密码

    Database:你想要操作的数据库

    Test Connection:测试连接

    生成代码

    找到你想要生成代码的表,单机右键,选择MybatisX-Generate

    module path:模块路径

    base path:当前路径(src/main/java)

    base package:生成的文件夹路径 (com.nickbears.demo.dto)

    relative package:实体文件夹(pojo)

    后面的就是文件或者表格忽略前缀后缀

  • 相关阅读:
    IO多路复用Selector
    QT 智能指针注意事项(备忘)
    WebSocket实现聊天功能
    java毕业设计在线课程教学大纲系统Mybatis+系统+数据库+调试部署
    PDF转换器用什么好?这款一定能够帮到你
    解决六大痛点促进企业更好使用生成式AI,亚马逊云科技顾凡采访分享可用方案
    vue element编辑功能
    【电商运营】社交媒体营销策略该如何制定?
    CPT-CY3/CY5/CY7/CY7.5/花菁染料CY3/Y5/CY7/CY7.5/抗Trop-2 IgG抗体偶联顺铂的制备
    网易有道财报:网易有道2023财年收入将强劲增长,亏损将减少?
  • 原文地址:https://blog.csdn.net/weixin_50369395/article/details/126723353