分库分表、读写分离--ShardingJDBC

1. 项目准备

1.1 建立数据库表

建立user_manage数据库,在该库中建立1张表app_user用来做分库前的测试,另外建12张按月份命名的表app_user_2024XX用来做分库。

CREATE DATABASE IF NOT EXISTS user_manage
CHARACTER SET utf8
COLLATE utf8_general_ci;USE user_manage;CREATE TABLE `app_user` (`id` INT AUTO_INCREMENT PRIMARY KEY,`name` VARCHAR(255) NOT NULL,`age` INT(10) NOT NULL,`sex` CHAR(1) NOT NULL,`address` VARCHAR(100) DEFAULT NULL,`phone` VARCHAR(20) DEFAULT NULL,`create_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,`update_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,`deleted` TINYINT(1) DEFAULT 0
) ENGINE = INNODB DEFAULT CHARSET = UTF8;CREATE TABLE `app_user_202401` (`id` INT AUTO_INCREMENT PRIMARY KEY,`name` VARCHAR(255) NOT NULL,`age` INT(10) NOT NULL,`sex` CHAR(1) NOT NULL,`address` VARCHAR(100) DEFAULT NULL,`phone` VARCHAR(20) DEFAULT NULL,`create_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,`update_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,`deleted` TINYINT(1) DEFAULT 0
) ENGINE = INNODB DEFAULT CHARSET = UTF8;CREATE TABLE `app_user_202402` (`id` INT AUTO_INCREMENT PRIMARY KEY,`name` VARCHAR(255) NOT NULL,`age` INT(10) NOT NULL,`sex` CHAR(1) NOT NULL,`address` VARCHAR(100) DEFAULT NULL,`phone` VARCHAR(20) DEFAULT NULL,`create_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,`update_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,`deleted` TINYINT(1) DEFAULT 0
) ENGINE = INNODB DEFAULT CHARSET = UTF8;CREATE TABLE `app_user_202403` (`id` INT AUTO_INCREMENT PRIMARY KEY,`name` VARCHAR(255) NOT NULL,`age` INT(10) NOT NULL,`sex` CHAR(1) NOT NULL,`address` VARCHAR(100) DEFAULT NULL,`phone` VARCHAR(20) DEFAULT NULL,`create_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,`update_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,`deleted` TINYINT(1) DEFAULT 0
) ENGINE = INNODB DEFAULT CHARSET = UTF8;CREATE TABLE `app_user_202404` (`id` INT AUTO_INCREMENT PRIMARY KEY,`name` VARCHAR(255) NOT NULL,`age` INT(10) NOT NULL,`sex` CHAR(1) NOT NULL,`address` VARCHAR(100) DEFAULT NULL,`phone` VARCHAR(20) DEFAULT NULL,`create_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,`update_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,`deleted` TINYINT(1) DEFAULT 0
) ENGINE = INNODB DEFAULT CHARSET = UTF8;CREATE TABLE `app_user_202405` (`id` INT AUTO_INCREMENT PRIMARY KEY,`name` VARCHAR(255) NOT NULL,`age` INT(10) NOT NULL,`sex` CHAR(1) NOT NULL,`address` VARCHAR(100) DEFAULT NULL,`phone` VARCHAR(20) DEFAULT NULL,`create_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,`update_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,`deleted` TINYINT(1) DEFAULT 0
) ENGINE = INNODB DEFAULT CHARSET = UTF8;CREATE TABLE `app_user_202406` (`id` INT AUTO_INCREMENT PRIMARY KEY,`name` VARCHAR(255) NOT NULL,`age` INT(10) NOT NULL,`sex` CHAR(1) NOT NULL,`address` VARCHAR(100) DEFAULT NULL,`phone` VARCHAR(20) DEFAULT NULL,`create_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,`update_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,`deleted` TINYINT(1) DEFAULT 0
) ENGINE = INNODB DEFAULT CHARSET = UTF8;CREATE TABLE `app_user_202407` (`id` INT AUTO_INCREMENT PRIMARY KEY,`name` VARCHAR(255) NOT NULL,`age` INT(10) NOT NULL,`sex` CHAR(1) NOT NULL,`address` VARCHAR(100) DEFAULT NULL,`phone` VARCHAR(20) DEFAULT NULL,`create_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,`update_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,`deleted` TINYINT(1) DEFAULT 0
) ENGINE = INNODB DEFAULT CHARSET = UTF8;CREATE TABLE `app_user_202408` (`id` INT AUTO_INCREMENT PRIMARY KEY,`name` VARCHAR(255) NOT NULL,`age` INT(10) NOT NULL,`sex` CHAR(1) NOT NULL,`address` VARCHAR(100) DEFAULT NULL,`phone` VARCHAR(20) DEFAULT NULL,`create_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,`update_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,`deleted` TINYINT(1) DEFAULT 0
) ENGINE = INNODB DEFAULT CHARSET = UTF8;CREATE TABLE `app_user_202409` (`id` INT AUTO_INCREMENT PRIMARY KEY,`name` VARCHAR(255) NOT NULL,`age` INT(10) NOT NULL,`sex` CHAR(1) NOT NULL,`address` VARCHAR(100) DEFAULT NULL,`phone` VARCHAR(20) DEFAULT NULL,`create_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,`update_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,`deleted` TINYINT(1) DEFAULT 0
) ENGINE = INNODB DEFAULT CHARSET = UTF8;CREATE TABLE `app_user_202410` (`id` INT AUTO_INCREMENT PRIMARY KEY,`name` VARCHAR(255) NOT NULL,`age` INT(10) NOT NULL,`sex` CHAR(1) NOT NULL,`address` VARCHAR(100) DEFAULT NULL,`phone` VARCHAR(20) DEFAULT NULL,`create_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,`update_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,`deleted` TINYINT(1) DEFAULT 0
) ENGINE = INNODB DEFAULT CHARSET = UTF8;CREATE TABLE `app_user_202411` (`id` INT AUTO_INCREMENT PRIMARY KEY,`name` VARCHAR(255) NOT NULL,`age` INT(10) NOT NULL,`sex` CHAR(1) NOT NULL,`address` VARCHAR(100) DEFAULT NULL,`phone` VARCHAR(20) DEFAULT NULL,`create_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,`update_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,`deleted` TINYINT(1) DEFAULT 0
) ENGINE = INNODB DEFAULT CHARSET = UTF8;CREATE TABLE `app_user_202412` (`id` INT AUTO_INCREMENT PRIMARY KEY,`name` VARCHAR(255) NOT NULL,`age` INT(10) NOT NULL,`sex` CHAR(1) NOT NULL,`address` VARCHAR(100) DEFAULT NULL,`phone` VARCHAR(20) DEFAULT NULL,`create_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,`update_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,`deleted` TINYINT(1) DEFAULT 0
) ENGINE = INNODB DEFAULT CHARSET = UTF8;

