Spring boot 知识整理
一、SpringBoot 背景内容梳理
-
SpringBoot是一个基于Spring框架的开源框架,用于简化Spring应用程序的初始搭建和开发过程。它通过提供约定优于配置的方式,尽可能减少开发者的工作量,使得开发Spring应用变得更加快速、便捷和高效。
-
SpringBoot的主要特点包括:
- 简化配置:SpringBoot遵循约定优于配置的原则,减少了传统Spring应用中的大量配置。它通过自动配置(auto-configuration)和起步依赖(starterdependencies)来简化项目的配置过程,让开发者可以快速搭建起一个可运行的Spring应用。
- 集成性强:SpringBoot提供了大量的开箱即用的特性和功能,如内嵌的Servlet容器(如Tomcat、Jetty或Undertow)、健康检查、指标监控等。它还整合了诸多常用的库和框架,如SpringData、SpringSecurity等,使得开发者可以快速构建出功能完善的应用。
- 微服务支持:SpringBoot非常适合用于构建微服务架构。它提供了丰富的支持,如通过SpringCloud进行微服务架构的开发,集成了服务发现、配置中心、负载均衡等功能,帮助开发者构建可伸缩、高可用的微服务系统。
- 内嵌服务器:SpringBoot可以将应用程序打包成一个可执行的JAR文件,并内置了常用的Servlet容器,如Tomcat、Jetty或Undertow。这样一来,开发者可以通过简单的java-jar命令来运行应用程序,而无需部署到外部应用服务器。
- 生态丰富:由于SpringBoot的广泛应用和强大生态系统,开发者可以轻松地使用各种扩展和插件,如Actuator、SpringBootDevTools等,提高开发效率和应用质量。
- 从前端的api到我后端的接受再到数据库:
- 发请求——>控制层接受——> 调用服务层的函数——>调用Repository——>找到对应的实体然后进行数据库的交互
其中额外设计的有 Response 的设计 ,方便前端对于后端返回数据的统一规范处理;
DTO类(用于封装数据,通常在层与层之间传递,避免直接暴露实体);
转换器的设计,方便后端设置哪些数据可以返回给对应的前端
二、Rest api 规范
-
路径
- 路径又称"终点”(endpoint),表示API的具体网址。
- 在RESTful架构中,每个网址代表一种资源(resource),所以网址中不能有动词,只能有名词,而且所用的名词往往与数据库的表格名对应。
-
Http 动词
- GET(SELECT):从服务器取出资源(一项或多项)。
- POST(CREATE):在服务器新建一个资源。
- PUT(UPDATE):在服务器更新资源(将户端提供改变后的完整资源)。
- PATCH(UPDATE):在服务器更新资源(客户端提供改变的属性)。
- DELETE(DELETE):从服务器删除资源。
三、JPA
JPA 提供了一种标准化的方式来进行对象关系映射,是 Java 应用程序中进行数据持久化的关键技术。通过使用 JPA,开发者可以更高效地管理数据库操作,专注于业务逻辑开发
JPA 是一个规范,多个框架实现了该规范,常见的实现包括:
- Hibernate:最流行的 JPA 实现,提供丰富的功能和强大的社区支持。
- EclipseLink:Oracle 官方的 JPA 实现,支持多种数据库。
- OpenJPA:Apache 提供的 JPA 实现。
3.1. JPA内部有关的注解
1. @Entity
- 定义:标识一个类为 JPA 实体,表示该类对应于数据库中的一张表。
2. @Table
- 定义:指定实体类对应的数据库表的名称。
- 用法:
@Table(name = "table_name")
3. @Id`
- 定义:标识实体类的主键字段。
4. @GeneratedValue`
- 定义:指定主键的生成策略。
- 常用策略:
GenerationType.IDENTITY
:主键由数据库自动生成。GenerationType.SEQUENCE
:使用数据库序列生成主键。GenerationType.AUTO
:根据数据库自动选择生成策略。
5. @Column`
- 定义:映射实体类的字段到数据库表的列。
- 常用属性:
name
:指定数据库列名。nullable
:指定该列是否可以为null
。length
:指定字符串列的最大长度。
6.@Builder
- 用于简化对象的构建过程。它通过生成一个构建器模式的实现,减少频繁的属性赋值
- 用法:
Student student = Student.builder() .name("Alice") .age(20).email("alice@example.com") .build();
3.2. JPA 的使用(JpaRepository<T, ID>)
-
JpaRepository<T, ID>是一个 Spring Data JPA 提供的接口,允许你执行 CRUD 操作。
- 第一个泛型参数
T
表示实体类的类型,即与数据库相对应的Java类 - 第二个泛型参数
ID
表示主键的类型,即用于唯一标识实体的字段,确保记录的唯一性(通常是Long
,Integer
,String
等) - 必须遵循
JpaRepository<实体类, 主键类型>
的格式。交换位置会导致错误。
- 第一个泛型参数
-
JPA的方法用法:
- 基本 CRUD 操作:
- 通过继承
JpaRepository
,可以获得基本的 CRUD 操作,如save()
,findById()
,delete()
,findAll()
等。
- 通过继承
- 查询方法命名约定:
- JPA 提供了一种约定优于配置的方法命名规则。你可以通过特定的命名规则自动生成查询。
- 示例:
findByEmail(String email)
:根据email
查找学生。findByAgeBetween(int min, int max)
:查找年龄在min
和max
之间的学生。findByNameStartingWith(String namePrefix)
:查找姓名以namePrefix
开头的学生。
- 使用
@Query
注解:- 可以使用
@Query
注解来定义自定义查询。 - 原始 SQL 查询:
- 使用
nativeQuery = true
指定这是一个原始 SQL 查询。 - 示例:
- 使用
- 可以使用
- 基本 CRUD 操作:
@Query(value = "select * from Student where email = :email", nativeQuery = true)
List<Student> findByEmail2(@Param("email") String email);query里面的用 :email 做占位符,用来读取@Parm 中的形参
.
- JPQL 查询:
- JPQL 用于面向对象的查询,允许你直接操作实体。
- 使用 SELECT NEW
创建新对象。
- 示例:`findByEmail3(@Param(“email”) String email)
@Query(value = "SELECT NEW com.demo.springbootstudy.dao.Student(s.name, s.email) FROM Student s WHERE s.email = :email")
List<Student> findByEmail3(@Param("email") String email);query里面的用 :email 做占位符,用来读取@Parm 中的形参
3.3 JpaSpecificationExecutor< T > 的使用
JpaSpecificationExecutor
是 Spring Data JPA 提供的接口,用于支持动态查询。通过该接口,可以使用 JPA Criteria API 构建复杂的查询条件.
.
在面对一个大项目,里面复杂的查询情况,可以单独创建一个文件夹存放不同实体的 Specification的静态定义,后续在服务层根据对应的情况,设置不同属性进行传参调用静态函数
使用:
- 创建Repority接口去继承 JpaSpecificationExecutor< T >(其中T指的是数据库表实体)
- 定义一个类存放Specification的静态方法,模板如下:
public static Specification<Student> filterByCriteria(StudentDTO studentDTO) { return (root, query, cb) -> { List<Predicate> predicates = new ArrayList<>(); if (studentDTO.getName() != null) { predicates.add(cb.equal(root.get("name"), studentDTO.getName())); } if (studentDTO.getMinAge() != null) { predicates.add(cb.greaterThanOrEqualTo(root.get("age"), studentDTO.getMinAge())); } if (studentDTO.getMaxAge() != null) { predicates.add(cb.lessThanOrEqualTo(root.get("age"), studentDTO.getMaxAge())); } //两个 return 实现的效果一样return query.where(predicates.toArray(new Predicate[0])).getRestriction();return cb.and(predicates.toArray(new Predicate[0])); };
}- `root`:表示查询的根实体,即在这里是 `Student`。
- `query`:表示查询的上下文。
- `cb`:表示构建条件的 `CriteriaBuilder`对象。- 其中这个cb里面集成多种方法用于构建查询条件- cb.and(predicates.toArray(new Predicate[0])); - 动态地将所有的查询条件结合起来,形成一个整体的查询条件
- `Predicate`:表示查询条件,通过add函数来添加不同的查询条件- .getRestriction() 用于获取它所表示的条件
- 后续调用先构建好对应的形参,然后调用上面的静态方法获取Specification;
- 最后调用Repository接口中的函数findAll,形参传入的是上面的Specification对象;
3.4 分页查找的用法
四、Mybatis 的用法
MyBatis 是一个 持久层框架,用于简化数据库操作。它提供了一种映射关系,将数据库中的记录映射到 Java 对象,并支持通过 XML 或注解的方式配置 SQL 语句。
.
MyBatis Plus 是在 MyBatis 的基础上开发的增强工具包,旨在简化开发,提高效率。它提供了 CRUD 操作、条件构造器、分页插件、代码生成器等多种功能。
4.1 配置
Pom.xml 配置
<dependencies><!-- MyBatis Plus 依赖 --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.1</version></dependency><!-- MySQL 驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.23</version></dependency><!-- Spring Boot Starter Web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><scope>provided</scope></dependency><!-- 其他依赖 --><!-- ... -->
</dependencies>
Spring Boot 配置(以 .yml 文件为主)
spring:datasource:url: jdbc:mysql://localhost:3306/your_database?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghaiusername: your_usernamepassword: your_passworddriver-class-name: com.mysql.cj.jdbc.Drivermybatis-plus:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl //sql打印到控制台
编写实体类
@Data
@TableName(value = "user")
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class User {@TableId(type = IdType.AUTO)private Long id;private String name;private Integer age;private String email;// @TableField(fill = FieldFill.INSERT, value = "create_time")// private Long createTime;// @TableField(fill = FieldFill.INSERT_UPDATE, value = "update_time")// private Long updateTime;// @Version// private Long version;
}
编写Mapper接口
@Mapper
public interface UserMapper extends BaseMapper<User> {
}
添加注解MapperScan
在Application类上添加@MapperScan
注解并指定mapper的包路径
Mybatis-plus 拦截器配置
配置类用于添加拦截器,如乐观锁、分页等插件
@Configuration public class MyBatisPlusConfig { @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); // 添加乐观锁拦截器 interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());// 添加分页拦截器interceptor.addInnerInterceptor(new PaginationInnerInterceptor()); return interceptor; }
}
4.2 常用功能介绍
1. CRUD 操作
MyBatis Plus 提供了基础的 CRUD 方法,包括 insert
、delete
、update
、select
等。
@Testvoid testInsert() {User user = User.builder().name("fengzhu").age(18).email("abc@a.com").build();userMapper.insert(user);}@Testvoid testSelect() {User user = userMapper.selectById(24L);System.out.println(user.getName());}@Testvoid testUpdate() {User user = User.builder().id(27L).email("fasfas@a.com").build();int count = userMapper.updateById(user);System.out.println("update success:" + count);}@Testvoid testDelete() {userMapper.deleteById(24L);}
2. 条件构造器
条件构造器主要涉及到3个类,AbstractWrapper
,QueryWrapper
,UpdateWrapper
在AbstractWrapper中提供了非常多的方法用于构建WHERE条件,而QueryWrapper针对SELECT语句,提供了select()方法,可自定义需要查询的列,而UpdateWrapper针对UPDATE语句,提供了set()方法,用于构造set语句,条件构造器也支持lambda表达式。
AbstractWrapper中用于构建SQL语句中的WHERE条件的方法进行部分列举
- eq:equals,等于
- allEq:all equals,全等于
- ne:not equals,不等于
- gt:greater than ,大于 >
- ge:greater than or equals,大于等于≥
- lt:less than,小于<
- le:less than or equals,小于等于≤
- between:相当于SQL中的BETWEEN
- notBetween
- like:模糊匹配。like(“name”,“黄”),相当于SQL的name like ‘%黄%’
- likeRight:模糊匹配右半边。likeRight(“name”,“黄”),相当于SQL的name like ‘黄%’
- likeLeft:模糊匹配左半边。likeLeft(“name”,“黄”),相当于SQL的name like ‘%黄’
- notLike:notLike(“name”,“黄”),相当于SQL的name not like ‘%黄%’
- isNull
- isNotNull
- in
- and:SQL连接符AND
- or:SQL连接符OR
- apply:用于拼接SQL,该方法可用于数据库函数,并可以动态传参
// 条件查询
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name", "Tom");
List<User> users = userMapper.selectList(queryWrapper);// 条件更新
UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("name", "Tom").set("age", 27);
userMapper.update(updateWrapper);
3. Condition
条件构造器的诸多方法中,均可以指定一个boolean类型的参数condition,用来决定该条件是否加入最后生成的WHERE语句中,比如
String name = "黄"; // 假设name变量是一个外部传入的参数
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.like(StringUtils.hasText(name), "name", name);
// 仅当 StringUtils.hasText(name) 为 true 时, 会拼接这个like语句到WHERE中
// 其实就是对下面代码的简化
if (StringUtils.hasText(name)) {wrapper.like("name", name);
}
4. 实体对象作为条件
调用构造函数创建一个Wrapper对象时,可以传入一个实体对象。后续使用这个Wrapper时,会以实体对象中的非空属性,构建WHERE条件(默认构建等值匹配的WHERE条件,这个行为可以通过实体类里各个字段上的@TableField注解中的condition属性进行改变)
@Test
public void test3() {User user = new User();user.setName("abc");user.setAge(28);QueryWrapper<User> wrapper = new QueryWrapper<>(user);List<User> users = userMapper.selectList(wrapper);users.forEach(System.out::println);
}
5. allEq方法
- allEq方法传入一个map,用来做等值匹配
- 当allEq方法传入的Map中有value为null的元素时,默认会设置为is null
- 若想忽略map中value为null的元素,可以在调用allEq时,设置参数boolean null2IsNull为false
@Test
public void test3() {QueryWrapper<User> wrapper = new QueryWrapper<>();Map<String, Object> param = new HashMap<>();param.put("age", 40);param.put("name", null);wrapper.allEq(param);List<User> users = userMapper.selectList(wrapper);users.forEach(System.out::println);
}
6. lambda条件构造器
- lambda条件构造器,支持lambda表达式,可以不必像普通条件构造器一样,以字符串形式指定列名,它可以直接以实体类的方法引用来指定列。
- 像普通的条件构造器,列名是用字符串的形式指定,无法在编译期进行列名合法性的检查,这就不如lambda条件构造器来的优雅。
@Test
public void testLambda() {LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();wrapper.like(User::getName, "黄").lt(User::getAge, 30);List<User> users = userMapper.selectList(wrapper);users.forEach(System.out::println);
}- `like(User::getName, "黄")`:表示查询 `User` 表中 `name` 字段包含"黄"的记录。
- `lt(User::getAge, 30)`:表示查询 `User` 表中 `age` 字段小于 30 的记录
更新操作
- updateById(T entity)
根据入参entity的id(主键)进行更新,对于entity中非空的属性,会出现在UPDATE语句的SET后面,即entity中非空的属性,会被更新到数据库,示例如下
@Testpublic void testUpdate2() {User user = new User();user.setId(1L); // 假设要更新的用户 IDuser.setName("新的名字"); // 只更新名字,其他属性保持不变userMapper.updateById(user);}
- update(T entity, Wrapper<T> wrapper)
根据实体entity和条件构造器wrapper进行更新,示例如下
@Testpublic void testUpdate2() {User user = new User();user.setName("abc");LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<>();wrapper.between(User::getAge, 26,31).likeRight(User::getName,"吴");userMapper.update(user, wrapper);}
删除操作
BaseMapper一共提供了如下几个用于删除的方法
- deleteById 根据主键id进行删除
- deleteBatchIds 根据主键id进行批量删除
- deleteByMap 根据Map进行删除(Map中的key为列名,value为值,根据列和值进行等值匹配)
- delete(Wrapper<T> wrapper) 根据条件构造器Wrapper进行删除
7. 自定义Sql
- 注解
@Select("select * from user")List<User> selectRaw();
- 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.example.mp.mappers.UserMapper"><select id="selectRaw" resultType="com.example.mp.po.User">SELECT * FROM user</select>
</mapper>public interface UserMapper extends BaseMapper<User> {List<User> selectRaw();
}
8. 分页插件
- 配置分页插件,在
MybatisPlusConfig
类中添加分页插件配置。
@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); // 如果配置多个插件, 切记分页最后添加// 如果有多数据源可以不配具体类型, 否则都建议配上具体的 DbTypereturn interceptor;}
- 在查询时使用
Page
对象进行分页。
@Testpublic void testPage() {LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();wrapper.ge(User::getAge, 28);// 设置分页信息, 查第3页, 每页2条数据Page<User> page = new Page<>(3, 2);// 执行分页查询Page<User> userPage = userMapper.selectPage(page, wrapper);System.out.println("总记录数 = " + userPage.getTotal());System.out.println("总页数 = " + userPage.getPages());System.out.println("当前页码 = " + userPage.getCurrent());// 获取分页查询结果List<User> records = userPage.getRecords();records.forEach(System.out::println);}
9. 代码生成器
- MyBatis Plus 提供了代码生成器,可以根据数据库表自动生成实体类、Mapper 接口、Service 类和 Controller 类。
public class Generator {public static void main(String[] args) {FastAutoGenerator.create("jdbc:mysql://localhost:3306/test?characterEncoding=utf-8","root", "").globalConfig(builder -> builder.author("aa").outputDir("your-path")).packageConfig(builder -> builder.parent("your-package").entity("entity").mapper("mapper").service("service").serviceImpl("service.impl").xml("mapper.xml")).strategyConfig(builder -> builder.entityBuilder().enableLombok()).templateEngine(new FreemarkerTemplateEngine()).execute();}
}
4.3 高级功能
1. 自动填充
通过在实体类里面的字段进行设置时间戳, create_time, update_time等字段需要自动填充
@TableField(fill = FieldFill.INSERT) // 插入时自动填充private long createTime;@TableField(fill = FieldFill.INSERT_UPDATE) // 插入/更新时自动填充private long updateTime;
自定义类 MetaObjectHandler 实现 MetaObjectHandler接口,并且去重写其两个方法:
@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {@Overridepublic void insertFill(MetaObject metaObject) {log.info("开始插入填充...");this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());}@Overridepublic void updateFill(MetaObject metaObject) {log.info("开始更新填充...");this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());}
}
2. 乐观锁(并发的情况)
乐观锁是一种并发控制机制,用于确保在更新记录时,该记录未被其他事务修改。MyBatis-Plus 提供了 OptimisticLockerInnerInterceptor 插件,使得在应用中实现乐观锁变得简单。
乐观锁的实现原理包括以下步骤:
- 读取记录时,获取当前的版本号(version)。
- 在更新记录时,将这个版本号一同传递。
- 执行更新操作时,设置 version = newVersion 的条件为 version = oldVersion。
- 如果版本号不匹配,则更新失败。
配置乐观锁插件:
@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());return interceptor;}
Entity对象version字段加上@version
注解
import com.baomidou.mybatisplus.annotation.Version;@Data
public class User {@TableIdprivate Long id;private String name;private Integer age;private String email;@Versionprivate Integer version;
}
相关文章:
Spring boot 知识整理
一、SpringBoot 背景内容梳理 SpringBoot是一个基于Spring框架的开源框架,用于简化Spring应用程序的初始搭建和开发过程。它通过提供约定优于配置的方式,尽可能减少开发者的工作量,使得开发Spring应用变得更加快速、便捷和高效。 SpringBoot…...
软件测试面试题汇总---实时更新
1. java垃圾回收机制 2. 类为什么不能多继承,而接口可以 参考为什么类之间只能单继承不能多继承,接口之间可以多继承,类与接口之间可以多实现_内部可以多继承而接口可以多实现-CSDN博客 3. java面向对象的三大特性 继承、封装、多态 4. …...
2025海外代理IP测评:Bright Data,ipfoxy,smartproxy,ipipgo,kookeey,ipidea哪个值得推荐?
近年来,随着全球化和跨境业务需求的不断扩大“海外代理IP”逐渐成为企业和个人在多样化场景中的重要工具。无论是进行数据采集、广告验证、社交媒体管理,还是跨境电商平台运营,选择合适的代理IP服务商都显得尤为重要。然而,市场上…...
蓝桥杯 8. 分巧克力
分巧克力 原题目链接 问题描述 儿童节那天有 K 位小朋友到小明家做客。小明拿出了珍藏的巧克力招待小朋友们。 小明一共有 N 块巧克力,其中第 i 块是 Hᵢ Wᵢ 的长方形。为了公平起见,小明需要从这 N 块巧克力中切出 K 块巧克力分给小朋友们。 要求…...
计算机组成原理—————计算机运算方法精讲<3>反码及移码的表示
第一部分:反码表示法 这里我们直接给出整数反码的计算公式 我们实际计算中其实不用死记硬背公式,小编在这里介绍一下求反码的秒杀技 反码秒杀技:定号取反 第一步:确定符号位是0还是1 第二步:符号位不变,…...
关于STM32创建工程文件启动文件选择
注意启动文件只要选择这几个 而不是要把所有都选上...
FC-4 mapping映射协议VI、hippi、fhcp、scma表示啥意思
FC-4 mapping映射协议VI、hippi、fhcp、scma表示啥意思 1.FC-4 Upper layer protocol协议映射层,定义了光纤通道和上层应用,包括FPGA/ARM 或者其他上层应用之间的接口。上层应用协议包括:串行scsi协议,fcp-scsi协议, f…...
15、stack、queue、deque的模拟实现
一、stack 1、stack的使用 请看这篇文章 2、stack的原理 这篇文章的栈原理讲的不错,并且有链式栈和顺序栈的创建,还有栈常使用的场景,没有数据结构基础的可以看,并且实现一下他的2种栈。 3、stack的实现 3.1、成员变量 这里…...
GR00T N1:面向通用类人机器人的开放基础模型
摘要 通用型机器人需要具备多功能的身体和智能的大脑。近年来,类人机器人的发展在构建人类世界中的通用自主性硬件平台方面展现出巨大潜力。一个经过大量多样化数据源训练的机器人基础模型,对于使机器人能够推理新情况、稳健处理现实世界的多变性以及快…...
保姆级教程:RK3588部署yolo目标检测模型
本文用到的板卡设备为鲁班猫4(LubanCat-4),瑞芯微rk3588系列处理器。 官方文档写的挺详细了,但是版本太多不统一,而且涉及了多个代码仓库,稍显杂乱。本着最少代码原则,仅需下载一个代码仓库&am…...
【含文档+PPT+源码】物联网车辆GPS定位管理系统【
项目视频介绍: 毕业作品物联台云平台的设计与实现 课程简介: 本课程演示的是一款物联网车辆GPS定位管理系统,主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Java 学习者。 1.包含:项目源码、项目文档、数据库脚…...
热烈祝贺“中芯机械”选择使用订单日记
感谢潍坊中芯机械制造有限公司选择使用订单日记! 潍坊中芯机械制造有限公司,成立于2023年,位于山东省潍坊市,是一家以从事生产、销售农业机械、汽车配件、机械电气设备等业务为主的企业。 在业务不断壮大的过程中,想…...
2025年保安员考试题库及答案
一、单选题 81、保安员张某和李某在火车站巡逻时,发现一男青年神色慌张,行为诡秘,这两名保安员识别这一可疑情况使用的方法是()。 A.查问法 B.直接观察法 C.判断法 D.视觉判断法 答案:B 82、某天&…...
ADB的安装及抓取日志(1)
一、简介 ADB(Android Debug Bridge)是一个通用命令行工具,允许你与 Android 设备进行通信。它主要用于开发和调试目的,但也可用于其他多种功能,如安装应用、运行 shell 命令、查看日志等。ADB 是 Android SDK 的一部…...
用 Iris数据做决策树分析
文章目录 Iris数据的准备1.直接从sklearn.datasets 加载或转化成文件已备本地使用2.可以在https://archive.ics.uci.edu/dataset/53/iris下载 过程示例代码如下生成的决策树如下:生成的分析报告如下: 决策树模型分析报告1. 模型性能2. 特征重要性3. 决策…...
【Bluedroid】A2DP Sink播放流程源码分析(三)
AVCTP消息处理 avrc_msg_cback /packages/modules/Bluetooth/system/stack/avrc/avrc_api.cc /******************************************************************************** Function avrc_msg_cback** Description This is the callback function used…...
概念实践极速入门 - 常用的设计模式 - 简单生活例子
概念实践极速入门 - 常用的设计模式 - 简单生活例子 SOLID 五大设计原则的首字母缩写 单一职责原则 和 开闭原则 就省略啦, 这两个概念很简单, 为了写而写反而容易误导人~* 鼓励大家字面理解! // 哎呀还是解释吧 单一(S): 单干一件事; 开闭(O): 拓展开放, 修改关…...
postgres 数据库信息解读 与 sqlshell常用指令介绍
数据库信息: sqlshell Server [localhost]: 192.168.30.101 Database [postgres]: Port [5432]: 5432 Username [postgres]: 用户 postgres 的口令: psql (15.12, 服务器 16.8 (Debian 16.8-1.pgdg1201)) 警告:psql 主版本15,服务器主版本为…...
映射网络路路径和ftp路径原理是什么,如何使用,有什么区别
文章目录 一、原理1. 映射网络路径2. FTP路径 二、使用方法1. 映射网络路径2. FTP路径 三、主要区别1. 协议与功能2. 安全性与权限3. 适用场景 四、如何选择?五、注意事项 映射网络路径(如SMB/CIFS或NFS)和FTP路径(FTP/FTPS/SFTP&…...
微服务3--服务容错
前言:本篇主要介绍服务容错与Sentinel进行限流。 高并发带来的问题 在微服务架构中,我们将业务拆分为一个个的服务,服务与服务之间都可以相互调用,但是由于网络或者说服务器本身的问题,服务不能保证100%可用ÿ…...
4.15redis点评项目下
--->接redis点评项目上 Redis优化秒杀方案 下单流程为:用户请求nginx--->访问tomcat--->查询优惠券--->判断秒杀库存是否足够--->查询订单--->校验是否是一人一单--->扣减库存--->创建订单 以上流程如果要串行执行耗时会很多,…...
Web开发-JavaEE应用原生和FastJson反序列化URLDNS链JDBC链Gadget手搓
知识点: 1、安全开发-JavaEE-原生序列化-URLDNS链分析 2、安全开发-JavaEE-FastJson-JdbcRowSetImpl链分析 利用链也叫"gadget chains",我们通常称为gadget: 1、共同条件:实现Serializable或者Externalizable接口&…...
坚持每日Codeforces三题挑战:Day 3 - 题目详解(2024-04-16,难度:900, 1200, 1200)
每天坚持写三道题第三天 (今天写点简单的,剩下去刷力扣了) 今日题目: Problem - B - Codeforces 900 Problem - B - Codeforces 1300 Problem - D - Codeforces 1400 题目一: Problem - B - Codeforces 题目大意: 给你一个数组,每次操…...
MySQL5.7递归查询
向下递归查询 SELECT ID,NAME,PARENT_ID,LEVEL_FROM(SELECT ID AS _IDS,(SELECT ID : GROUP_CONCAT(ID)FROM TREE_TABLE WHERE FIND_IN_SET(PARENT_ID,ID) > 0AND REMOVE N) T1,L : L 1 AS LEVEL_FROM TREE_TABLE,(SELECT ID : start, L: 0) T2WHERE ID IS NOT NULL) T3,…...
半导体设备通信标准—secsgem v0.3.0版本使用说明文档(2)之GEM(SEMI 30)
文章目录 1、处理器1.1、事件 2、GEM 合规性2.1、状态模型2.2、 设备加工状态2.3、 文档2.4、 控制 (作员启动)2.5、 动态事件报告配置2.6、 跟踪数据收集2.7、 报警管理2.8、 远程控制2.9、 设备常量2.10、 工艺配方管理2.11、 物料移动2.12、 设备终端…...
C++异步编程从入门到精通实战:全面指南与实战案例
C异步编程从入门到精通实战:全面指南与实战案例 在当今多核处理器普及的时代,异步编程成为了提升程序性能和响应能力的关键技术。无论是在高频交易系统、实时游戏引擎,还是网络服务器和大型数据处理平台,异步编程都发挥着至关重要…...
驱动开发硬核特训 · Day 13:从 device_create 到 sysfs,设备文件是如何生成的?
🔍 B站相应的视屏教程: 📌 内核:博文视频 - 备树深度解析:理论 实践全指南(含 of 函数与 i.MX8MP 实例) 敬请关注,记得标为原始粉丝。 🔧 📌 本文目标&#…...
肾脏系统触发 “数据包泄漏“ (血尿)与 “元数据校验异常“(蛋白尿)
肾脏系统触发 "数据包泄漏" (血尿)与 "元数据校验异常"(蛋白尿) 用计算机术语来类比。在之前的对话中,肾小球被比作防火墙或过滤器,肾小管则是回收系统。红细胞泄漏通常是因为肾小球的过滤屏障受损,而蛋白尿则可能与肾小…...
密码学(二)流密码
2.1流密码的基本概念 流密码的基本思想是利用密钥 k 产生一个密钥流...,并使用如下规则对明文串 ... 加密:。密钥流由密钥流发生器产生: ,这里是加密器中的记忆元件(存储器)在时刻 i 的状态,…...
Python 趣味学习 -数据类型脱口秀速记公式 [特殊字符]
🎤 Python数据类型脱口秀速记公式 🐍 1️⃣ 四大金刚登场 "Set叔(无序洁癖)、Tuple爷(顽固老头)、List姐(百变女王)、Dict哥(万能钥匙)"2️⃣ 特性对比RAP 🎶 内存/作用域: 全局变量 → 函数内修改 → 可变(mutable)会…...
嵌入式Linux设备使用Go语言快速构建Web服务,实现设备参数配置管理方案探究
本文探讨,利用Go语言及gin框架在嵌入式Linux设备上高效搭建Web服务器,以实现设备参数的网页配置。通过gin框架,我们可以在几分钟内创建一个功能完善的管理界面,方便对诸如集中器,集线器等没有界面的嵌入式设备的管理。…...
波束形成(BF)从算法仿真到工程源码实现-第十二节-总结
一、总结 (1)基于webrtc的非线性波束形成效果较好,复杂度较低,但是波束形成后引入了非线性,导致噪声估计不准确,降噪效果变差。 (2)MVDR使用噪声协方差矩阵对平稳噪声降噪效果比较…...
【AI】IDEA 集成 AI 工具的背景与意义
一、IDEA 集成 AI 工具的背景与意义 随着人工智能技术的迅猛发展,尤其是大语言模型的不断演进,软件开发行业也迎来了智能化变革的浪潮。对于开发者而言,日常工作中面临着诸多挑战,如代码编写的重复性劳动、复杂逻辑的实现、代码质…...
解释原型链的概念,并说明`Object.prototype.__proto__`的值是什么?
原型链是 JavaScript 中实现继承的核心机制。每个对象都有一个指向其原型对象的私有链接(通过 [[Prototype]] 内部属性),而原型对象自身也可能拥有原型,这种链式结构被称为原型链。当访问对象的属性时,若对象自身不存在…...
prototype`和`__proto__`有什么区别?如何手动修改一个对象的原型?
在 JavaScript 中,prototype 和 __proto__ 都与原型链相关,但它们的角色和用途有本质区别: 1. prototype 和 __proto__ 的区别 特性prototype__proto__归属对象仅函数对象拥有(如构造函数)所有对象默认拥有࿰…...
数据挖掘案例-电力负荷预测
今日课程 时间序列预测介绍 电力负荷预测项目开发(开发一个基于时间以及历史负荷信息,预测未来负荷的模型) 一、时间序列预测简介 1.什么是时序预测 时间序列预测是一种根据历史时间序列数据来预测未来值的方法。 任务比较好理解&#…...
SQL Server中OPENJSON + WITH 来解析JSON
一、概念 OPENJSON 是 SQL Server(2016 及更高版本) 中引入的一个表值函数,它将 JSON 文本转换为行和列的关系型数据结构。通过添加 WITH 子句,可以明确指定返回数据的结构和类型,实现 JSON 数据到表格数据的精确映射…...
在 Linux 中判断当前网络类型与网卡类型的实用方法(内外网判断 + 网卡分类)
在日常使用 Linux(例如 Jetson、树莓派、服务器)过程中,我们经常会遇到以下几个问题: 如何知道系统当前是走 有线网络还是无线网络?如何判断是连接了 公网还是内网?169.254.x.x 是什么?为什么我…...
Docker compose入门
目录 Docker Compose简介安装docker compose局限一 适合单机部署,不适合生产环境1. 架构设计目标不同2. 关键功能对比3. 生产环境的核心需求4. 适用场景总结5. 为什么 Compose 不适合生产? Docker Compose 简介 Docker Compose 是一个用于简化多容器Do…...
Docker Search 和 Docker Pull 失效解决
目录 1. Docker Search 1.1 问题描述 1.2 解决方案 1.2.1 方案1 命令行方式 1.2.2 方案2 非命令行方式 2. Docker Pull 2.1 问题描述 2.2 解决方案 2.2.1 替换镜像源 2.2.1.1 编辑镜像源(linux)版 2.2.1.2 编辑镜像源(windows版本…...
Langchain Agent封装的工具
LangChain Agent Tools 参考文档 本文档详细介绍了LangChain框架中可用的Agent工具及其使用方法。这些工具可以赋予AI智能体与外部系统和服务交互的能力,从而构建功能更强大的应用程序。 目录 工具加载方法基础工具文件和系统工具搜索和信息检索工具语言模型增强…...
Windows11删除文件时弹出提示“没有管理员权限”,怎么办?
Windows11删除文件时弹出提示“没有管理员权限”,怎么办? 原因:文件没有读取到完全控制的权限。 解决方法:点击开始-设置-账户,检查Windows是否登录管理员账户,必须登录管理员账户。然后回到电脑桌面&…...
使用HTML + CSS + JS,编写一个台球追分计分器
目录 一.代码 二.效果展示 三.该计分器的优点 一.代码 <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><…...
CS5346 - CHARTS: Chart with Point / Bar / Line / Box
文章目录 Chart with Point(点图)Scatter Chart(散点图)Pictogram(图标)Connected Scatter PlotConnected Dot plot(连接点图)Bubble Chart(气泡图) Chart wi…...
CNN实现简易教程
一、CNN基础回顾与设计原则 在开始实践之前,我们先快速回顾CNN的核心组件和设计原则,这将帮助你理解后续的代码和设计决策。 1. CNN的核心组件 卷积层(Convolutional Layer):通过卷积核提取局部特征(如边缘、纹理)。主要参数包括: 输入通道数(in_channels):输入数…...
Flask(1): 在windows系统上部署项目1
1 前言 学习python也有段时间了,最近一个小项目要部署,正好把过程写下来。 在程序的结构上我选择了w/s模式,相比于c/s模式,无需考虑客户端的升级;框架我选择了flask,就是冲着轻量级去的,就是插件…...
Zookeeper 可观测性最佳实践
Zookeeper 介绍 ZooKeeper 是一个开源的分布式协调服务,用于管理和协调分布式系统中的节点。它提供了一种高效、可靠的方式来解决分布式系统中的常见问题,如数据同步、配置管理、命名服务和集群管理等。本文介绍通过 DataKit 采集 Zookeeper 指标&#…...
vs2022使用git方法
1、创建git 2、在cmd下执行 git push -f origin master ,会把本地代码全部推送到远程,同时会覆盖远程代码。 3、需要设置【Git全局设置】,修改的代码才会显示可以提交,否则是灰色的不能提交。 4、创建的分支,只要点击…...
【探商宝】跨境关税博弈下的技术破局:从头部平台现象看数字贸易体系重构
2025年4月,某头部跨境电商平台在北美市场上演了一场教科书级的技术突围战:其移动应用在72小时内从应用商店总榜300名开外飙升至第2位,单日下载量暴增近10倍。这场现象级爆发的背后,是关税政策与数字技术深度博弈的集中呈现。作为开…...
DeepSeek是否支持动态模态选择?揭秘多模态AI的智能切换能力
什么是动态模态选择? 想象一下你在和AI助手聊天: “帮我看看这张图片里有什么?”——AI切到视觉模式 “把图片内容写成300字总结”——切回文本模式 “再把它翻译成英文语音”——切到语音模式 这种根据任务需求自动切换处理模式的能力就是…...