springboot 整合 mybatis-plus

一.前言

        1. mybatis-plus是什么

        mybatis-plus是一个对mybati框架的拓展框架,它在mybatis框架基础上做了许多的增强,帮助我们快速的进行代码开发。目前企业开发中,使用mybati的项目基本会选择使用mybatis-plus来提升开发效率。

        2.官网地址:MyBatis-Plus 🚀 为简化开发而生

二.项目集成

        1. 项目中集成(示例用的springboot2.x+mysql)

        step1.引入依赖

<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.7</version>
</dependency>

        step2.配置数据源

spring: datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://192.168.**.**:3306/ruiusername: rootpassword: ******

        step3.启动类添加注解 @MapperScan 指向mapper接口所在包

@SpringBootApplication
@MapperScan("com.rui.mapper")
@EnableFeignClients(defaultConfiguration = MyFeignConfiguration.class)
public class AdminServerApplication {public static void main(String[] args) {SpringApplication.run(AdminServerApplication.class, args);}
}

        step4.定义实体类

        step5.编码测试:

(编码测试演示比较接近实际开发的代码,如果只是简单验证,用baseMapper就行了)

以下代码均为mybatis-plus提供的代码生成器生成的,如何使用在后续段落会讲,这里先看一下代码样子,眼熟以下

代码结构:

controller层:

@Slf4j
@RestController
@RequestMapping("/configInfo")
public class ConfigInfoController {@Autowiredprivate IConfigInfoService configInfoService;@GetMapping("/list")public List<ConfigInfo>  listConfigs () {return configInfoService.list();}}

service层:

        interface:

public interface IConfigInfoService extends IService<ConfigInfo> {}

        impl:

** 注意,这里继承了一个ServiceImpl 它是mybatis-plus提供的类,帮我们完成许DB操作**

@Service
public class ConfigInfoServiceImpl extends ServiceImpl<ConfigInfoMapper, ConfigInfo> implements IConfigInfoService {}

mapper层:

        mapper接口:

** 注意,我们的mapper实现了 BaseMapper ,它是mybatis-plus提供的接口,有常用的CRUD**

public interface ConfigInfoMapper extends BaseMapper<ConfigInfo> {}

        mapper.xml: (其实就是空的,如果后面开始有自定义sql,需要这里写)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.rui.mapper.ConfigInfoMapper"></mapper>

        以上操作结束后,启动项目,postMan访问接口,发现可以正常访问数据库:

在测试环节,大家可以发现我的service和mapper都是空的,但是却可以调用list方法访问数据库。

其实,上面的编码中,我们在自己的业务Service中继承了抽象类ServiceImpl,ServiceImpl实现了IService这个接口中的方法,并定义了四个成员变量 baseMapper,entityClass, mapperClass,log,且这四个成员变量都是protected的,因此,在我们的业务Service中,我们可以直接调用IService的方法诸如saveAndUpdate,list,page等,也可以通过this.baseMapper 的方式来获取baseMapper对象,来调用baseMapper的方法

