MyBatis-Plus

news2024/11/15 19:31:52

MyBatis-Plus

1、简介

MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

润物无声

只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑。

效率至上

只需简单配置,即可快速进行 CRUD 操作,从而节省大量时间。

丰富功能

热加载、代码生成、分页、性能分析等功能一应俱全。

2、创建并初始化数据库

2.1创建数据库

mybatis_plus

2.2创建 User 表

其对应的数据库 Schema 脚本如下:

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)
);

其对应的数据库 Data 脚本如下:

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');

3、确认idea配置

3.1 打开配置

3.2 Java编译器

3.3 项目和文件的编码

3.4 Maven配置

4、创建项目

4.1 初始化工程

使用 Spring Initializr 快速初始化一个 Spring Boot 工程

Group:com.aqrlmy

Artifact:mybatis_plus

版本:2.2.1.RELEASE

4.2 引入依赖

注意:引入 MyBatis-Plus 之后请不要再次引入 MyBatis,以避免因版本差异导致的问题。

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.1</version>
</dependency>

<!--mysql依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--lombok用来简化实体类-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>

4.3idea中安装lombok插件

4.3.1 idea2019版本

4.3.2 idea2018版本

5、编写代码

5.1 配置

在 application.properties 配置文件中添加 MySQL 数据库的相关配置:

spring boot 2.0(内置jdbc5驱动)

#mysql数据库连接
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis_plus?characterEncoding=utf-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=root

spring boot 2.1及以上(内置jdbc8驱动)

注意:driver和url的变化

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis_plus?serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=root

注意:

1、这里的 url 使用了 ?serverTimezone=GMT%2B8 后缀,因为8.0版本的jdbc驱动需要添加这个后缀,否则运行测试用例报告如下错误:

java.sql.SQLException: The server time zone value ‘Öйú±ê׼ʱ¼ä’ is unrecognized or represents more

2、这里的 driver-class-name 使用了 com.mysql.cj.jdbc.Driver ,在 jdbc 8 中 建议使用这个驱动,否则运行测试用例的时候会有 WARN 信息

5.2 启动类

在 Spring Boot 启动类中添加 @MapperScan 注解,扫描 Mapper 文件夹

@SpringBootApplication
@MapperScan("com.aqrlmy.demomptest.mapper")
public class DemomptestApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemomptestApplication.class, args);
    }

}

5.3 添加实体

创建包 entity 编写实体类 User.java(此处使用了 Lombok 简化代码)

@Data
public class User {
    private Long id;
    private String name;
    private Integer age;
    private String email;
}

查看编译结果

5.4 添加mapper

创建包 mapper 编写Mapper 接口: UserMapper.java

@Repository
public interface UserMapper extends BaseMapper<User> {
}

5.5 测试

添加测试类,进行功能测试:

@SpringBootTest
class DemomptestApplicationTests {

    @Autowired
    private UserMapper userMapper;

    @Test
    public void findAll() {
        List<User> users = userMapper.selectList(null);
        System.out.println(users);
    }
}

注意:

IDEA在 userMapper 处报错,因为找不到注入的对象,因为类是动态创建的,但是程序可以正确的执行。

为了避免报错,可以在 dao 层 的接口上添加 @Repository 注

通过以上几个简单的步骤,我们就实现了 User 表的 CRUD 功能,甚至连 XML 文件都不用编写!

查看控制台输出:

5.6 查看sql输出日志

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

二、主键策略

1、插入操作

//添加
@Test
public void testAdd() {
    User user = new User();
    user.setName("lucy");
    user.setAge(20);
    user.setEmail("1243@qq.com");
    int insert = userMapper.insert(user);
    System.out.println(insert);
}

注意:数据库插入id值默认为:全局唯一id

2、MP的主键策略

2.1 ASSIGN_ID

MyBatis-Plus默认的主键策略是:ASSIGN_ID (使用了雪花算法)

@TableId(type = IdType.ASSIGN_ID)
private String id;

雪花算法:分布式ID生成器