在这里插入图片描述

1.2 项目搭建-集成mybatisplus

目录结构
在这里插入图片描述
pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.gzdemo</groupId><artifactId>shardingjdbc-demo</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><lombok.version>1.18.8</lombok.version><mysql.version>5.1.46</mysql.version><mybatis.version>3.5.1</mybatis.version><mybatis.plus.version>3.4.1</mybatis.plus.version></properties><!-- 继承Spring boot --><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.5.RELEASE</version></parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!-- Mysql 数据库 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>${mysql.version}</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>${mybatis.plus.version}</version></dependency></dependencies>
</project>

application.yml

server:port: 8080spring:datasource:driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://192.168.200.131:3306/user_manage?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=falseusername: rootpassword: root
# 设置Mapper接口所对应的XML文件位置,如果你在Mapper接口中有自定义方法,需要进行该配置
mybatis-plus:mapper-locations: classpath*:mapper/*.xml# 设置别名包扫描路径,通过该属性可以给包中的类注册别名type-aliases-package: com.gzdemo.shardingdemo.pojo

AppUser

import lombok.Data;
import java.util.Date;@Data
//默认映射到app_user表
public class AppUser {private Integer id;private String name;private Integer age;private String sex;private String address;private String phone;private Date create_time;private Date update_time;private Short deleted;
}

AppUserService

public interface AppUserService extends IService<AppUser> {boolean addOne(AppUser appUser);
}

AppUserServiceImpl

@Service
public class AppUserServiceImpl extends ServiceImpl<AppUserMapper, AppUser> implements AppUserService {@AutowiredAppUserMapper appUserMapper;@Overridepublic boolean addOne(AppUser appUser){return appUserMapper.insertOne(appUser);}
}

AppUserMapper

@Mapper
public interface AppUserMapper extends BaseMapper<AppUser> {boolean insertOne(@Param("user") AppUser appUser);
}

AppUserMapper.xml

<?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.gzdemo.shardingdemo.dao.AppUserMapper"><insert id="insertOne" parameterType="com.gzdemo.shardingdemo.pojo.AppUser">insert into `app_user`(id,name,age,sex,address,phone,create_time,update_time,deleted)values(#{user.id},#{user.name},#{user.age},#{user.sex},#{user.address},#{user.phone},#{user.create_time},#{user.update_time},#{user.deleted});</insert>
</mapper>

AppUserController

@RestController
@RequestMapping("/appUser")
public class AppUserController {@AutowiredAppUserService appUserService;@PostMapping("/add")public String addAppUser(@RequestBody AppUser appUser){appUser.setCreate_time(new Date());appUser.setUpdate_time(new Date());appUserService.save(appUser); //mybatisplus生成appUser.setId(appUser.getId()+1000);appUserService.addOne(appUser); //手写的sqlreturn "成功";}
}

ShardingJdbcDemoApplication

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

1.3 postman测试

在这里插入图片描述
数据插入到了app_user表中,mybatisplus没问题
在这里插入图片描述

2. 分库分表实战

添加依赖

<dependency><groupId>org.apache.shardingsphere</groupId><artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId><version>5.0.0</version>
</dependency><!--druid-->
<dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.21</version>
</dependency>

2.1 分表

更改application.yml配置
包括配置数据源、配置逻辑表、配置分片算法
在这里插入图片描述
测试
在这里插入图片描述
查看数据库,发现数据被插入到app_user_202406表里
在这里插入图片描述

2.2 分库

再新建3个数据库,接下来将所有数据分在4个库里。
在这里插入图片描述

更改配置

  • 添加数据源
    在这里插入图片描述
  • 设置分库策略
    在这里插入图片描述
  • 配置分库算法
    这里的算法是取appUser的id的hash值除以取模4求余,再取绝对值,根据结果放在ds0,ds1,ds2,ds3库里
    在这里插入图片描述
    测试
    写一个mapping测试
@PostMapping("/addBatch")public String addAppUser(){List<AppUser> list = new ArrayList<>();for (int i = 0;i<100;i++){AppUser appUser = new AppUser();appUser.setId(11001+i);System.out.print(Math.abs(appUser.hashCode()%4)+",");appUser.setSex("0");appUser.setName("zhangsan"+i);appUser.setAge(25);appUser.setDeleted((short)0);appUser.setCreate_time(new Date());list.add(appUser);}appUserService.saveBatch(list);return "成功";

发送请求
在这里插入图片描述查看数据库,发现4个库的app_user_202406表里都有数据
在这里插入图片描述

2.3 分库分表后读取数据

@GetMapping("/list")public List<AppUser> list(){return appUserService.list();}

测试发现把所有分库的所有表都读取出来了

在这里插入图片描述

2.4 分库分表完整配置

server:port: 8080spring:shardingsphere:datasource:names: ds0,ds1,ds2,ds3ds0:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://192.168.200.131:3306/user_manage?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=falseusername: rootpassword: rootds1:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://192.168.200.131:3306/user_manage_01?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=falseusername: rootpassword: rootds2:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://192.168.200.131:3306/user_manage_02?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=falseusername: rootpassword: rootds3:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://192.168.200.131:3306/user_manage_03?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=falseusername: rootpassword: rootrules:sharding:tables:#配置逻辑数据库app_user:#数据库节点actual-data-nodes: ds$->{0..3}.app_user_$->{202401..202412}#分表策略table-strategy:standard:#分片键为 created_time  根据哪个字段分片,该字段叫分片键sharding-column: create_time#分表算法为sharding-algorithm-name: app-user-table-inline#分库策略database-strategy:standard:#分库列为id列sharding-column: id#分库算法 database_inlinesharding-algorithm-name: app-user-database-inline#算法配置sharding-algorithms:#订单表分表算法app-user-table-inline:type: INTERVALprops:datetime-pattern: yyyy-MM-dd HH:mm:ssdatetime-lower: 2024-01-01 00:00:00datetime-upper: 2024-12-01 00:00:00sharding-suffix-pattern: yyyyMMdatetime-interval-unit: MONTHS#分库算法配置app-user-database-inline:type: INLINEprops:algorithm-expression: ds$->{Math.abs(id.hashCode()%4)}# 设置Mapper接口所对应的XML文件位置,如果你在Mapper接口中有自定义方法,需要进行该配置
mybatis-plus:mapper-locations: classpath*:mapper/*.xml# 设置别名包扫描路径,通过该属性可以给包中的类注册别名type-aliases-package: com.gzdemo.shardingdemo.pojo

3. 读写分离

使两个主库ds0,ds1负责写数据,因此把分库算法中取模4设置为取模2

ds0作为主库负责写,ds2负责读;ds1作为主库负责写,ds1和ds3负责读

配置

          #分库算法配置app-user-database-inline:type: INLINEprops:algorithm-expression: ds$->{Math.abs(id.hashCode()%2)}rules:#读写分离配置readwrite-splitting:data-sources:ds0:#主数据源write-data-source-name: ds0#从数据源read-data-source-names: ds2#负载均衡算法load-balancer-name: randomds1:#主数据源write-data-source-name: ds1#从数据源read-data-source-names: ds1,ds3#负载均衡算法load-balancer-name: random#负载均衡算法load-balancers:round-robin:type: ROUND_ROBINrandom:type: RANDOM

修改user_manage库(ds0)中的i第一个name为zhangsanmanage;
修改user_manage_01库(ds1)中的i第一个name为zhangsanmanage01;
修改user_manage_02库(ds2)中的i第一个name为zhangsan3manage02;
修改user_manage_03库(ds3)中的i第一个name为zhangsanmanage03;

在这里插入图片描述

测试list接口,发现每次请求id为11004的只有来自于ds02的数据;
而id为11001的由于采用random算法,有时候只有来自于ds03的数据,有时候ds01和ds03的都有;
当采用rr算法时,发现每次只有来自于ds03的数据。没有ds02的数据。
这里暂时还不清楚原因。
在这里插入图片描述在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

4. 分库分表、读写分离所有配置

server:port: 8080spring:shardingsphere:datasource:names: ds0,ds1,ds2,ds3ds0:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://192.168.200.131:3306/user_manage?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=falseusername: rootpassword: rootds1:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://192.168.200.131:3306/user_manage_01?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=falseusername: rootpassword: rootds2:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://192.168.200.131:3306/user_manage_02?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=falseusername: rootpassword: rootds3:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://192.168.200.131:3306/user_manage_03?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&useSSL=falseusername: rootpassword: rootrules:sharding:tables:#配置逻辑数据库app_user:#数据库节点actual-data-nodes: ds$->{0..3}.app_user_$->{202401..202412}#分表策略table-strategy:standard:#分片键为 created_time  根据哪个字段分片,该字段叫分片键sharding-column: create_time#分表算法为sharding-algorithm-name: app-user-table-inline#分库策略database-strategy:standard:#分库列为id列sharding-column: id#分库算法 database_inlinesharding-algorithm-name: app-user-database-inline#算法配置sharding-algorithms:#订单表分表算法app-user-table-inline:type: INTERVALprops:datetime-pattern: yyyy-MM-dd HH:mm:ssdatetime-lower: 2024-01-01 00:00:00datetime-upper: 2024-12-01 00:00:00sharding-suffix-pattern: yyyyMMdatetime-interval-unit: MONTHS#分库算法配置app-user-database-inline:type: INLINEprops:algorithm-expression: ds$->{Math.abs(id.hashCode()%2)}#读写分离配置readwrite-splitting:data-sources:ds0:#主数据源write-data-source-name: ds0#从数据源read-data-source-names: ds2#负载均衡算法load-balancer-name: randomds1:#主数据源write-data-source-name: ds1#从数据源read-data-source-names: ds1,ds3#负载均衡算法load-balancer-name: random#负载均衡算法load-balancers:round-robin:type: ROUND_ROBINrandom:type: RANDOM# 设置Mapper接口所对应的XML文件位置,如果你在Mapper接口中有自定义方法,需要进行该配置
mybatis-plus:mapper-locations: classpath*:mapper/*.xml# 设置别名包扫描路径,通过该属性可以给包中的类注册别名type-aliases-package: com.gzdemo.shardingdemo.pojo

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

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

相关文章

vm-bhyve网卡设定桥接故障解决@FreeBSD

问题 在使用vm-bhyve虚拟机管理软件的时候&#xff0c;使用vm无法绑定网卡igb0 vm switch add public igb0 报错&#xff1a;/usr/local/sbin/vm: ERROR: failed to add member igb0 to the virtual switch public 解决 于是准备用原生ifconfig命令来绑定&#xff0c;结果…

ConvNeXt(CVPR 2022)论文解读

paper&#xff1a;A ConvNet for the 2020s official implementation&#xff1a;https://github.com/facebookresearch/ConvNeXt third-party implementation&#xff1a;https://github.com/huggingface/pytorch-image-models/blob/main/timm/models/convnext.py 背景 在…

基于SSM框架的垃圾分类系统的设计与实现(含源码+sql+开题报告+论文+论文答辩模板)

图1 前台首页截图 首页展示&#xff1a;首页展示法律法规、公示公告、用户交流论坛、分类指南、垃圾站点、以及个人中心&#xff1b; 法律法规&#xff1a;展示我国《城市生活垃圾分类及其评价标准》以及《生活垃圾分类标志》等最新法律法规&#xff1b; 公示公告&#xff1…

另一棵树的子树(oj题)

一、题目链接 https://leetcode.cn/problems/subtree-of-another-tree/submissions/536304222 二、题目思路 1.首先遍历大树&#xff0c;判断大树的根结点的值是否等于小树的根结点的值&#xff0c;如果不相等&#xff0c;就找大树的左孩子或者右孩子&#xff0c;以左孩子为根…

php 实现:给图片加文字水印,图片水印,压缩图片

演示环境&#xff1a; 1、windows10 2、phpstudy 3、php7.4 一、案例演示&#xff1a; 二、素材准备 1、准备一张原始图片 2、准备一张水印图片&#xff08;透明底图的最好&#xff09; 3、字体库&#xff08;windows系统自带的字体库&#xff0c;路径在&#xff1a;C:\Window…

Navicat连接Oracle

目标&#xff1a; 1.Navicat连接Oracle数据库&#xff0c;报错 无监听程序。 一、下载安装Navicat15 https://zhuanlan.zhihu.com/p/675991635 下载安装资源 链接&#xff1a;百度网盘 请输入提取码 提取码&#xff1a;1u1q 二、测试SQL PLUS连接数据库 在全部程序--》Ora…

Python | Leetcode Python题解之第123题买卖股票的最佳时机III

题目&#xff1a; 题解&#xff1a; class Solution:def maxProfit(self, prices: List[int]) -> int:n len(prices)buy1 buy2 -prices[0]sell1 sell2 0for i in range(1, n):buy1 max(buy1, -prices[i])sell1 max(sell1, buy1 prices[i])buy2 max(buy2, sell1 - …

Hadoop+Spark大数据技术 第七次作业

第七次作业 1. 简述Spark SQL使用的数据抽象DataFrame与Dataset的区别。 DataFrame: 基于 Row 对象的二维表格结构&#xff0c;类似于关系型数据库中的表。 行和列都有明确的 Schema&#xff08;模式&#xff09;&#xff0c;可以进行类型推断。 提供了丰富的操作接口&#xff…

docker私有镜像仓库的搭建及认证

简介&#xff1a; docker私有镜像仓库的搭建及认证 前言 在生产上使用的 Docker 镜像可能包含我们的代码、配置信息等&#xff0c;不想被外部人员获取&#xff0c;只允许内 网的开发人员下载。 Docker 官方提供了一个叫做 registry 的镜像用于搭建本地私有仓库使用。在内部网…

苍穹外卖数据可视化

文章目录 1、用户统计2、订单统计3、销量排名Top10 1、用户统计 所谓用户统计&#xff0c;实际上统计的是用户的数量。通过折线图来展示&#xff0c;上面这根蓝色线代表的是用户总量&#xff0c;下边这根绿色线代表的是新增用户数量&#xff0c;是具体到每一天。所以说用户统计…

CS4344国产替代音频DAC数模转换芯片DP7344采样率192kHz

目录 DAC应用简介DP7344简介结构框图DP7344主要特性微信号&#xff1a;dnsj5343参考原理图 应用领域 DAC应用简介 DAC&#xff08;中文&#xff1a;数字模拟转换器&#xff09;是一种将数字信号转换为模拟信号&#xff08;以电流、电压或电荷的形式&#xff09;的设备。电脑对…

BSD盲区检测系统性能要求及试验方法

相关术语 盲区检测(bsd,blind spot detection)试验车辆(subject vehicle)目标车辆(target vehicle)横向距离(lateral distance):试验车车身最外缘(不包含外后视镜)与目标车辆车身最外缘(不包含外后视镜)之间的横向距离。 纵向距离(longitudinal distance):试验…

SpringBoot的第二大核心AOP系统梳理

目录 1 事务管理 1.1 事务 1.2 Transactional注解 1.2.1 rollbackFor 1.2.2 propagation 2 AOP 基础 2.1 AOP入门 2.2 AOP核心概念 3. AOP进阶 3.1 通知类型 3.2 通知顺序 3.3 切入点表达式 execution切入点表达式 annotion注解 3.4 连接点 1 事务管理 1.1 事务…

云计算与 openstack

文章目录 一、 虚拟化二、云计算2.1 IT系统架构的发展2.2 云计算2.3 云计算的服务类型 三、Openstack3.1 OpenStack核心组件 一、 虚拟化 虚拟化使得在一台物理的服务器上可以跑多台虚拟机&#xff0c;虚拟机共享物理机的 CPU、内存、IO 硬件资源&#xff0c;但逻辑上虚拟机之…

组装电脑(使用老机箱)

昨天同事拿来一台联想 ThinkCentre M6210t的台式机&#xff0c;说计算机实在是太慢了&#xff0c;在只保留主机箱想升级一下。   她拿来了配件&#xff0c;有电源、主板、CPU、CPU风扇、内存条、机箱风扇、硬盘&#xff1a;   主板&#xff1a;华硕 Prime H610M-K D4&#…

element-ui表格全选

项目场景&#xff1a; 根据项目需求&#xff0c;要求在表格外加【全选】复选框&#xff0c;切换分页也需将每一行都勾选上 实现方式&#xff1a; 借用element-ui文档的这几个方法和属性 <el-checkboxv-model"checkAll"change"handleCheckAllChange"&g…

【计算机网络】——物理层(图文并茂)

物理层 一.物理层概述1.物理层要实现的功能2.物理层接口特征1.机械特性2.电气特性3.功能特性4.过程特性 二.物理层下面的传输媒体1.传输媒体的分类2.导向型传输媒体1.同轴电缆2.双绞线3.光纤 3.非导向型传输媒体1.无线电波2.微波3.红外线4.激光5.可见光 三.传输方式1.串行传输与…

自动化桌面整理新时代:Llama 3驱动的智能文件管理系统

在信息爆炸的时代,个人和企业用户的电脑桌面常常被海量文件占据,导致查找特定文件如同大海捞针。为了解决这一痛点,Llama 3应运而生——一个集成了先进多模态AI技术的智能文件管家,旨在将杂乱无章的文件世界变得井然有序。本文将深入探讨Llama 3如何利用其创新功能,不仅自…

研发效能DevOps: Ubuntu 部署 JFrog 制品库

目录 一、实验 1.环境 2.Ubuntu 部署 JFrog 制品库 3.Ubuntu 部署 postgresql数据库 4.Ubuntu 部署 Xray 5. 使用JFrog 增删项目 二、问题 1.Ubuntu 如何通过apt方式部署 JFrog 制品库 2.Ubuntu 如何通过docker方式部署 JFrog 制品库 3.安装jdk报错 4.安装JFrog Ar…

javascript DOM 属性详解:读取、修改、移除

No.内容链接1Openlayers 【入门教程】 - 【源代码示例300】 2Leaflet 【入门教程】 - 【源代码图文示例 150】 3Cesium 【入门教程】 - 【源代码图文示例200】 4MapboxGL【入门教程】 - 【源代码图文示例150】 5前端就业宝典 【面试题详细答案 1000】 文章目录 一、读取…