首页 > 其他分享 >微服务框架——MybatisPlus

微服务框架——MybatisPlus

时间:2022-11-17 18:58:25浏览次数:64  
标签:服务 框架 column iEmployeeService employee new Employee MybatisPlus class

MybatisPlus

一、快速入门

1.mybatisPlus特性
  • 无侵入:只增强,不改变。
  • 损耗小:启动的时候直接注入基本CRUD
  • 强大的CRUD操作:提供通用Mapper,通用service,条件构造器等
  • Lambda:支持lambda形式的调用
  • 主键自动生成
  • 支持ActiveRecord模式:实体类只需继承 Model 类即可进行强大的 CRUD 操作
  • 支持自定义全局通用操作
  • 内置代码生成器
  • 内置分页插件,且支持多种数据库
  • 内置性能分析插件:输出sql语句执行时间
  • 内置全局拦截插件
2.快速开始
  • 屏蔽数据库建表插入数据细节,Employee表,Employee实体类。忽略架构层级细节

  • 导入依赖

    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.2.0</version>
    </dependency>
    
  • Mapper类

    @Repository
    @Mapper
    public interface EmployeeMapper extends BaseMapper<Employee> {
    }
    
  • 测试类

    @SpringBootTest
    class BoottestApplicationTests extends AbstractJUnit4SpringContextTests {
    
        @Autowired
        EmployeeMapper employeeMapper;
    
        @Test
        void contextLoad2() {
            //UserMapper 中的 selectList() 方法的参数为 MP 内置的条件封装器 Wrapper,所以不填写就是无任何条件
            List<Employee> list = employeeMapper.selectList(null);
            for (Employee employee : list) {
                System.out.println(employee);
            }
        }
    }
    

    输出成功:

3.相关注解
  • @TableName

    标识实体类对应的表

    @TableName("employee")
    public class Employee {
        private int id;
        private String name;
        private int did;
    }
    
  • @TableId

    标识主键

    public class Employee {
        @TableId
        private int id;
        private String name;
        private int did;
    }
    

    type值可以设置当前主键的生成策略

  • @TableField

    标识数据库的其他字段

    public class Employee {
        @TableId
        private int id;
        @TableField("name")
        private String name;
        private int did;
    }
    
  • @Version

    乐观锁注解,标识在对应字段属性上

  • @EnumValue

    普通枚举类注解

  • @TableLogic

    表字段逻辑处理注解(逻辑删除等)

  • @OrderBy

    内置sql默认指定排序

二、基本功能

1.逻辑删除

逻辑删除是为了方便数据恢复和保护数据本身价值等等的一种方案,但实际对用户来说就是删除。只是管理员可以选择去管理删除掉的数据。

  • 使用(在实体类的对应字段上添加@TableLogic注解)

    @TableLogic
    private Integer deleted;
    
  • 配置

    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)
    
  • 实际场景

    实际场景中,官方推荐直接在数据库中设置逻辑删除字段的默认值。

    如果不想设置默认值,可以在insert的时候插入到实体类对象中或者使用mp的自动填充功能

2.自动填充

自定义填充功能意在某些场景下减少程序员的工作量,比如注册时间、更新时间这些,或者说上文的逻辑删除需要在插入时赋值等。可以让mp直接托管字段的赋值,非常银杏。

  • 使用:

    public class User {
        // 注意!这里需要标记为填充字段
        @TableField(fill = FieldFill.INSERT)
        private String fillField;
        ....
    }
    

    填充字段的值一共有4种。对应的值对应某个插入场景。

  • 配置:填充功能的配置需要实现MetaObjectHandler接口。

    @Component
    public class MyMetaObjectHandler implements MetaObjectHandler {
    
        @Override
        public void insertFill(MetaObject metaObject) {
            //参数(参数类,填充字段名,填充类型,填充值)
            this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now()); // 起始版本 3.3.0(推荐使用)
            // 或者
            this.strictInsertFill(metaObject, "createTime", () -> LocalDateTime.now(), LocalDateTime.class); // 起始版本 3.3.3(推荐)
        }
    
        @Override
        public void updateFill(MetaObject metaObject) {
            this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); // 起始版本 3.3.0(推荐)
            // 或者
            this.strictUpdateFill(metaObject, "updateTime", () -> LocalDateTime.now(), LocalDateTime.class); // 起始版本 3.3.3(推荐)
        }
    }
    
