四,MyBatis-Plus 当中的主键策略和分页插件的(详细实操使用)
四,MyBatis-Plus 当中的主键策略和分页插件的(详细实操使用)
文章目录
- 四,MyBatis-Plus 当中的主键策略和分页插件的(详细实操使用)
- 1. 主键策略
- 1.1 主键生成策略介绍
- 2. 准备工作:
- 2.1 AUTO 策略
- 2.2 INPUT 策略
- 2.3 ASSIGN_ID 策略
- 2.3.1 雪花算法
- 2.4 NONE 策略
- 2.5 ASSIGN_UUID 策略
- 3. 分页
- 3.1 分页插件
- 3.2 自定义分页插件
- 4. 总结:
- 5. 最后:
1. 主键策略
1.1 主键生成策略介绍
首先大家先要指定什么是主键,主键的作用就是唯一标识,我们可以通过这个唯一标识来定位到这条数据。
当然对于表数据中的主键,我们可以自己设计生成规则,生成主键。但是在更多的场景中,没有特殊要求的话,我们每次自己手动生成的比较麻烦,我们可以借助框架提供好的主键生成策略,来生成主键。这样比较方便快捷。
在MyBatis Plus 中提供了一个注解,是 @TeableId 。

该注解提供了各种的主键生成策略,我们可以通过使用该注解来对于新增的数据指定主键生成策略。那么在以后新增数据的时候,数据就会按照我们指定的主键生成策略来生成对应的主键。
2. 准备工作:
特别说明:
需要导入的相关
jar依赖。如下:
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.5.3</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.rainbowsea</groupId><artifactId>mp03</artifactId><version>0.0.1-SNAPSHOT</version><name>mp03</name><description>mp03</description><url/><licenses><license/></licenses><developers><developer/></developers><scm><connection/><developerConnection/><tag/><url/></scm><properties><java.version>8</java.version></properties><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></dependency><!-- spring boot web 依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- mysql 驱动依赖--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!-- lombok 的依赖--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!-- druid--><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.8</version></dependency><!-- mybatis-plus 的依赖--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.3</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build><repositories><repository><id>spring-snapshots</id><name>Spring Snapshots</name><url>https://repo.spring.io/snapshot</url><releases><enabled>false</enabled></releases></repository></repositories><pluginRepositories><pluginRepository><id>spring-snapshots</id><name>Spring Snapshots</name><url>https://repo.spring.io/snapshot</url><releases><enabled>false</enabled></releases></pluginRepository></pluginRepositories></project>对应的 application.yaml 文件的配置的编写:
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/mybatisplus?serverTimezone=UTC&characterEncoding=utf8&useUnicode=true&useSSL=falseusername: rootpassword: MySQL123main:banner-mode: off #关闭 spring boot 在命令行当中的图标显示mybatis-plus:global-config:banner: false # 关闭 mybatis-plus 在命令行当中的图标显示db-config:table-prefix: rainbowsea_ # 还可以通过统一添加前缀的方式:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 开启 Log 日志信息打印map-underscore-to-camel-case: true # 开启驼峰,下划线映射规则
编写对应的 DataSource 数据源,这里我们通过配置类的方式,将Spring Boot 的数据库连接池换为 Druid 数据库连接池。如下:

package com.rainbowsea.config;import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import javax.sql.DataSource;@Configuration // 标注配置类
public class DruidDataSourceConfig {@Bean@ConfigurationProperties(value = "spring.datasource")public DataSource getDataSource() {DruidDataSource druidDataSource = new DruidDataSource();return druidDataSource;}
}
运行测试,看看是否换为了 Druid 数据库连接池。

编写场景启动器:

2.1 AUTO 策略
该策略为跟随数据库表的主键递增策略,前提是数据库表的主键要设置为自增。


实体类添加注解,指定主键生成策略。
运行测试:

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.rainbowsea.bean.User;
import com.rainbowsea.mapper.UserMapper;
//import com.rainbowsea.mapper.UserMapper2;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import javax.annotation.Resource;@SpringBootTest
public class PrimaryKeyTest {@Autowired//@Resourceprivate UserMapper userMapper;@Testvoid primary() {User user = new User();user.setName("张三");user.setAge(19);user.setEmail("mary@rainbowsea.com");userMapper.insert(user);}
}