雪花算法是由Twitter公布的分布式主键生成算法,它能够保证不同表的主键的不重复性,以及相同表的主键的有序性。

核心思想:

长度共64bit(一个long型)。

首先是一个符号位,1bit标识,由于long基本类型在Java中是带符号的,最高位是符号位,正数是0,负数是1,所以id一般是正数,最高位是0。

41bit时间截(毫秒级),存储的是时间截的差值(当前时间截 - 开始时间截),结果约等于69.73年。

10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID,可以部署在1024个节点)。

12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID)。

优点:整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞,并且效率较高。

2.2 AUTO 自增策略

需要在创建数据表的时候设置主键自增

实体字段中配置 @TableId(type = IdType.AUTO)

@TableId(type = IdType.AUTO)
private Long id;

要想影响所有实体的配置,可以设置全局主键配置

#全局设置主键生成策略
mybatis-plus.global-config.db-config.id-type=auto

三、自动填充和乐观锁

1、更新操作

注意:update时生成的sql自动是动态sql:UPDATE user SET age=? WHERE id=?

//修改
@Test
public void testUpdate() {
    User user = new User();
    user.setId(1340868235401764865L);
    user.setName("lucymary");
    int count = userMapper.updateById(user);
    System.out.println(count);
}

2、自动填充

需求描述:

项目中经常会遇到一些数据,每次都使用相同的方式填充,例如记录的创建时间,更新时间等。

我们可以使用MyBatis Plus的自动填充功能,完成这些字段的赋值工作

2.1数据库修改

在User表中添加datetime类型的新的字段 create_time、update_time

2.2实体类修改

实体上增加字段并添加自动填充注解

@TableField(fill = FieldFill.INSERT)
private Date createTime;  //create_time

@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime; //update_time

2.3实现元对象处理器接口

注意:不要忘记添加 @Component 注解

@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    //mp执行添加操作,这个方法执行
    @Override
    public void insertFill(MetaObject metaObject) {
        this.setFieldValByName("createTime",new Date(),metaObject);
        this.setFieldValByName("updateTime",new Date(),metaObject);
    }

    //mp执行修改操作,这个方法执行
    @Override
    public void updateFill(MetaObject metaObject) {
        this.setFieldValByName("updateTime",new Date(),metaObject);
    }
}

3、乐观锁

3.1场景

**主要适用场景:**当要更新一条记录的时候,希望这条记录没有被别人更新,也就是说实现线程安全的数据更新

乐观锁实现方式:

取出记录时,获取当前version

更新时,带上这个version

执行更新时, set version = newVersion where version = oldVersion

如果version不对,就更新失败

接下来介绍如何在Mybatis-Plus项目中,使用乐观锁:

4、乐观锁实现流程

4.1修改实体类

添加 @Version 注解

@Version
private Integer version;

4.2创建配置文件

创建包config,创建文件MybatisPlusConfig.java

此时可以删除主类中的 @MapperScan 扫描注解

@Configuration
@MapperScan("com.aqrlmy.demomptest.mapper")
public class MpConfig {
    /**
     * 乐观锁插件
     */
    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor() {
        return new OptimisticLockerInterceptor();
    }
}

4.3注册乐观锁插件

在 MybatisPlusConfig 中注册 Bean

/**
* 乐观锁插件
*/
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}

四、查询

1、查询

1.1通过多个id批量查询

完成了动态sql的foreach的功能

//多个id批量查询
@Test
public void testSelect1() {
    List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));
    System.out.println(users);
}

1.2简单的条件查询

通过map封装查询条件

注意:map中的key对应数据库中的列名。如:数据库user_id,实体类是userId,这时map的key需要填写user_id

//简单条件查询
@Test
public void testSelect2() {
    Map<String, Object> columnMap = new HashMap<>();
    columnMap.put("name","Jack");
    columnMap.put("age",20);
    List<User> users = userMapper.selectByMap(columnMap);
    System.out.println(users);
}

2、分页

2.1分页插件

MyBatis Plus自带分页插件,只要简单的配置即可实现分页功能

