最近突然想学一下mybatis-plus希望尽快提上日程吧。
好了,提上日程,冲冲冲

快速开始

这里贴一个官网连接 mybatis-plus
照着他们一步步来就可以了,有些省事,但确实写的非常详细。

BaseMapper 中的 insert方法的默认 策略

在 mp(mybatis-plus) 中,你使用 insert方法的时候,是会自动将id 回填到的对象中的,但是默认情况生成的是这种一连串的 数字

mp-insert.jpeg

这种生成方式,采用的是 Twitter的雪花算法,具体了解可百度,保证了分布式的情况下id也唯一。

如果你想使用 主键自增的方式,你需要将数据库表中的 主键自增打开,然后在 id 属性上加 @TableId(type = IdType.AUTO)

  1. @Data
  2. public class User {
  3. //主键自增
  4. @TableId(type = IdType.AUTO)
  5. private Long id;
  6. private String name;
  7. private Integer age;
  8. private String email;
  9. }

虽然分布式下采用默认的生成策略较好,但是毕竟身为大三狗,我写的也都是小项目。所以就先用自增吧。

@TableId 具体属性自行查看哦

update 方法

mp的 update 是 执行的是动态sql, 也就是条件修改

  1. @Test
  2. void testUpdate() {
  3. User user = new User();
  4. user.setId(1238647983271899149L);
  5. user.setName("hello");
  6. user.setAge(20);
  7. userMapper.updateById(user);
  8. }

你对象里没有的字段,是不会进行修改的
mp-update.png

关于 create_time 和 update_time 的问题

在阿里开发手册中写了,数据表必须要有这两个字段。
所以不免会想到,这两个字段能不能自动生成或更新,不通过每次创建时间。

一般有两种策略
之前我用的就是这种

  • 数据库自动生成

  • mp-datetime.png
    对这两个字段设置默认值为 CURRENT_TIMESTAMP ,update需要在 根据时间戳更新那里打上勾
  • mp 生成自动填充
  1. //插入的时候自动填充
  2. @TableField(fill = FieldFill.INSERT)
  3. private LocalDateTime createTime;
  4. //插入和更新的时候自动填充
  5. @TableField(fill = FieldFill.INSERT_UPDATE)
  6. private LocalDateTime updateTime;
  1. //自动填充 增强类 这里的cretaeTime是实体类属性而不是数据库字段名
  2. @Slf4j
  3. @Component
  4. public class MyMetaObjectHandler implements MetaObjectHandler {
  5. //插入填充
  6. @Override
  7. public void insertFill(MetaObject metaObject) {
  8. //自动填充时间
  9. log.info("insertFill running");
  10. //三个参数分别是 字段名,填充值,元数据
  11. this.setFieldValByName("createTime", LocalDateTime.now(),metaObject);
  12. this.setFieldValByName("updateTime", LocalDateTime.now(),metaObject);
  13. }
  14. //更新填充
  15. @Override
  16. public void updateFill(MetaObject metaObject) {
  17. //自动填充时间
  18. log.info("updateFill running");
  19. //三个参数分别是 字段名,填充值,元数据
  20. this.setFieldValByName("updateTime", LocalDateTime.now(),metaObject);
  21. }
  22. }

查询

批量查询

  1. @Test
  2. //批量查询 in(1, 2, 3)
  3. void testSelectBatchIds() {
  4. List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));
  5. users.forEach(System.out::println);
  6. }

条件查询

  1. //简单的 条件查询
  2. @Test
  3. void testSelectByMap() {
  4. HashMap<String, Object> map = new HashMap<>();
  5. map.put("name","hello");
  6. map.put("email","geji@qq.com");
  7. List<User> users = userMapper.selectByMap(map);
  8. users.forEach(System.out::println);
  9. }

分页查询

  1. @Test
  2. void testSelectPage() {
  3. Page<User> userPage = new Page<>(1, 5);
  4. userMapper.selectPage(userPage, null);
  5. List<User> records = userPage.getRecords();
  6. records.forEach(System.out::println);
  7. }