2.2 INPUT 策略
该策略表示,必须由我们手动的插入id,否则无法添加数据
// 该策略表示,必须由我们手动的插入id,否则无法添加数据,前提是:需要去掉数据表的自增策略


import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.Version;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler;
import com.rainbowsea.enums.GenderEnum;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.util.Date;
import java.util.Map;@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName(autoResultMap = true,value = " rainbowsea_user2")//查询时将json字符串封装为Map集合
public class User extends Model<User> {@TableId(type = IdType.INPUT) // 该策略表示,必须由我们手动的插入id,否则无法添加数据,前提是:需要去掉数据表的自增策略private String id;private String name;private Integer age;private String email;
}
这里如果我们省略不写id,会发现,无法插入数据

@Test
void primaryKey(){User user = new User();user.setName("Jerry");user.setAge(38);user.setEmail("test8@powernode.com");userMapper.insert(user);
}

但是我们自己指定了id,发现可以添加成功

2.3 ASSIGN_ID 策略
我们来思考一下,像之前这种自动递增的方式,有什么问题?
如果我们将来一张表的数据量很大,我们需要进行分表。
常见的分表策略有两种:水平拆分,垂直拆分
- 水平拆分:水平拆分就是将一个大的表按照数据量进行拆分

- 垂直拆分: 垂直拆分就是将一个大的表按照字段进行拆分