3.主键策略
public enum IdType {
    //数据库ID自增,数据库需要支持主键自增(如MySQL),并设置主键自增
    AUTO(0),
    //该类型为未设置主键类型,默认使用雪花算法生成
    NONE(1),
    //用户输入ID,数据类型和数据库保持一致就行
    //该类型可以通过自己注册自动填充插件进行填充
    INPUT(2),
    //以下3种类型、只有当插入对象ID 为空,才自动填充。 */
    //全局唯一ID (idWorker),数值类型  数据库中也必须是数值类型 否则会报错
    ID_WORKER(3),
    //全局唯一ID (UUID,不含中划线)
    UUID(4),
    //字符串全局唯一ID (idWorker 的字符串表示),数据库也要保证一样字符类型
    ID_WORKER_STR(5);
}

如果在@TableId中使用type指定了主键策略的话,那么就得配置主键策略相关的bean使其生效。

我们也可以直接选择在yml中配置全局策略使其生效。

mybatis-plus:
  global-config:
    db-config:
      id-type: auto

甚至可以自定义自己的主键策略,只需要实现IdentifierGenerator接口即可

@Component
public class CustomIdGenerator implements IdentifierGenerator {
    @Override
    public Long nextId(Object entity) {
      	//id生成逻辑
        ...
      	//返回生成的id
        return id;
    }
}

注入自定义的主键策略

@Bean
public IdentifierGenerator idGenerator() {
    return new CustomIdGenerator();
}
4.默认CRUD注入

MP为我们自动注入了很多基本的crud操作,这在极大程度上省去了很多的工作量

  • Service

    编写自己的service类继承mp的service基类IService<>,泛型为表映射的实体类名

    @Service
    public interface IEmployeeService extends IService<Employee> {
    
    }
    

    常用api

    @Test
    void mpService(){
        Employee employee = new Employee();
        List<Employee> employeeList = Collections.singletonList(employee);
        //插入一条记录
        iEmployeeService.save(employee);
        //批量插入
        iEmployeeService.saveBatch(employeeList);
        //存在更新,不存在则插入
        iEmployeeService.saveOrUpdate(employee);
        iEmployeeService.saveOrUpdate(employee,new UpdateWrapper<>());
        iEmployeeService.saveOrUpdateBatch(employeeList);
        //条件删除
        iEmployeeService.remove(new QueryWrapper<>());
        iEmployeeService.removeById(1);
        //批量删除
        iEmployeeService.removeByIds(employeeList.stream().map(Employee::getId).collect(Collectors.toList()));
        //根据id查询
        Employee employee1 = iEmployeeService.getById(1);
        //条件查询
        Map<String, Object> employeeMap = iEmployeeService.getMap(new QueryWrapper<>());
        Employee employee2 = iEmployeeService.getOne(new QueryWrapper<>());
        //查询全表
        List<Employee> employeeList1 = iEmployeeService.list();
        List<Employee> employeeList2 = iEmployeeService.listByIds(employeeList.stream().map(Employee::getId).collect(Collectors.toList()));
        //分页查询
        Page<Employee> employeePage1 = iEmployeeService.page(new Page<>());
        Page<Employee> employeePage2 = iEmployeeService.page(new Page<>(),new QueryWrapper<>());
        //查询数量
        int count = iEmployeeService.count(new QueryWrapper<>());
        //链式查询
        iEmployeeService.query().eq("name","马云").ge()....
        //链式条件删除
        iEmployeeService.update().eq("name","马云").remove();
        //链式条件更新
        iEmployeeService.update().eq("name","马云").update();
    }
    
  • Mapper

    编写自己的Mapper类继承mp的mapper基类BaseMapper<>,泛型为表映射的实体类名

    @Repository
    @Mapper
    public interface EmployeeMapper extends BaseMapper<Employee> {
    }
    

    常用api

    @Test
    void mpMapper(){
        Employee employee = new Employee();
        List<Employee> employeeList = Collections.singletonList(employee);
        //插入一条记录
        employeeMapper.insert(employee);
        //条件删除
        employeeMapper.delete(new QueryWrapper<>());
        //批量删除
        employeeMapper.deleteBatchIds(employeeList.stream().map(Employee::getId).collect(Collectors.toList()));
        employeeMapper.deleteById(1);
        employeeMapper.updateById(employee);
        //批量查找
        List<Employee> employeeList1 = employeeMapper.selectList(new QueryWrapper<>());
        List<Employee> employeeList2 = employeeMapper.selectBatchIds(employeeList.stream().map(Employee::getId).collect(Collectors.toList()));
        //查询数量
        Integer count = employeeMapper.selectCount(new QueryWrapper<>());
        //分页查询
        Page<Employee> employeePage = employeeMapper.selectPage(new Page<>(), new QueryWrapper<>());
    }
    
  • Class

    实体类继承mp的Model基类之后,可以直接使用实体类的对象进行基本的crud操作,非常银杏

    public class Employee extends Model<Employee> implements Serializable {
    ...
    }
    
    @Test
    void mpModel(){
        Employee employee = new Employee();
        employee.insert();
        employee.deleteById();
        employee.updateById();
        employee.selectById();
    }
    