2.1.1添加分页插件

配置类中添加@Bean配置

/**
 * 分页插件
 */
@Bean
public PaginationInterceptor paginationInterceptor() {
    return new PaginationInterceptor();
}

2.1.2测试selectPage分页

测试:最终通过page对象获取相关数据

//分页查询
@Test
public void testSelectPage() {
    Page<User> page = new Page(1,3);
    Page<User> userPage = userMapper.selectPage(page, null);
    //返回对象得到分页所有数据
    long pages = userPage.getPages(); //总页数
    long current = userPage.getCurrent(); //当前页
    List<User> records = userPage.getRecords(); //查询数据集合
    long total = userPage.getTotal(); //总记录数
    boolean hasNext = userPage.hasNext();  //下一页
    boolean hasPrevious = userPage.hasPrevious(); //上一页

    System.out.println(pages);
    System.out.println(current);
    System.out.println(records);
    System.out.println(total);
    System.out.println(hasNext);
    System.out.println(hasPrevious);
}

2.2测试selectMapsPage分页

当指定了特定的查询列时,希望分页结果列表只返回被查询的列,而不是很多null值

测试selectMapsPage分页:结果集是Map

@Test
public void testSelectMapsPage() {
//Page不需要泛型
Page<Map<String, Object>> page = newPage<>(1, 5);
Page<Map<String, Object>> pageParam = userMapper.selectMapsPage(page, null);
List<Map<String, Object>> records = pageParam.getRecords();
records.forEach(System.out::println);
System.out.println(pageParam.getCurrent());
System.out.println(pageParam.getPages());
System.out.println(pageParam.getSize());
System.out.println(pageParam.getTotal());
System.out.println(pageParam.hasNext());
System.out.println(pageParam.hasPrevious());
}

五、删除与逻辑删除

1、删除

1.1根据id删除记录

@Test
public void testDeleteById(){
    int result = userMapper.deleteById(5L);
system.out.println(result);
}

1.2批量删除

@Test
public void testDeleteBatchIds() {
    int result = userMapper.deleteBatchIds(Arrays.asList(8, 9, 10));
system.out.println(result);
}

1.3简单条件删除

@Test
public void testDeleteByMap() {
HashMap<String, Object> map = new HashMap<>();
map.put("name", "Helen");
map.put("age", 18);
    int result = userMapper.deleteByMap(map);
system.out.println(result);
}

2、逻辑删除

2.1物理删除和逻辑删除

物理删除:真实删除,将对应数据从数据库中删除,之后查询不到此条被删除数据

逻辑删除:假删除,将对应数据中代表是否被删除字段状态修改为“被删除状态”,之后在数据库中仍旧能看到此条数据记录

逻辑删除的使用场景:

可以进行数据恢复

有关联数据,不便删除

2.2 逻辑删除实现流程

2.2.1数据库修改

添加 deleted字段

ALTERTABLE `user` ADD COLUMN `deleted` boolean DEFAULT false

2.2.2实体类修改

添加deleted 字段,并加上 @TableLogic 注解

@TableLogic
private Integer deleted;

2.2.3配置(可选)

application.properties 加入以下配置,此为默认值,如果你的默认值和mp默认的一样,该配置可无

mybatis-plus.global-config.db-config.logic-delete-value=1
mybatis-plus.global-config.db-config.logic-not-delete-value=0

2.2.4 测试

测试后发现,数据并没有被删除,deleted字段的值由0变成了1

测试后分析打印的sql语句,是一条update

注意:被删除前,数据的deleted 字段的值必须是 0,才能被选取出来执行逻辑删除的操作

@Test
public void testLogicDelete() {
    int result = userMapper.deleteById(1L);
system.out.println(result);
}

2.2.5测试逻辑删除后的查询

MyBatis Plus中查询操作也会自动添加逻辑删除字段的判断

@Test
public void testLogicDeleteSelect() {
List<User> users = userMapper.selectList(null);
users.forEach(System.out::println);
}

六、条件构造器和常用接口