逻辑删除

数据库添加逻辑字段
在实体类里也添加字段

  1. //表示当前字段为逻辑删除字段,默认1删除,0未删除
  2. @TableLogic
  3. private Integer isDeleted;

代码生成器 和 配置

要引入 模版和 generator 依赖

  1. <dependency>
  2. <groupId>com.baomidou</groupId>
  3. <artifactId>mybatis-plus-generator</artifactId>
  4. <version>3.3.1.tmp</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.apache.velocity</groupId>
  8. <artifactId>velocity-engine-core</artifactId>
  9. <version>2.2</version>
  10. </dependency>
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/mybatis-plus?serverTimezone=Asia/Shanghai&useUnicode=yes
    username: root
    password: 123456
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  mapper-locations:
    - classpath:cn.edu.zzuli.mapper.xml/*.xml
    @Test
    void testCodeGenerator() {
        //1.创建代码生成器
        AutoGenerator mpg = new AutoGenerator();


        //2.全局配置
        GlobalConfig gc = new GlobalConfig();
        //获取当前项目的路径
        String projectPath = System.getProperty("user.dir");
        gc.setOutputDir(projectPath + "/src/main/java");
        gc.setAuthor("geji");
        //生成后是否打开资源管理器
        gc.setOpen(false);
        //生成文件的时候是否重新覆盖
        gc.setFileOverride(false);
        //设置主键策略
        gc.setIdType(IdType.AUTO);

        //设置Service首字母去除I
        gc.setServiceName("%sService");
        //设置日期类型
        gc.setDateType(DateType.TIME_PACK);
        //实体属性 Swagger2 注解
        gc.setSwagger2(true);

        mpg.setGlobalConfig(gc);


        //3.数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://127.0.0.1:3306/mybatis-plus?serverTimezone=Asia/Shanghai&useUnicode=yes");
        // dsc.setSchemaName("public");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("123456");
        mpg.setDataSource(dsc);


        // 包配置
        PackageConfig pc = new PackageConfig();
//        pc.setModuleName(scanner("模块名"));
        pc.setParent("cn.edu.zzuli.MybatisPlusGenerate");
        pc.setEntity("entity");
        pc.setController("controller");
        pc.setService("service");
        pc.setMapper("mapper");

        mpg.setPackageInfo(pc);

        //策略配置
        StrategyConfig strategy = new StrategyConfig();
        //strategy.setInclude("xxx"+"_\\w*");//映射的表名
        //strategy.setTablePrefix("xxx_");//不生成表的前缀
        strategy.setNaming(NamingStrategy.underline_to_camel);//驼峰策略
        //strategy.setColumnNaming(NamingStrategy.underline_to_camel);

        //自动添加 lombok的注解
        strategy.setEntityLombokModel(true);
        strategy.setLogicDeleteFieldName("is_deleted");
        //去除boolean值的前缀
        //strategy.setEntityBooleanColumnRemoveIsPrefix(true);

        //生成自动填充
        TableFill createTime = new TableFill("create_time", FieldFill.INSERT);
        TableFill updateTime = new TableFill("update_time", FieldFill.INSERT_UPDATE);
        List<TableFill> tableFills = new ArrayList<>();
        tableFills.add(createTime);
        tableFills.add(updateTime);
        strategy.setTableFillList(tableFills);

        //生成乐观锁的列,version 字段,这里我没有用,就注释掉
        //strategy.setVersionFieldName("version");

        //RestFul API
        strategy.setRestControllerStyle(true);
        //url 驼峰命名,转换为_
        strategy.setControllerMappingHyphenStyle(true);

        mpg.setStrategy(strategy);

        //执行
        mpg.execute();

    }

网友的踩坑日记

条件构造器

舒服啊,这样,特别是 lambdaWrapper,美滋滋好吧

        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getName,"halo")
                .lt(User::getAge,25);

        User user = userMapper.selectOne(queryWrapper);
        System.out.println(user);

条件构造器官网文档