MybatisPlus

gitee地址:https://gitee.com/infiniteStars/mybatis-plus
笔记是根据B站狂神说Java整理得来的,建议边看视频,边看笔记。

1.简介

2.快速入门

  1. 新建数据库
DROP TABLE IF EXISTS user;

CREATE TABLE user
(
	id BIGINT(20) NOT NULL COMMENT '主键ID',
	name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
	age INT(11) NULL DEFAULT NULL COMMENT '年龄',
	email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
	PRIMARY KEY (id)
);

DELETE FROM user;

INSERT INTO user (id, name, age, email) VALUES
(1, 'Jone', 18, 'test1@baomidou.com'),
(2, 'Jack', 20, 'test2@baomidou.com'),
(3, 'Tom', 28, 'test3@baomidou.com'),
(4, 'Sandy', 21, 'test4@baomidou.com'),
(5, 'Billie', 24, 'test5@baomidou.com');
  1. 初始化一个SpringBoot项目
  2. 导入依赖
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
    <!--       mybatis-plus-->
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.0.5</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>
  1. 连接数据库
spring:
  datasource:
    username: root
    password: root
    url: jdbc:mysql://localhost:3306/mybatis_plus?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
    driver-class-name: com.mysql.jdbc.Driver
  1. 创建User类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private Long id;
    private String name;
    private Integer age;
    private String email;
}
  1. 创建UserMapper
@Repository
public interface UserMapper extends BaseMapper<User> {
}
  1. 在启动类中配置mapper扫描
    • @MapperScan(“com.dz.mybatis_plus.mapper”)
@MapperScan("com.dz.mybatis_plus.mapper")
@SpringBootApplication
public class MybatisPlusApplication {

    public static void main(String[] args) {
        SpringApplication.run(MybatisPlusApplication.class, args);
    }
}
  1. 测试
@Autowired
private UserMapper userMapper;
@Test
void contextLoads() {
    List<User> users = userMapper.selectList(null);
    for (User user : users) {
        System.out.println(user);
    }
}
  1. 测试结果

image-20210515103910686

3.配置日志

  • 现在的SQl语句都是不可见的,所以需要配置日志将它显示出来。
#配置日志
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  • 效果

image-20210515104523133

4.自动填充处理

  • 在处理数据库数据时,我们都希望create_time和updata_time两个字段可以自动生成和更新。下边介绍两种方式。

1.数据库级别

  • 在工作中不建议修改数据库。
  • 在表中新建字段,并进行配置。create_time只用填默认,不用√下边的。

image-20210515111618829

  • 更新User类
private Date createTime;private Date updataTime;
  • 测试(修改数据)
@Testvoid updataTest() {   
  User user = new User();   
  user.setAge(20);    
  user.setId(1L);    
  int i = userMapper.updateById(user);    
  System.out.println(i);}
  • 结果

image-20210515114030364

2.代码级别

  • 将刚才在数据库中设置的改为默认。只保留字段。
  • 在User类相应字段添加注解
@TableField(fill = FieldFill.INSERT)
private Date createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updataTime;
  • 编写对应的处理器
@Component
@Slf4j
public class MyMeatObjectHandler implements MetaObjectHandler {
    @Override
    public void insertFill(MetaObject metaObject) {
        this.setFieldValByName("createTime",new Date(),metaObject);
        this.setFieldValByName("updataTime",new Date(),metaObject);
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        this.setFieldValByName("updataTime",new Date(),metaObject);
    }
}

  • 测试

5.乐观锁

1.简介

当要更新一条记录的时候,希望这条记录没有被别人更新。
乐观锁实现方式:

  • 取出记录时,获取当前version
  • 更新时,带上这个version
  • 执行更新时, set version = newVersion where version = oldVersion
  • 如果version不对,就更新失败
乐观锁:1、先查询,获得版本号 version = 1
      -- A update user set name = "kuangshen", version = version + 1 where id = 2 and version = 1
      -- B 线程抢先完成,这个时候 version = 2,会导致 A 修改失败!
      update user set name = "kuangshen", version = version + 1where id = 2 and version = 1

2.实现步骤

  1. 在数据库中添加version字段。
  2. 在User类中添加
@Version //代表这是一个乐观锁private Integer version;
  1. 新建一个配置类
@Configuration@EnableTransactionManagement@MapperScan("com.dz.mybatis_plus.mapper")
public class MybatisPlusConfig {    
// 注册乐观锁插件    
  @Bean    
  public OptimisticLockerInterceptor optimisticLockerInterceptor() {        
          return new OptimisticLockerInterceptor();    }}
  1. 测试
  • 线程二插队,更新之后version变为2, 所以线程一就更新不了。