三、条件构造器

在前文的很多地方都能看到条件构造器的身影,他们是mp用于生成 sql 的 where 条件的一个工具类。比较常用的就是queryWrapper和updateWrapper

1.QueryWrapper
  • 等值比较

    eq(R column, Object val); // 等于 =,比如 eq("name", "老六") ---> name = '老六'
    ne(R column, Object val); // 不等于 <>
    gt(R column, Object val); // 大于 >
    ge(R column, Object val); // 大于等于 >=
    lt(R column, Object val); // 小于 <
    le(R column, Object val); // 小于等于 <=
    
  • 范围比较

    between(R column, Object val1, Object val2); // between a and b, 例: between("age", 18, 30) ---> age between 18 and 30
    notBetween(R column, Object val1, Object val2); // not between a and b
    in(R column, Object... values); // IN (v0, v1, ...)
    notIn(R column, Object... values); // NOT IN (v0, v1, ...)
    inSql(R column, String value); // IN sql语句
    notInSql(R column, String value); // NOT IN sql语句
    
  • 模糊匹配

    like(R column, Object val); // LIKE '%值%',比如like("name", "王") ---> name like '%王%'
    notLike(R column, Object val); // NOT LIKE '%值%'
    likeLeft(R column, Object val); // LIKE '%值'
    likeRight(R column, Object val); // LIKE '值%'
    
  • 空值比较

    isNull(R column); // IS NULL,例: isNull("name") ---> name is null
    isNotNull(R column); // IS NOT NULL
    
  • 分组排序

    groupBy(R... columns); // 等价于 GROUP BY colums ..., 例: groupBy("id", "name") ---> group by id,name
    orderByAsc(R... columns); // ORDER BY colums... ASC   升序
    orderByDesc(R... columns); // ORDER BY colums ... DESC   降序
    having(String sqlHaving, String value); // HAVING ( sql语句 )
    
  • 实际中sql语句不建议直接在wrapper语句中写。如果有wrapper实现不了的语句,直接使用原始的mybatis写即可。

四、扩展功能

1.代码生成器

新版本的代码生成器需要额外导入一个mybatis-plus-generator的依赖,并且只有3.5.1及以上版本适用新的生成器

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.5.1</version>
</dependency>

生成器需要一个可运行的程序,可以直接自定义一个工具程序,在main函数里运行生成程序。

新版本的改进是优化了旧版本的set注入,而是采用链式编程的方式。以FastAutoGenerator为启动器进行配置