wapper介绍

Wrapper : 条件构造抽象类,最顶端父类

AbstractWrapper : 用于查询条件封装,生成 sql 的 where 条件

QueryWrapper : 查询条件封装

UpdateWrapper : Update 条件封装

AbstractLambdaWrapper : 使用Lambda 语法

LambdaQueryWrapper :用于Lambda语法使用的查询Wrapper

LambdaUpdateWrapper : Lambda 更新封装Wrapper

@SpringBootTest
publicclassQueryWrapperTests {

@Autowired
privateUserMapperuserMapper;
}

2、测试用例

2.1 ge、gt、le、lt、isNull、isNotNull

@Test
public void testQuery() {
QueryWrapper<User>queryWrapper = newQueryWrapper<>();
queryWrapper
        .isNull("name")
        .ge("age", 12)
        .isNotNull("email");
    int result = userMapper.delete(queryWrapper);
System.out.println("delete return count = " + result);
}

2.2 eq、ne

注意:seletOne()返回的是一条实体记录,当出现多条时会报错

@Test
public void testSelectOne() {
QueryWrapper<User>queryWrapper = newQueryWrapper<>();
queryWrapper.eq("name", "Tom");
Useruser = userMapper.selectOne(queryWrapper);//只能返回一条记录,多余一条则抛出异常
System.out.println(user);
}

2.3 between、notBetween

包含大小边界

@Test
public void testSelectCount() {
QueryWrapper<User>queryWrapper = newQueryWrapper<>();
queryWrapper.between("age", 20, 30);
    Integer count = userMapper.selectCount(queryWrapper); //返回数据数量
System.out.println(count);
}

2.4 like、notLike、likeLeft、likeRight

selectMaps()返回Map集合列表,通常配合select()使用

@Test
public void testSelectMaps() {
QueryWrapper<User>queryWrapper = newQueryWrapper<>();
queryWrapper
        .select("name", "age")
        .like("name", "e")
        .likeRight("email", "5");
List<Map<String, Object>>maps = userMapper.selectMaps(queryWrapper);//返回值是Map列表
maps.forEach(System.out::println);
}

2.5 orderBy、orderByDesc、orderByAsc

@Test
public void testSelectListOrderBy() {
QueryWrapper<User>queryWrapper = newQueryWrapper<>();
queryWrapper.orderByDesc("age", "id");
List<User>users = userMapper.selectList(queryWrapper);
users.forEach(System.out::println);
}

查询方式

查询方式说明
setSqlSelect设置 SELECT 查询字段
whereWHERE 语句,拼接 + WHERE 条件
andAND 语句,拼接 + AND 字段=值
andNewAND 语句,拼接 + AND (字段=值)
orOR 语句,拼接 + OR 字段=值
orNewOR 语句,拼接 + OR (字段=值)
eq等于=
allEq基于 map 内容等于=
ne不等于<>
gt大于>
ge大于等于>=
lt小于<
le小于等于<=
like模糊查询 LIKE
notLike模糊查询 NOT LIKE
inIN 查询
notInNOT IN 查询
isNullNULL 值查询
isNotNullIS NOT NULL
groupBy分组 GROUP BY
havingHAVING 关键词
orderBy排序 ORDER BY
orderAscASC 排序 ORDER BY
orderDescDESC 排序 ORDER BY
existsEXISTS 条件语句
notExistsNOT EXISTS 条件语句
betweenBETWEEN 条件语句
notBetweenNOT BETWEEN 条件语句
addFilter自由拼接 SQL
last拼接在最后,例如:last(“LIMIT 1”)

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

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

相关文章

数据结构学习笔记(Ⅷ):排序

目录 1 排序基础 1.1 排序的基本概念 2 排序算法 2.1 插入排序 1.思想 2.实现 3.效率分析 4.优化 2.2 希尔排序 1.定义 2.实现 3.效率分析 3 交换排序 3.1 冒泡排序 1.定义 2.实现 3.效率分析 3.2 快速排序 1.算法思想 2.实现 3.效率分析 4 选择排序 4.…