三.使用技巧

        1.理解mybatis-plus在代码中做的事情

        mybatis-plus为我们提供的最核心的功能其实就是对Mybatis的Mapper接口的增强,它提供了一个BaseMapper,一个mybatis的mapper接口继承了BaseMapper的话,就会被mybatis-plus进行增强,实现一系列的常用的数据库操。使用mybatis-plus最简单的办法其实就是引入mybatis-plus的依赖后,定义好Entity对象(实体对象),然后让mapper继承BaseMapper,最终我们使用baseMaper中的方法来进行开发。

        看一个使用baseMapper的例子:

        todo

        但是直接使用baseMaper的话,有许多操作我们还需要自己写代码,比如一些批量操作,如batchSave(批量插入)等。所以,mybatis-plus还提供了ServiceImpl,来帮我们实现这些。

        上面的编码中,我们在自己的业务Service中继承了抽象类ServiceImpl,ServiceImpl实现了IService这个接口中的方法,并定义了四个成员变量 baseMapper,entityClass, mapperClass,log,且这四个成员变量都是protected的,因此,在我们的业务Service中,我们可以直接调用IService的方法诸如saveAndUpdate,list,page等,也可以通过this.baseMapper 的方式来获取baseMapper对象,来调用baseMapper的方法。

        2.使用QueryWrapper进行查询

        以该service为例:

        QueryWrapper是我们工作中每天都啊哟使用的,场景非常多,我列出一些常见的场景,方便大家查阅

                1.1. 新增

        ConfigInfo configInfo = mockData();this.baseMapper.insert(configInfo);

                1.2. 删除

        LambdaQueryWrapper<ConfigInfo> configInfoQueryWrapper = new LambdaQueryWrapper<>();configInfoQueryWrapper.eq(ConfigInfo::getId, 500L);this.baseMapper.delete(configInfoQueryWrapper);

                1.3. 修改

        // 方法1 根据id更新,直接传入对象ConfigInfo configInfo = mockData();this.baseMapper.updateById(configInfo);//方法2 使用wrapper更新 set代表要修改的字段 eq是条件为相等的isiUpdateWrapper<ConfigInfo> configInfoUpdateWrapper = Wrappers.update();configInfoUpdateWrapper.set("appName","chengxuyuanA");configInfoUpdateWrapper.set("groupId", "groupA");configInfoUpdateWrapper.eq("id", 500L);this.baseMapper.update(configInfoUpdateWrapper);

                1.4. 查询

                列表查询

                        简单查询(简单的条件查询)

        // 查润groupId 为 5001的数据LambdaQueryWrapper<ConfigInfo> configInfoQueryWrapper = new LambdaQueryWrapper<>();configInfoQueryWrapper.eq(ConfigInfo::getGroupId, "5001");List<ConfigInfo> res = this.baseMapper.selectList(configInfoQueryWrapper);

                        复杂查询  (场景太多了,我就用一个包含 and, or, in ,between ,order by 的sql来表示一下用法)

        // select *// from config_info// where app_name like '%app%'//  and id between 1 and 50//  or (src_ip in ('1.0.1.1', '196.123.1.1', '0.0.0.0') and effect is not null)LambdaQueryWrapper<ConfigInfo> configInfoQueryWrapper = new LambdaQueryWrapper<>();configInfoQueryWrapper.like(ConfigInfo::getAppName, "app").between(ConfigInfo::getId, 1, 50);configInfoQueryWrapper.or(w->w.in(ConfigInfo::getSrcIp,srcips).isNotNull(ConfigInfo::getEffect));

                        分组聚合(其实这个一般不会用,考虑性能和优化,聚合的东西一般自己写sql)

        LambdaQueryWrapper<ConfigInfo> configInfoQueryWrapper = new LambdaQueryWrapper<>();configInfoQueryWrapper.groupBy(ConfigInfo::getGroupId);Long res = this.baseMapper.selectCount(configInfoQueryWrapper);

                分页查询

        Page page = new Page();page.setCurrent(1);page.setSize(10);LambdaQueryWrapper<ConfigInfo> configInfoQueryWrapper = new LambdaQueryWrapper<>();configInfoQueryWrapper.eq(ConfigInfo::getGroupId, "5001");IPage<ConfigInfo> pageData = this.page(page, configInfoQueryWrapper);

        3.自定义sql查询

                3.1.使用自定义sql

                和使用mybatis完全一样,这里不赘述了

                3.2.对自定义sql分页

                interface层

IPage<ConfigRation> selectUserPage(Page page, @Param("configration") ConfigRation configrationVo);

                同mybatis的正常使用,但是在第一个参数加上一个Page入参

        4.字段映射及一些注解使用技巧

                普通映射

                默认不需要注解,只要把数据库的字段的_去掉,换成小驼峰就行了

                如果需要对象属性名和数据库字段名称不同,可以用如下注解:

@TableField(value = "data_Source")
private String dataType;

                java对象的属性在数据库中不存在

@TableField(exist = false)
@Schema(description = "是否绑定告警通知规则,true是。false否")
private Boolean isBindNoticeRule;
                枚举映射

枚举注解@EnumValue,需要在枚举对象和java的实体类上都加:

public enum GenderEnum {MALE(0, "男"),FEMALE(1, "女");@EnumValueprivate final int code;private final String desc;GenderEnum(int code, String desc) {this.code = code;this.desc = desc;}
}
@TableName("user")
public class User {@TableIdprivate Long id;@TableField("gender")@EnumValueprivate GenderEnum gender;// 省略其他属性和方法
}
                逻辑删除注解

逻辑删除需要进行一些配置:

step1:增加配置