其实我们对于拆分后的数据,有三点需求,就拿水平拆分类说:
之前的表的主键是有序的,拆分后还是有序的。
虽然做了表的拆分,但是每条数据还需要保证主键的唯一性。
主键最好不要直接暴露数据的数量,这样容易被外界知道关键信息。
那就需要有一种算法,能够实现这三个需求,这个算法就是雪花算法。
2.3.1 雪花算法
雪花算法是由一个
64位的二进制组成的,最终就是一个Long类型的数据。主要分为:四部分存储 。
1位的符号位,固定值为 041位的时间戳10位的机器码,包含5位机器 id 和5位服务 id12位的序列号
**使用雪花算法可以实现有序、唯一、且不直接暴露排序的数字。 **

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.Version;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import com.baomidou.mybatisplus.extension.handlers.FastjsonTypeHandler;
import com.rainbowsea.enums.GenderEnum;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.util.Date;
import java.util.Map;@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName(autoResultMap = true,value = " rainbowsea_user2")//查询时将json字符串封装为Map集合
public class User extends Model<User> {@TableId(type = IdType.ASSIGN_ID) // 雪花算法,就算数据表,没有设置自增策略,也可以成功的自增策略private String id;private String name;private Integer age;private String email;}
运行测试:

我们可以在插入后发现一个19位长度的id,该id就是雪花算法生成的id,这是二级制的十进制表示形式
2.4 NONE 策略
NONE策略表示不指定主键生成策略,当我们没有指定主键生成策略或者主键策略为NONE的时候,他跟随的是全局策略,那我们来看一下他的全局策略默认是什么
是在application.yaml 文件当中配置 id-type 属性。全局配置中 id-type是用于配置主键生成策略的,我们可以看一下id-type的默认值


通过查看源码发现,id-type的默认值就是雪花算法。
也就是说,就算我们不采用任何的了主键策略,**在全局配置当中,默认就是采用了雪花算法
ASSIGN_ID策略**

2.5 ASSIGN_UUID 策略
UUID(Universally Unique Identifier)全局唯一标识符,定义为一个字符串主键 (注意:这里是字符串,也就是说,你的数据表的id 的主键,要为字符串类型,才可以使用这个ASSIGN_UUID策略),采用32位数字组成,编码采用 16进制,定义了在时间和空间都完成唯一的系统信息。
UUID的编码规则:
1~8位采用系统时间,在系统时间上精确到毫秒级保证时间上的唯一性。9~16位采用底层的 IP地址,在服务器集群中的唯一性。17~24位采用当前对象的HashCode值,在一个内部对象上的唯一性。25~32位采用调用方法的一个随机数,在一个对象内的毫秒级的唯一性。通过上述以上4中策略可以保证数据的唯一性 。在系统中需要用到随机数的地方都可以考虑采用UUID 算法。
我们想要演示UUID的效果,需要改变一下表的字段类型和实体类的属性类型
将数据库表的字段类型改为 varchar(50)

将实体类的属性类型改为String,并指定主键生成策略为 IdType.ASSIGN_UUID


完成数据的添加。我们会发现,成功添加了一条数据,id为uuid类型

3. 分页
在大部分场景下,如果我们的SQL没有这么复杂,是可以直接通过MybatisPlus提供的方法来实现查询的,在这种情况下,我们可以通过配置分页插件来实现分页效果
分页的本质就是需要设置一个拦截器,通过拦截器拦截了SQL,通过在SQL语句的结尾添加limit关键字,来实现分页的效果

3.1 分页插件
接下来看一下配置的步骤:配置分页插件
- 通过配置类来指定一个具体数据库的分页插件,因为不同的数据库的方言不同,具体生成的分页语句也会不同,这里我们指定数据库为Mysql数据库。

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.apache.ibatis.plugin.Interceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class MybatisPlusConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();/*通过配置类来指定一个具体数据库的分页插件,因为不同的数据库的方言不同,具体涩会给你从的分页语句也会不同,这里我们指定数据库为 MySQL数据库*/mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));return mybatisPlusInterceptor;}}
实现分页查询效果:

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.rainbowsea.bean.User;
import com.rainbowsea.mapper.UserMapper;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;import javax.annotation.Resource;@SpringBootTest
public class PageTest {@Resourceprivate UserMapper userMapper;@Testvoid selectPage() {LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();// 指定分页对象,分页对象包含分页信息 IPageIPage<User> userPage = new Page<>(1,3);//Page<User> userPage = new Page<>(2, 3);// 执行查询userMapper.selectPage(userPage, lambdaQueryWrapper);// 获取分页查询的信息System.out.println("当前页:" + userPage.getCurrent());System.out.println("每页显示条数: " + userPage.getSize());System.out.println("总页数: " + userPage.getPages());System.out.println("总条数: " + userPage.getTotal());System.out.println("分页数据: " + userPage.getRecords());}
}


3.2 自定义分页插件
在某些场景下,我们需要自定义SQL语句来进行查询。接下来我们来演示一下自定义SQL的分页操作
在Mapper接口中提供对应的方法,方法中将IPage对象作为参数传入

package com.rainbowsea.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.rainbowsea.bean.User;
import org.apache.ibatis.annotations.Mapper;@Mapper // 包路径扫描
public interface UserMapper extends BaseMapper<User> {IPage<User> selectByName(IPage<User> page, String name);
}
在UserMapper.xml映射配置文件中提供查询语句。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.rainbowsea.mapper.UserMapper"><select id="selectByName" resultType="com.rainbowsea.bean.User">select * from rainbowsea_user where name = #{name}</select></mapper>
实现分页查询效果:

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.rainbowsea.bean.User;
import com.rainbowsea.mapper.UserMapper;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;import javax.annotation.Resource;@SpringBootTest
public class PageTest {@Resourceprivate UserMapper userMapper;@Testvoid selectPage2() {IPage<User> userPage = new Page<>(1,3);userMapper.selectByName(userPage,"Mary");// 获取分页查询的信息System.out.println("当前页:" + userPage.getCurrent());System.out.println("每页显示条数: " + userPage.getSize());System.out.println("总页数: " + userPage.getPages());System.out.println("总条数: " + userPage.getTotal());System.out.println("分页数据: " + userPage.getRecords());}
}
4. 总结:
- 主键策略:
- AUTO 策略,自动添加主键,前提是:要设置数据表的自增。
- INPUT 策略:该策略表示,必须由我们手动的插入id,否则无法添加数据,前提是:需要去掉数据表的自增策略。
- ASSIGN_ID: 策略,运用了雪花算法,为主键的id 加密的同时自增了。
- NONE策略:默认的策略,该策略默认就是:默认设置(默认就是雪花算法),数据表没有设置自增策略,也可以成功。
- ASSIGU_UUID策略:采用UUID的编码加密主键,同时自增主键,全局唯一标识符,定义为一个字符串主键,注意是字符串,所以数据表的主键要为字符串类型才行,对应的 Java bean 对象当中的属性值,也要为 字符串类型
- 分页的本质就是需要设置一个拦截器,通过拦截器拦截了SQL,通过在SQL语句的结尾添加limit关键字,来实现分页的效果
5. 最后:
“在这个最后的篇章中,我要表达我对每一位读者的感激之情。你们的关注和回复是我创作的动力源泉,我从你们身上吸取了无尽的灵感与勇气。我会将你们的鼓励留在心底,继续在其他的领域奋斗。感谢你们,我们总会在某个时刻再次相遇。”
相关文章:
四,MyBatis-Plus 当中的主键策略和分页插件的(详细实操使用)
四,MyBatis-Plus 当中的主键策略和分页插件的(详细实操使用) 文章目录 四,MyBatis-Plus 当中的主键策略和分页插件的(详细实操使用)1. 主键策略1.1 主键生成策略介绍 2. 准备工作:2.1 AUTO 策略2.2 INPUT 策略2.3 ASSIGN_ID 策略2.3.1 雪花算…...
Win32打开UWP应用
最近无意间发现Windows里一个神奇的文件夹。 shell:appsfolder 运行打开 这个文件夹后,你可以看到本机安装的所有应用程序。 我觉得这个挺方便的,所以做了一个简单的appFolderDialog包给C#用 项目地址:https://github.com/TianXiaTech/App…...
C# C++ 笔记
第一阶段知识总结 lunix系统操作 1、基础命令 (1)cd cd /[目录名] 打开指定文件目录 cd .. 返回上一级目录 cd - 返回并显示上一次目录 cd ~ 切换到当前用户的家目录 (2)pwd pwd 查看当前所在目录路径 pwd -L 打印当前物理…...
关于最小二乘法
最小二乘法的核心思想简单而优雅:我们希望找到一条最佳的曲线,使其尽可能贴近所有的数据点。想象一下,当你在画布上描绘一条线,目标是让这条线与点的距离最小。数学上,这可以表示为: 在这个公式中ÿ…...
国产OpenEuler与Centos全面之比较
OpenEuler 和 CentOS 都是流行的 Linux 发行版,但它们有一些关键的区别。以下是 OpenEuler 和 CentOS 的全面比较: 1. 起源和支持: - OpenEuler:由华为公司支持,中国开源社区主导开发的操作系统,旨在构建一…...
Java面试题一
一、Java语言有哪些特性? Java语言具有多种特性,这些特性使得Java成为一种广泛使用的编程语言。以下是Java语言的一些主要特性: 面向对象(Object-Oriented): Java是一种纯面向对象的编程语言。它支持类&…...
LabVIEW提高开发效率技巧----自动化测试和持续集成
在大型项目中,自动化测试和持续集成是提高开发效率和代码质量的关键手段。通过这些技术,开发者能够在开发的早期阶段快速发现问题,减少后期调试的工作量,并且能够确保代码的稳定性和可维护性。以下是这两个概念如何在LabVIEW开发中…...
开源链动 2+1 模式 S2B2C 商城小程序:激活 KOC,开启商业新征程
摘要:本文深入探讨了 KOC 在立体连接中的重要性,以及如何通过开源链动 21 模式 S2B2C 商城小程序发现和找到更多的 KOC。强调了历史积累强关系和快速强化强关系的方法,并阐述了该商城小程序在推动商业发展中的关键作用。 一、引言 在当今竞争…...
什么是Node.js?
为什么JavaScript可以在浏览器中被执行? 在浏览器中我们加载了一些待执行JS代码,这些字符串要当中一个代码去执行,是因为浏览器中有JavaScript的解析引擎,它的存在我们的代码才能被执行。 不同的浏览器使用不同的javaScript解析引…...
即插即用篇 | DenseNet卷土重来! YOLOv8 引入全新密集连接卷积网络 | ECCV 2024
本改进已同步到YOLO-Magic框架! 本文重新审视了密集连接卷积网络(DenseNets),并揭示了其在主流的ResNet风格架构中被低估的有效性。我们认为,由于未触及的训练方法和传统设计元素没有完全展现其能力,DenseNets的潜力被忽视了。我们的初步研究表明,通过连接实现的密集连接…...
智能监控,守护绿色能源:EasyCVR在电站视频监控中心的一站式解决方案
随着科技的飞速发展,视频监控技术在社会安全、企业管理及智慧城市建设等领域中扮演着越来越重要的角色。特别是在电力行业中,电站作为能源供应的关键设施,其安全性和稳定性至关重要。传统的人工监控方式已难以满足现代电站复杂多变的运行需求…...
【BUG】静读天下|静读天下无法设置段间距解决方案
【BUG】静读天下|静读天下无法设置段间距解决方案 文章目录 【BUG】静读天下|静读天下无法设置段间距解决方案前言解决办法 凑质量分静读天下的特点与优势功能布局与使用技巧个人使用心得结语 前言 03-23 求助|关于排版的问题【静读天下吧】_…...
希捷电脑硬盘好恢复数据吗?探讨可能性、方法以及注意事项
在数字化时代,数据已成为我们生活和工作中不可或缺的一部分。希捷电脑硬盘作为数据存储的重要设备,承载着大量的个人文件、工作资料以及珍贵回忆。然而,面对硬盘故障或误操作导致的数据丢失,许多用户不禁要问:希捷电脑…...
java通过webhook给飞书发送群消息
现在使用飞书的人越来越多了,飞书有一个最大的好处,可以使用webhook简便的发送群消息。而在工作中,也经常会因为一些运维方面的工作,需要给飞书发送群消息,来实时提醒相关负责人,及时处理工作。 一、先看一下效果吧&a…...
每日一题——第一百零九题
题目:进制转换合集。任意r进制与十进制之间的转换 #include<stdio.h> #include<stdlib.h> #include<string.h> #include<ctype.h> long stringToDecimal(const char* str, int base); void convertToBaseR(int num, int r);int main() {ch…...
街头摊贩检测系统源码分享
街头摊贩检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vis…...
服务器数据恢复—SAN环境下LUN映射出错导致文件系统一致性出错的数据恢复案例
服务器数据恢复环境: SAN环境下一台存储设备中有一组由6块硬盘组建的RAID6磁盘阵列,划分若干LUN,MAP到不同业务的SOLARIS操作系统服务器上。 服务器故障: 用户新增了一台服务器,将存储中的某个LUN映射到新增加的这台服…...
深度学习:自然语言处理的基本原理
概念: 自然语言处理(Natural Language Processing,简称NLP)是人工智能和语言学领域的一个分支,它致力于研究如何让计算机能够理解、解释和生成人类语言,以及如何实现人与计算机之间的有效通信。自然语言处理…...
Win10 Chrome浏览器被强制绑定主页的解决办法
Win10 Chrome浏览器被强制绑定主页的解决办法 背景 刚刚重装的系统默认是某杀毒软件,使用浏览器时发现浏览器主页老是hao123,还改不了。于是卸载了此杀毒软件,换了别的。发现还是解决不了浏览器主页被绑定且改不了的问题 体现 chrome://se…...
【UE5】将2D切片图渲染为体积纹理,最终实现使用RT实时绘制体积纹理【第四篇-着色器投影-接收阴影部分】
上一章中实现了体积渲染的光照与自阴影,那我们这篇来实现投影 回顾 勘误 在开始本篇内容之前,我已经对上一章中的内容的错误进行了修改。为了确保不会错过这些更正,同时也避免大家重新阅读一遍,我将在这里为大家演示一下修改的…...
Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...
学校招生小程序源码介绍
基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...
土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等
🔍 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术,可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势,还能有效评价重大生态工程…...
微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...
ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...
中医有效性探讨
文章目录 西医是如何发展到以生物化学为药理基础的现代医学?传统医学奠基期(远古 - 17 世纪)近代医学转型期(17 世纪 - 19 世纪末)现代医学成熟期(20世纪至今) 中医的源远流长和一脉相承远古至…...
保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek
文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama(有网络的电脑)2.2.3 安装Ollama(无网络的电脑)2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...
MinIO Docker 部署:仅开放一个端口
MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...
作为测试我们应该关注redis哪些方面
1、功能测试 数据结构操作:验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化:测试aof和aof持久化机制,确保数据在开启后正确恢复。 事务:检查事务的原子性和回滚机制。 发布订阅:确保消息正确传递。 2、性…...
Vue 模板语句的数据来源
🧩 Vue 模板语句的数据来源:全方位解析 Vue 模板(<template> 部分)中的表达式、指令绑定(如 v-bind, v-on)和插值({{ }})都在一个特定的作用域内求值。这个作用域由当前 组件…...