第4章 SpringBoot与Web应用

文章目录第4章 SpringBoot与Web应用4.1 配置Tomcat运行4.2 https安全访问4.3 数据验证4.4 配置错误页4.5 全局异常处理4.6 文件上传4.6.1 基础上传4.6.2 上传文件限制4.6.3 上传多个文件4.7 拦截器4.8 AOP拦截器4.9 本章小结4.9 本章小结第4章 SpringBoot与Web应…

[附源码]计算机毕业设计病人跟踪治疗信息管理系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Linux系统移植二:生成fsbl引导文件并制作BOOT.bin

前情提要 对于ZYNQ而言&#xff0c;在引导过程中&#xff0c;先运行FSBL来设置PS&#xff0c;然后运行U-Boot用于加载Linux内核映像并引导Linux Linux系统移植一&#xff1a;移植U-BOOT 添加自己的板子并编译&#xff08;非petalinux版&#xff09; 一文中已成功生成了u-boot…

基于MPPT的PV光伏发电simulink建模和仿真

目录 1.算法描述 2.matlab算法仿真效果 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 MPPT控制器的全称是“最大功率点跟踪”&#xff08;Maximum Power Point Tracking&#xff09;太阳能控制器&#xff0c;是传统太阳能充放电控制器的升级换代产品。MPPT控制器能够实时侦测…

ManiSkill 2022机器学习顶会ICLR上的世界顶尖机械臂大赛赛题解读,演示轨迹转换,点云查看

1.赛事相关信息 点击查看 2.赛题分析 软体对GPU要求较高&#xff0c;环境配置复杂&#xff0c;选择刚体环境先以模仿学习/强化学习的刚体环境为基础&#xff0c;后期再考虑无限制刚体环境部分任务&#xff08;如将物块移动到指定位置&#xff09;&#xff0c;存在相机之外的…

Day818.电商系统的分布式事务调优 -Java 性能调优实战

电商系统的分布式事务调优 Hi&#xff0c;我是阿昌&#xff0c;今天学习记录的是关于电商系统的分布式事务调优。 一个线上事故&#xff0c;在一次 DBA 完成单台数据库线上补丁后&#xff0c;系统偶尔会出现异常报警&#xff0c;开发工程师很快就定位到了数据库异常问题。 具…

SQL通用语法与DDL操作

学习笔记 sql通用语法 1 sql语句可以单行或多行书写&#xff0c;以分号结尾&#xff1b; 2 sql语句可以使用空格/缩进来增强语句的可读性&#xff1b; 3 mysql数据库的sql语句不区分大小写 4 单行注释&#xff1a;-- 内容 或 # 内容 多行注释&#xff1a; /* 内容 */ sql语句…

【地图之vue-baidu-map】点击获取坐标(点Marker)、坐标集(多边形polygon)

点击获取坐标&#xff08;点Marker&#xff09; 官网链接&#xff1a;Vue Baidu Map 需求 1.点击某点设置该点为中心点 2.获取点的经纬度 3.确定选取成功&#xff0c;取消就不赋值。 实现步骤 第一步&#xff1a;设置打开弹窗的地方 <el-button click"clickAdd…

c# .net 树莓派/香橙派用到物联网包Iot.Device.bindings 支持设备说明文档

c# .net 树莓派&#xff08;进口&#xff0c;贵&#xff09;/香橙派&#xff08;国产&#xff0c;功能相同&#xff0c;性价比高&#xff09;用到物联网包Iot.Device.bindings 支持设备说明文档 我们c# .net 开发树莓派/香橙派都需要用到Iot.Device.bindings和System.Device.G…

阿里巴巴 Github 星标 57.9KJava 面试突击汇总(全彩版)首次公开

现在互联网大环境不好&#xff0c;互联网公司纷纷裁员并缩减 HC&#xff0c;更多程序员去竞争更少的就业岗位&#xff0c;整的 IT 行业越来越卷。身为 Java 程序员的我们就更不用说了&#xff0c;上班 8 小时需要做好本职工作&#xff0c;下班后还要不断提升技能、技术栈&#…