@Testpublic void testOptimisticLocker2(){    
// 线程 1    
User user = userMapper.selectById(1L);    
user.setName("kuangshen111");    
user.setEmail("24736743@qq.com");    
// 模拟另外一个线程执行了插队操作    
User user2 = userMapper.selectById(1L);    
user2.setName("kuangshen222");    
user2.setEmail("24736743@qq.com");   
 userMapper.updateById(user2);    
 // 自旋锁来多次尝试提交!    
 userMapper.updateById(user); 
 // 如果没有乐观锁就会覆盖插队线程的值!}

image-20210515133356509

6.分页插件

  1. 配置
 //分页插件
 @Bean
 public PaginationInterceptor paginationInterceptor() {    
    return new PaginationInterceptor();}
  1. 测试
@Test
public void testPage(){    
// 参数一:当前页    // 参数二:页面大小    // 使用了分页插件之后,所有的分页操作也变得简单的!    
Page<User> page = new Page<>(1,5);    
userMapper.selectPage(page,null);   
 page.getRecords().forEach(System.out::println);    
 System.out.println(page.getTotal());}

image-20210515135939489

7.逻辑删除

物理删除 :从数据库中直接移除

逻辑删除 :在数据库中没有被移除,而是通过一个变量来让他失效! deleted = 0 > deleted = 1

管理员可以查看被删除的记录!防止数据的丢失,类似于回收站!

  1. 数据库添加deleted字段。
  2. User类添加deleted属性
@TableLogic //逻辑删除注解
private Integer deleted;
  1. 配置
  • 在config中
//    逻辑删除
@Bean
public ISqlInjector sqlInjector(){    
return new LogicSqlInjector();
}
  • 在application.yml配置
#逻辑删除
mybatis-plus:  
  global-config:    
    db-config:      
      logic-delete-field: flag 
       # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)      
       logic-delete-value: 1 # 逻辑已删除值(默认为 1)      
       logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
  1. 测试
@Testpublic void deleteTest(){   
 int i = userMapper.deleteById(1L);
 }

image-20210515141738176

  • 数据库中的数据并没有被删除,但是查询的时候查询不到。

image-20210515141828527

8.代码一键生成

  1. 导入依赖
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.0.5</version>
</dependency>
<!--        代码生成器依赖-->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.4.1</version>
</dependency>
<!-- 模板引擎 -->
<dependency>
    <groupId>org.apache.velocity</groupId>
    <artifactId>velocity-engine-core</artifactId>
    <version>2.0</version>
</dependency>
  1. 在test下边新建一个AutoCode类
  • 想要生成其他的表,只需在策略配置中修改表名即可。可以写多个表名。
// 代码自动生成器
public class AutoCode {
    public static void main(String[] args) {
        // 需要构建一个 代码自动生成器 对象
        AutoGenerator mpg = new AutoGenerator();
        // 配置策略
        // 1、全局配置
        GlobalConfig gc = new GlobalConfig();
        String projectPath = System.getProperty("user.dir");
        gc.setOutputDir(projectPath+"/src/main/java");
        gc.setAuthor("dz");
        gc.setOpen(false);
        gc.setFileOverride(false); // 是否覆盖
        gc.setServiceName("%sService"); // 去Service的I前缀
        gc.setIdType(IdType.ID_WORKER);
        gc.setDateType(DateType.ONLY_DATE);
        gc.setSwagger2(true);
        mpg.setGlobalConfig(gc);
        //2、设置数据源
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://localhost:3306/hellomall? useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("root");
        dsc.setDbType(DbType.MYSQL);
        mpg.setDataSource(dsc);
        //3、包的配置
        PackageConfig pc = new PackageConfig();
        pc.setParent("com.dz");
        pc.setEntity("pojo");
        pc.setMapper("mapper");
        pc.setService("service");
        pc.setController("controller");
        mpg.setPackageInfo(pc);
        //4、策略配置
        StrategyConfig strategy = new StrategyConfig();
        strategy.setInclude("cart"); // 设置要映射的表名,可以写多个
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        strategy.setEntityLombokModel(true); // 自动lombok;
        strategy.setLogicDeleteFieldName("deleted");
        // 自动填充配置
        TableFill gmtCreate = new TableFill("gmt_create", FieldFill.INSERT);
        TableFill gmtModified = new TableFill("gmt_modified", FieldFill.INSERT_UPDATE);
        ArrayList<TableFill> tableFills = new ArrayList<>();
        tableFills.add(gmtCreate);
        tableFills.add(gmtModified);
        strategy.setTableFillList(tableFills);
        // 乐观锁
        strategy.setVersionFieldName("version");
        strategy.setRestControllerStyle(true);
        strategy.setControllerMappingHyphenStyle(true); //localhost:8080/hello_id_2
        mpg.setStrategy(strategy);
        mpg.execute(); //执行
    }
}

  1. 结果

image-20210515150239061

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