mybatis-plus:global-config:db-config:logic-delete-field: deleted # 全局逻辑删除字段名logic-delete-value: 1 # 逻辑已删除值logic-not-delete-value: 0 # 逻辑未删除值

step2:在实体类中使用 @TableLogic 注解

public class User {// 其他字段...@TableLogicprivate Integer deleted;
}
                多数据源注解

多数据源支持需要一个包  dynamic-datasource

step1:maven增加依赖

<dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId><version>${version}</version>
</dependency>

step2:数据源配置:

spring:datasource:dynamic:primary: masterstrict: falsedatasource:master:url: jdbc:mysql://xx.xx.xx.xx:3306/dynamicusername: rootpassword: 123456driver-class-name: com.mysql.jdbc.Driverslave_1:url: jdbc:mysql://xx.xx.xx.xx:3307/dynamicusername: rootpassword: 123456driver-class-name: com.mysql.jdbc.Driverslave_2:url: ENC(xxxxx)username: ENC(xxxxx)password: ENC(xxxxx)driver-class-name: com.mysql.jdbc.Driver

step3:使用 @DS 切换数据源

@Service
@DS("slave")
public class UserServiceImpl implements UserService {@Autowiredprivate JdbcTemplate jdbcTemplate;@Override@DS("slave_1")public List selectByCondition() {return jdbcTemplate.queryForList("select * from user where age >10");}
}
                字段忽略注解
@TableField(exist = false)
private String companyname;

四.常用插件

       1.插件介绍

        介绍两个插件DataPermissionInterceptor, PaginationInnerInterceptor

        DataPermissionInterceptor:

        我们在开发中,很多项目有多租户,多组织的需求,不同租户和组织能看到的数据内容不同。假如业务数据我们用一个字段tenent_id区分不同租户的数据,那么我们希望开发者在编码时候,不需要刻意关注这个字段,正常写业务逻辑就好,有一个统一的拦截器能帮助我们在调用数据库时候把 tenent_id = {user_tenent_id} 这段sql加到查询语句中,DataPermissionInterceptor就是帮我们做这个事情的。

        实际开发中,基本涉及到多组织,多租户的项目都会使用这个插件。如果大家在开发中发现使用了mybatis-plus的项目默认拼接了一些sql,可以尝试搜索DataPermissionInterceptor来找一下加的地方。

        PaginationInnerInterceptor

        分页插件, 对于单一数据库类型来说,都建议配置该值,避免每次分页都去抓取数据库类型,使用方法很简单,直接new PaginationInnerInterceptor(dataType就好)

        2.实战使用

step1: 注册拦截器,加入了上面介绍的俩插件

@Configuration
public class MybatisAutoConfiguration implements WebMvcConfigurer {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor(@Autowired(required = false) DataPermissionHandler dataPermissionHandler) {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();if (dataPermissionHandler != null) {interceptor.addInnerInterceptor(new DataPermissionInterceptor(dataPermissionHandler));}interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.POSTGRE_SQL));return interceptor;}
}

 step2:DataPermissionHandler编码

public class DataPermissionHandler extends MultiDataPermissionHandler {@Overridepublic Expression getSqlSegment(Table table, Expression where, String mappedStatementId) {// 在此处编写自定义数据权限逻辑try {String sqlSegment = "..."; // 数据权限相关的 SQL 片段return CCJSqlParserUtil.parseCondExpression(sqlSegment);} catch (JSQLParserException e) {e.printStackTrace();return null;}}
}

五.使用代码生成器

        关于代码生成器

        代码生成器在工作中其实很常用,所以我觉得不了解的道友还是需要了解一下。

        1.代码生成器配置

        我使用的mybatis-plus是3.5.7,低于3.5版本的话,可能略有不同

        step1:引入两个依赖包:

        <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>3.5.7</version></dependency><!-- freemarker模板 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-freemarker</artifactId><version>3.1.2</version></dependency>

       step2:创建一个java类,用来生成代码,我一般喜欢在项目中建一个dev文件夹,放一些开发工具