命令注入漏洞解析

漏洞简介 Atlassian Bitbucket Server 和 Data Center 是 Atlassian 推出的一款现代化代码协作平台&#xff0c;支持代码审查、分支权限管理、CICD 等功能。 受影响的Bitbucket Server 和 Data Center版本存在使用环境变量的命令注入漏洞&#xff0c;具有控制其用户名权限的攻…

代码随想录刷题记录day34 动态规划理论基础+斐波那契数+爬楼梯+使用最小花费爬楼梯

代码随想录刷题记录day34 动态规划理论基础斐波那契数爬楼梯使用最小花费爬楼梯 动态规划理论基础 解决的问题 由前一个状态决定了后一个的状态&#xff0c;可以用动态规划来解决。贪心是没有状态推导的。 解题步骤 确定dp数组&#xff08;dp table&#xff09;以及下标的…

一键集成 SQL 审核到你的 GitLab 和 GitHub CI/CD

本文以 GitLab 为例&#xff0c;GitHub 方式类似。 操作步骤 事先准备 开启 Bytebase 团队版&#xff08;从 v1.8.0 开始&#xff0c;你可以直接开启 14 天的团队版免费试用&#xff09;。 为你的 Bytebase workspace 和项目开启 VCS 工作流&#xff1a;https://www.bytebas…

基于钉钉通讯录,同步构建本地LDAP服务

上一篇《利用飞书通讯录同步搭建本地LDAP》方案发出后&#xff0c;引起不少企业 IT 人员共鸣。本次&#xff0c;宁盾针对使用了钉钉社交应用的企业推出基于钉钉通讯录&#xff08;组织架构和用户信息&#xff09;同步搭建本地 LDAP的方案。 钉钉已经成为很多企业日常处理工作的…

基于FPGA的智能小车系统

目 录 前 言 1 第1章 系统总体方案设计 4 1.1 系统任务描述 4 1.2 控制系统要求 4 1.3 方案设计与论证 4 1.3.1 小车载体选择 4 1.3.2 主控制器选择 5 1.3.3 传感器选择 5 1.3.4 电机驱动选择 6 1.3.5 稳压电源选择 7 1.3.6 智能小车系统最终方案 7 1.4 系统总体设计 8 1.4.…

【Java开发】 Spring 07 :Spring AOP 实践详解(通过 AOP 打印数据访问层)

AOP 指是面向切面编程&#xff08;通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术&#xff09;&#xff0c;利用AOP可以对业务逻辑的各个部分进行隔离&#xff0c;从而使得业务逻辑各部分之间的耦合度降低&#xff0c;提高程序的可重用性&#xff0c;同时提…

SpringBoot 3.0 新特性,内置声明式 HTTP 客户端

http interface 从 Spring 6 和 Spring Boot 3 开始&#xff0c;Spring 框架支持将远程 HTTP 服务代理成带有特定注解的 Java http interface。类似的库&#xff0c;如 OpenFeign 和 Retrofit 仍然可以使用&#xff0c;但 http interface 为 Spring 框架添加内置支持。 什么是…

RabbitMQ之集群方案原理

对于无状态应用&#xff08;如普通的微服务&#xff09;很容易实现负载均衡、高可用集群。而对于有状态的系统&#xff08;如数据库等&#xff09;就比较复杂。 1、业界实践 主备模式&#xff1a;单活&#xff0c;容量对等&#xff0c;可以实现故障转移。使用独立存储时需要借…

【Matplotlib绘制图像大全】(二十五):Matplotlib使用figure()添加画布

前言 大家好,我是阿光。 本专栏整理了《Matplotlib绘制图像大全》,内包含了各种常见的绘图方法,以及Matplotlib各种内置函数的使用方法,帮助我们快速便捷的绘制出数据图像。 正在更新中~ ✨ 🚨 我的项目环境: 平台:Windows10语言环境:python3.7编译器:PyCharmMatp…