mybatis-plus

来源:xiaoger 发布时间:2020-04-06 12:30:08 作者:admin 阅读量:188

mybatis-plus

1、使用条件**

  • 需要导入的包

        <!--mybatis-plus-->
       <dependency>
           <groupId>com.baomidougroupId>
           <artifactId>mybatis-plus-boot-starterartifactId>
           <version>3.0.5version>
       dependency>
  • application.properties配置

#数据库配置
spring.datasource.username=root
spring.datasource.password=123xjx
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

#配置日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

2、使用方法

  • 需要mapper包下面的类需要继承BaseMapper,然后才会有基本的增删改查方法。

package com.xiaoger.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xiaoger.pojo.User;
import org.springframework.stereotype.Repository;

@Repository  //这个是标明这个类是mapper类
public interface UserMapper extends BaseMapper<User> {
}
  • 测试连接数据库以及对数据库的操作

@SpringBootTest
class MybatisPlusApplicationTests {


   @Autowired
   private UserMapper userMapper;

   @Test
   void contextLoads() {   //可以使用userMapper里面的方法
       List<User> users = userMapper.selectList(null);

       users.forEach(System.out::println);
   }
}

3、主键唯一策略

  • 主键自增,实体类字段上加上 @TableId(type= IdType.AUTO)

  • 数据库上的字段一定要自增,不然会出错

image-20200405144356367

  • 一些源码的解释

public enum IdType {
   AUTO(0),  //数据库的自增
   NONE(1),  //未设置主键,一般为null
   INPUT(2),  //手动输入主键id
   ID_WORKER(3),  //默认全局唯一的id
   UUID(4),   //全局唯一id
   ID_WORKER_STR(5);  //ID_WORKER的字符串表示法
}

4、数据库字段自动填充

  • 一般就是创建时间以及更新时间这两个字段需要在数据库中自动填充

  • 实体类字段上面加上自动填充的注解:

    //字段填充内容
   @TableField(fill = FieldFill.INSERT)
   private Date createTime; //创建时间
   @TableField(fill = FieldFill.INSERT_UPDATE)
   private Date updateTime;  //更新时间
  • 然后实现这个自动填充策略

package com.xiaoger.handler;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.util.Date;

@Slf4j  //这个是打印日志的
@Component   //加入到Ioc容器中
public class MyMetaObjectHandler implements MetaObjectHandler {

   //插入的填充策略
   @Override
   public void insertFill(MetaObject metaObject) {
       //setFieldValByName(String fieldName, Object fieldVal, MetaObject metaObject)
       this.setFieldValByName("createTime",new Date(),metaObject);
       this.setFieldValByName("updateTime",new Date(),metaObject);
   }

   //更新填充策略
   @Override
   public void updateFill(MetaObject metaObject) {
       this.setFieldValByName("updateTime",new Date(),metaObject);
   }
}

5、乐观锁的使用

  • 就是在多线程的情况下,保证对数据库的读写操作安全。

  • 取出记录时,获取当前version

  • 更新时,带上这个version

  • 执行更新时, set version = yourVersion+1 where version = yourVersion

  • 如果version不对,就更新失败

--A 线程A开始查询
update user set name="xiaoger",version=version+1
where id=2 and version=1
--B 线程抢先完成,这个时候,version就变成了2,就会导致线程A修改失败
update user set name="xiaoger",version=version+1
where id=2 and version=1
  • 说白了就是A线程查出来了数据准备修改,然后B线程也查出了相同的数据准备修改,但是B比A先修改,version默认为1,然后version就变成了2,导致A线程携带的version=1不能对数据进行修改,保证了安全性。

使用方法:

  • 数据库里面需要加一个version字段,一般为int, 默认值为1

  • 在实体类上面加一个@version注解,表示乐观锁注解

@TableId(type= IdType.AUTO)
   private int id;
   private String name;
   private String pwd;

   @Version  //乐观锁注解
   private int version;
  • 注册乐观锁组件(一般写一个config的配置类,bean注入插件就行了)

@MapperScan("com.xiaoger.mapper")
@EnableTransactionManagement  //自动管理事务
@Configuration  //代表是一个配置类
public class MyBatisPlusConfig {

   @Bean
   public OptimisticLockerInterceptor optimisticLockerInterceptor() {
       return new OptimisticLockerInterceptor();
   }
}
  • 测试乐观锁

@Test
   public void testVersion(){
       
       //线程1进行更新操作(更新失败)
       User user = userMapper.selectById(10);
       user.setName("测试名字1111");
       user.setPwd("1234567");

       //模拟线程2进行更新操作(更新成功)
       User user1 = userMapper.selectById(10);
       user1.setName("测试名字22222");
       user1.setPwd("1234567");
       userMapper.updateById(user1);

       userMapper.updateById(user);
   }

6、分页查询

  • 需要在config配置类配置分页插件

//分页
   /**
    * 分页插件
    */
   @Bean
   public PaginationInterceptor paginationInterceptor() {
       return new PaginationInterceptor();
   }
  • 然后就可以使用了(测试)

    //分页
   @Test
   public void page(){
       //第一个参数代表第几页,第二个参数代表查询几条数据
       Page<User> Page = new Page<>(1,2);
       userMapper.selectPage(Page,null);

       Page.getRecords().forEach(System.out::println);
   }

7、逻辑删除

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

逻辑删除:在数据库中没有移除,只是通过一个变量让他查询不到。

  • 给数据库表增加一个字段,deleted =>0表示正常,1表示被逻辑删除了。