//数据库驱动配置
FastAutoGenerator.create("url",username,password)
//基本配置,参数为一个函数式接口,之后的配置相同
.globalConfig(new Consumer<GlobalConfig.Builder>() {
    @Override
    public void accept(GlobalConfig.Builder builder) {
        builder.outputDir(System.getProperty("user.dir") + "/src/main/java")//包输出路径
                .author("姬如千泷")//作者名
                .dateType(DateType.ONLY_DATE)//时间类型
                .fileOverride()//文件覆盖
                .enableSwagger()//开启swagger
                .enableKotlin()//开启kotlin模式,泛用性更广的编程语言
                .commentDate(String)//日期格式化串
                .build();//构建
    }
})
//包配置
.packageConfig(builder -> {
     builder.parent("com...")//父包名,默认为com.baomidou
            .
            .entity("entity")//实体类包名
            .mapper("mapper")//mapper包名
            .controller("controller")//controller包名
            .service("service");//service包名
            .serviceImpl("service.impl")//实现类包名
            .xml("mapper.xml")//xml包名
            .other("other")//自定义文件包名
            .pathInfo("")//输出路径
            .build();//构建
})
//模板配置
.templateConfig(builder -> {
     builder.disable()//禁用所有模板
            .disable(TemplateType.ENTITY...)//禁用部分模板
            .entity("/templates/entity.java")//设置实体类模板路径,下同
            .service("/templates/service.java")
            .serviceImpl("/templates/serviceImpl.java")
            .mapper("/templates/mapper.java")
            .mapperXml("/templates/mapper.xml")
            .controller("/templates/controller.java")
})
//策略配置
.strategyConfig(builder -> {
     builder.addInclude("employee","department","company")//添加要生成代码结构的表
            .enableCapitalMode()//开启大写命名
            .enableSkipView()//开启跳过视图
            .disableSqlFilter()//禁用sql过滤
            .likeTable(new LikeTable("USER"))//模糊表匹配
            .addTablePrefix("t_", "c_")//表过滤前缀
            .addFieldSuffix("_flag")//字段过滤后缀
            .build();
}).execute();//执行整个配置

不仅如此,在strategyConfig配置中好可以引申更多的详细配置,比如乐观锁、主键策略等等

.strategyConfig(builder -> {
     builder
            //实体类配置
            .entityBuilder()
            .superClass(BaseEntity.class)//设置父类
            .disableSerialVersionUID()//禁用SerialVersionUID生成
            .enableChainModel()//开启链式模式
            .enableLombok()//启用lombok
            .enableRemoveIsPrefix()//bool字段移除is
            .enableTableFieldAnnotation()//开启字段注解
            .enableActiveRecord()//开启ActiveRecord模型
            .versionColumnName("version")//乐观锁字段名
            .logicDeleteColumnName("deleted")//逻辑删除字段名
            .naming(NamingStrategy.no_change)//表名映射策略——下划线转驼峰
            .columnNaming(NamingStrategy.underline_to_camel)//字段名映射策略——下划线转驼峰
            .addSuperEntityColumns("id", "created_by", "created_time", "updated_by", "updated_time")//父类公共字段
            .addIgnoreColumns("age")//忽略字段
            .addTableFills(new Column("create_time", FieldFill.INSERT))//表字段填充
            .addTableFills(new Property("updateTime", FieldFill.INSERT_UPDATE))
            .idType(IdType.AUTO)//主键策略
            .formatFileName("%sEntity")//.java文件名
            //controller配置
            .build().controllerBuilder()
            .superClass(BaseController.class)//父类
            .enableHyphenStyle()//驼峰转连字符,如user_hello
            .enableRestStyle()//生成restcontroller注解
            .formatFileName("%sAction")//文件名
            //service配置
            .build().serviceBuilder()
            .superServiceClass(BaseService.class)//接口父类
            .superServiceImplClass(BaseServiceImpl.class)//实现类父类
            .formatServiceFileName("%sService")//接口文件名
            .formatServiceImplFileName("%sServiceImp")//接口实现类文件名
            //mapper配置
            .build().mapperBuilder()
            .superClass(BaseMapper.class)//父类mapper
            .enableMapperAnnotation()//开启@Mappper注解
            .enableBaseResultMap()//启用BaseResultMap
            .enableBaseColumnList()//启用BaseColumnList
            .cache(MyMapperCache.class)//缓存实现类
            .formatMapperFileName("%sDao")//mapper文件名
            .formatXmlFileName("%sXml")//xml文件名
})
2.SQL性能分析插件

mp提供了一种用来帮助程序员检测优化sql语句的插件,可以打印出sql的详情以及执行时长。使用前需要导入依赖包

<dependency>
  <groupId>p6spy</groupId>
  <artifactId>p6spy</artifactId>
  <version>最新版本</version>
</dependency>

在yml中进行配置注入

spring:
  datasource:
    driver-class-name: com.p6spy.engine.spy.P6SpyDriver
    url: jdbc:p6spy:h2:mem:test
    ...

官方提供的关于spy插件的配置