        结构如图:

代码:

public class CodeGenerator {public static void main(String[] args) {FastAutoGenerator.create("jdbc:mysql://192.168.**.**:3306/rui","root","******").globalConfig(builder -> builder.author("rui").outputDir(Paths.get(System.getProperty("user.dir")) +"/services/admin-server" +"/src/main/java").commentDate("yyyy-MM-dd")).packageConfig(builder -> builder.parent("com.rui").entity("entity").mapper("mapper").service("service").serviceImpl("service.impl").xml("mapper.xml")).strategyConfig(builder -> builder// 要生成代码的表名称,不加下面这行就是全库生成.addInclude("config_info") .entityBuilder().enableLombok()).templateEngine(new FreemarkerTemplateEngine()).execute();}}

        2.代码生成器使用

        直接右键执行即可,执行后就会在项目中生成对应文件。默认的模板controller,service中是没有方法的,可以自己配置一下模板,放一些和前端交互的CRUD。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/40042.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LT8668SXC 、LT8668SX-D 、LT8668SX三种芯片的相似与不同

一、LT8668SXC(支持eDP输出&#xff09; 定义:LT8668SXC配置在HDMI2.1标准下工作&#xff0c;最大数据速率为8Gbps。 LT8668SXC还可以配置为在Type-C输入或DP1.4a下工作&#xff0c;数据速率高达8.1Gbps。 eDP1.4b输出由8个数据通道组成&#xff0c;支持RBR (1.62Gbps)、HBR (2…

比较多种msvcr110.dll丢失的解决方法,哪一种更加方便?

当遇到“msvcr110.dll丢失”这种问题时&#xff0c;这通常意味着你的系统中缺少了Microsoft Visual C 2012 Redistributable的组件。下面我将详细介绍五种解决方法&#xff0c;并对比它们的优点。 一.多种msvcr110.dll丢失的解决方法 方法 1: 重新安装Microsoft Visual C 2012…

Redis持久化的三种方式(RDB、AOF和混合)

Redis持久化的三种方式(RDB、AOF和混合) 目录 Redis持久化的三种方式(RDB、AOF和混合)介绍RDB示例1.配置文件2.触发 RDB 快照保存3.验证 AOF示例1.配置文件2.校验 混合型持久化存储配置文件 介绍 Redis数据主要存储与内存中&#xff0c;因此如果服务器意外重启、宕机、崩溃&am…

乘积最大子数组

代码实现&#xff1a; 方法一&#xff1a;暴力法 方法二&#xff1a;动态规划 int maxProduct(int *nums, int numsSize) {long imax nums[0], imin nums[0], res nums[0];for (int i 1; i < numsSize; i) {if (nums[i] < 0) {int temp imax;imax imin;imin temp;…

学会python——用python编写一个电子时钟(python实例十七)

目录 1.认识Python 2.环境与工具 2.1 python环境 2.2 Visual Studio Code编译 3.电子时钟程序 3.1 代码构思 3.2代码实例 3.3运行结果 4.总结 1.认识Python Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。 Python 的设计具有很强的可读性…

今天的A股,让人惊愕了,2个耐人寻味的重要信号,有望迎来下一个超级风口!

今天的A股&#xff0c;让人惊愕了&#xff0c;你知道是为什么吗&#xff1f;盘面上出现2个耐人寻味的重要信号&#xff0c;有望迎来下一个超级风口&#xff01; 1、今天两市低开低走&#xff0c;但大消费劲头十足&#xff0c;连中免这样的大体量都涨停了&#xff0c;另外消费茅…

爬虫-网页基础

HTML 基本语法 HTML&#xff1a;Hyper Text Markup Language, 超文本标记语言&#xff0c;是计算机语言的一种&#xff0c;由元素构成。 p元素 <p>Web 真好玩&#xff01;</p> 由三大部分组成 开始标签&#xff1a;一对尖括号中间包裹这元素名称元素内容&#x…

SaaS运营:如何根据“客户漏斗”定制合作伙伴营销策略?

将你的合作伙伴营销策略与你的客户漏斗模型相结合&#xff0c;可以显著提升你的营销效果。通过瞄准客户旅程中的每一个阶段&#xff0c;你可以增加客户参与度并推动转化&#xff0c;从而将你的促销活动提升到新的高度——这仅仅是一个以数据为支撑的方法。 为了探讨如何在漏斗…

数据结构 - C/C++ - 树

公开视频 -> 链接点击跳转公开课程博客首页 -> 链接点击跳转博客主页 目录 树的概念 结构特性 树的样式 树的存储 树的遍历 节点增删 二叉搜索树 平衡二叉树 树的概念 二叉树是树形结构&#xff0c;是一种非线性结构。 非线性结构&#xff1a;在二叉树中&#x…

LLM应用:传统NLP任务

LLM出来以后&#xff0c;知乎上就出现了“传统NLP已死”的言论&#xff0c;但是传统NLP真的就被扔进历史的垃圾桶了吗&#xff1f; 其实&#xff0c;尽管LLM具有出色的通用能力&#xff0c;但仍然无法有效应对低资源领域的自然语言处理任务&#xff0c;如小语种翻译。为了更好地…

golang——Gin框架及路由介绍

一. 框架介绍 Gin是一个轻量级的Go语言Web框架&#xff0c;它具有高性能和简洁的设计。由于其快速的路由匹配和处理性能&#xff0c;Gin成为Go语言中最受欢迎的Web框架之一。 特点&#xff1a; 快速和轻量&#xff1a;Gin框架的设计注重性能和效率&#xff0c;采用了一些优化措…

第二十一章 网络编程

​ 一、网络的相关概念 1. 网络通信 &#xff08;1&#xff09;网络通信&#xff1a;将 数据 通过网络从一台设备传输到另一台设备 &#xff08;2&#xff09;java.net 包下提供了一系列的类或接口&#xff0c;完成网络通信 2. 网络 概念&#xff1a;两台或多台设备通过一定…

轻松省电!教你苹果手机自动调节亮度怎么设置

在日常使用手机的过程中&#xff0c;屏幕亮度是影响电池续航的关键因素之一。苹果手机提供的自动调节亮度功能&#xff0c;可以根据环境光线自动调整屏幕亮度&#xff0c;从而提供最佳的视觉体验并有效延长电池使用时间。想知道苹果手机自动调节亮度怎么设置吗&#xff1f; 本…

工厂自动化相关设备工业一体机起到什么作用?

在当今的制造业领域&#xff0c;工厂自动化已成为提高生产效率、保证产品质量和降低成本的关键。在这一进程中&#xff0c;工业一体机作为一种重要的设备&#xff0c;发挥着不可或缺的作用。 工业一体机是自动化生产线上的控制中心。它能够整合和处理来自各个传感器、执行器和其…

02:vim的使用和权限管控

vim的使用 1、vim基础使用1.1、vim pathname 2、vim高级用法2.1、查找2.2、设置显示行号2.3、快速切换行2.4、 行删除2.5、行复制粘贴 3、权限管理3.1、普通用户和特权用户3.2、文件权限表示 vim是Linux中的一种编辑器&#xff0c;类似于window中的记事本&#xff0c;可以对创建…

产业链协同,共谋产业新高度

国际数字影像产业园始终秉承“产业协同&#xff0c;共谋发展”的核心理念&#xff0c;致力于通过深化产业链上下游的紧密合作&#xff0c;推动数字影像产业的持续繁荣。 一、产业协同的具体实践 1、产业链整合&#xff1a;园区积极整合数字影像产业的上下游资源&#xff0c;形…

Prometheus 监控服务器

Prometheus概述 组件化设置&#xff1a;nginx ,ceph , Prometheus 部署Prometheus服务器 配置时间 安装Prometheus服务器 访问web页面&#xff1a;http://192.168.88.5:9090/ 添加被监控端 监控方式&#xff1a; 拉取&#xff1a;pull。监控端联系被监控端&#xff0c;采集数…

Apache APISIX遇到504超时的解决办法

说明&#xff1a; Apache APISIX版本&#xff1a;v3.9.0Apache APISIX Dashboard版本&#xff1a;v3.0.1 当使用Apache APISIX开源网关&#xff0c;通过接口上传或下载大文件等时&#xff0c;出现如下“504 Gateway Time-out”错误信息&#xff0c;它表示网关或代理服务器未能…

springboot系列六: springboot底层机制实现 下

实现SpringBoot底层机制[Tomcat启动分析 Spring容器初始化 Tomcat如何关联Spring容器] 实现任务阶段1-创建Tomcat, 并启动&#x1f966;说明&#xff1a;创建Tomcat, 并启动&#x1f966;分析代码实现&#x1f966;完成测试 实现任务阶段2-创建Spring容器&#x1f966;说明&a…

H5项目使用vant组件的手机号校验

前言&#xff1a; 在开发h5项目的时候遇到手机号校验&#xff0c;原本想采用后台管理那种校验方式&#xff08;validator函数写校验手机号逻辑&#xff09;猛然间发现&#xff0c;可以在使用行内使用pattern属性 用法如下 <van-form submit"onSubmit"><van-…