image-20200405205245239

  • 在实体类上增加属性

    @TableLogic  //逻辑删除的注解
   private int deleted;
  • 在config配置类中配置

    //逻辑删除组件
   @Bean
   public ISqlInjector sqlInjector(){
       return new LogicSqlInjector();
   }
  • 这个还要再properties中进行配置

#配置逻辑删除(其实就代表数据库中deleted对应的字段)
mybatis-plus.global-config.db-config.logic-delete-value=1
mybatis-plus.global-config.db-config.logic-not-delete-value=0
  • 测试逻辑删除

    //逻辑删除
   @Test
   public void luoji(){
       userMapper.deleteById(2);
   }

image-20200405210128576

  • 可以看出逻辑查询本质上就是一个更新操作,只是将deleted的值改为1,后面如果正常查询的话,每次查询都会带上deleted=0这个条件去查询,如果该数据经过了逻辑删除,deleted=1,那么就不会被查询到。

image-20200405210524495

8、性能分析

作用:能够输出当前sql查询数据所用的时间,便于优化

  • 配置开发环境(properties)

#开发环境
spring.profiles.active=dev
  • 需要在config配置类中配置

    /**
    * SQL执行效率插件
    */
   @Bean
   @Profile({"dev","test"})// 设置 dev test 环境开启(需要)
   public PerformanceInterceptor performanceInterceptor() {
       PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
       performanceInterceptor.setMaxTime(100);  //设置sql语句最大的查询时间
       performanceInterceptor.setFormat(true);  //格式化sql语句(就是让sql语句排版输出,方便观察)

       return performanceInterceptor;
   }
  • 测试查询全部用户

image-20200405212847229

9、代码自动生成器

pojo,service,controller都可以自己生成。

  • 需要导入的依赖(主要几个核心依赖)

<!--mybatis-plus-->
       <dependency>
           <groupId>com.baomidougroupId>
           <artifactId>mybatis-plus-boot-starterartifactId>
           <version>3.0.5version>
       dependency>
       <!--不导入这个会导致生成文件错误-->
       <dependency>
           <groupId>org.apache.velocitygroupId>
           <artifactId>velocity-engine-coreartifactId>
           <version>2.0version>
       dependency>
       <dependency>
           <groupId>org.projectlombokgroupId>
           <artifactId>lombokartifactId>
       dependency>
       <!--swagger2-->
       <dependency>
           <groupId>io.springfoxgroupId>
           <artifactId>springfox-swagger2artifactId>
           <version>2.9.1version>
       dependency>
  • 可以在test目录下建一个java类(配置详情)

package com.xiaoger.auto_code.Code;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
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;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;

import java.util.ArrayList;

public class test {
   public static void main(String[] args) {
       //需要构建一个代码自动生成器对象
       AutoGenerator mpg = new AutoGenerator();

       //配置策略
       //1、全局配置
       GlobalConfig gc = new GlobalConfig();
       String projectPath = System.getProperty("user.dir");  //获得项目路径
//        System.out.println(projectPath);
       gc.setOutputDir(projectPath+"/src/main/java"); //拼接得到包路径
       gc.setAuthor("xiaoger");//作者名字
       gc.setOpen(false);//不打开资源管理器
       gc.setFileOverride(true);//是否覆盖文件
       gc.setServiceImplName("%sService");//去掉service的I前缀
       gc.setIdType(IdType.ID_WORKER); //默认全局唯一的id
       gc.setDateType(DateType.ONLY_DATE);
       gc.setSwagger2(true);
       mpg.setGlobalConfig(gc);  //把设置好的gc放入对象中

       //设置数据源
       DataSourceConfig dsc = new DataSourceConfig();
       dsc.setUrl("jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8");
       dsc.setDriverName("com.mysql.cj.jdbc.Driver");
       dsc.setUsername("root");
       dsc.setPassword("123xjx");
       dsc.setDbType(DbType.MYSQL);  //设置为mysql数据库
       mpg.setDataSource(dsc);

       //包的配置
       PackageConfig pc = new PackageConfig();
       pc.setModuleName("user");
       pc.setParent("com.xiaoger.auto_code");
       pc.setEntity("entity");  //实体类
       pc.setMapper("mapper");  //mapper包
       pc.setService("service"); //service包
       pc.setController("controller"); //控制层
       mpg.setPackageInfo(pc);

       //策略配置
       StrategyConfig strategy = new StrategyConfig();
       strategy.setInclude("user"); //设置要映射的表名(可以多个)
       strategy.setNaming(NamingStrategy.underline_to_camel); //驼峰命名
       strategy.setColumnNaming(NamingStrategy.underline_to_camel);
       strategy.setEntityLombokModel(true);//导入lombok包

       strategy.setLogicDeleteFieldName("deleted"); // 逻辑删除字段名称

       //自动填充配置
       //一般针对数据库中创建时间和修改时间这两个字段
       TableFill gmtCreate = new TableFill("create_time", FieldFill.INSERT);
       TableFill gmtModified = new TableFill("update_time",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);

       mpg.setStrategy(strategy); //配置策略

       mpg.execute();  //执行


   }
}
  • 生成的目录结构


Original article, reproduced please specify:mybatis-plus | xiaoger

(本站所有资源来源于网络,仅供学习交流使用,本站不承担关于本资源的任何法律责任。)

我要评论 登录后才能发布评论

  Article archive

感谢鲶鱼博客提供的模板   我要留言
中央许可免备案
Catfish(鲶鱼) CMS V 5.9.15