#3.2.1以上使用
modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory
#3.2.1以下使用或者不配置
#modulelist=com.p6spy.engine.logging.P6LogFactory,com.p6spy.engine.outage.P6OutageFactory
# 自定义日志打印
logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger
#日志输出到控制台
appender=com.baomidou.mybatisplus.extension.p6spy.StdoutLogger
# 使用日志系统记录 sql
#appender=com.p6spy.engine.spy.appender.Slf4JLogger
# 设置 p6spy driver 代理
deregisterdrivers=true
# 取消JDBC URL前缀
useprefix=true
# 配置记录 Log 例外,可去掉的结果集有error,info,batch,debug,statement,commit,rollback,result,resultset.
excludecategories=info,debug,result,commit,resultset
# 日期格式
dateformat=yyyy-MM-dd HH:mm:ss
# 实际驱动可多个
#driverlist=org.h2.Driver
# 是否开启慢SQL记录
outagedetection=true
# 慢SQL记录标准 2 秒
outagedetectioninterval=2

3.MybatisX插件

MybatisX 是一款基于 IDEA 的快速开发插件,为效率而生,可视化了大部分的mp功能。直接在插件库下载即可

官方文档:MybatisX快速开发插件 | MyBatis-Plus (baomidou.com)

标签:服务,框架,column,iEmployeeService,employee,new,Employee,MybatisPlus,class
From: https://www.cnblogs.com/wtlbbdbk/p/16900452.html

相关文章

  • Linux简单扩展Http服务
    一、个人用户主页1开启主页功能[root@centos~]#vim/etc/httpd/conf.d/userdir.conf1.1重启服务[root@centos~]#systemctlrestarthttpd2、创建个人用户网站的数据2.1......
  • 群集+LVS虚拟服务器
    一,群集1.何为群集群集:由多台主机构成,但对外只表现为一个整体,只提供一个访问入口(域名或ip),相当于一台大型计算机。2.群集存在的原因互联网应用中,随着站点对硬件性能、响......
  • 6. 服务器内部转发与客户端重定向
    #服务器内部转发##req.getRequestDispatcher("注册的servlet的url,不带/").forward(req,resp);##客户端仅发起一次请求,客户端地址栏不会改变。#客户端重定向##res......
  • 云原生服务编排技术
       基于云原生的服务编排技术主要实现融合计算、存储和网络能力开放,通过云原生和云计算统一编排调度平台来实现底层资源的调度及上层服务编排。运用OpenStack底层基础......
  • 手把手,完整的从0搭建vite-vue3-ts项目框架:配置less+svg+pinia+vant+axios
    项目同步git:https://gitee.com/lixin_ajax/vue3-vite-ts-pinia-vant-less.git  为避免赘述,过于基础的点会直接省略或贴图,比如创建文件夹/文件的路径/路由一类配置相......
  • 云原生服务编排技术
     基于云原生的服务编排技术主要实现融合计算、存储和网络能力开放,通过云原生和云计算统一编排调度平台来实现底层资源的调度及上层服务编排。运用OpenStack底层基础设施......
  • “一站式”家校服务系统---开发日志1
    一、虚拟机搭建(CentOS)1、自行下载安装VirtualBox。visualBox进行安装需要cpu开启虚拟化,在开机启动的时候设置主板,CPUconfiguration,然后点击IntelVitualizationTec......
  • MediatRPC - 基于MediatR和Quic通讯实现的RPC框架,比GRPC更简洁更低耦合,开源发布第一版
    大家好,我是失业在家,正在找工作的博主Jerry。作为一个.Net架构师,就要研究编程艺术,例如SOLID原则和各种设计模式。根据这些原则和实践,实现了一个更简洁更低耦合的RPC(RemoteP......
  • GPS北斗NTP授时服务器助力数字化校园网络建设
    GPS北斗NTP授时服务器助力数字化校园网络建设GPS北斗NTP授时服务器助力数字化校园网络建设京准电子科技官微——ahjzsz随着网络的普及,许多单位都建了自己的园区网,使用的......
  • Nginx网站服务配置
    一、NGINX概述1.1nginx简介Nginx("enginex")是一个开源、高性能、高可靠的HTTP和反向代理服务器。Nginx是由IgorSysoev为俄罗斯访问量第二的Rambler.ru站......