Mybatis_plus-逻辑删除、通用枚举、自动填充、插件等

一、逻辑删除

曾经我们写的删除代码都是物理删除。

逻辑删除:删除转变为更新

​ update user set deleted=1 where id = 1 and deleted=0

查找: 追加 where 条件过滤掉已删除数据,如果使用 wrapper.entity 生成的 where 条件也会自动追加该字段

​ 查找: select id,name,deleted from user where deleted=0

1.修改表结构

  • 给 user 表增加 deleted 字段(1代表删除0代表未删除)

    CREATE TABLE `user` (
      `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
      `name` varchar(30) DEFAULT NULL COMMENT '姓名',
      `age` int DEFAULT NULL COMMENT '年龄',
      `uemail` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '邮箱',
      `deleted` int DEFAULT '0' COMMENT '删除与否',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
    
  • 修改字段的方式

    ALTER TABLE user ADD column `deleted` int DEFAULT '0' COMMENT '删除与否';
    

2.开启配置支持

  • 配置com.baomidou.mybatisplus.core.config.GlobalConfig$DbConfig

    mybatis-plus:
      global-config:
        db-config:
          logic-delete-value: 1 # 逻辑已删除值(默认为 1)
          logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
    

3.@TableLogic

  • 实体类字段上加上@TableLogic注解

    @Data
    public class User {
        @TableId(type = IdType.AUTO)
        private Long id;
        private String name;
        @TableField(select = false)
        private Integer age;
        @TableField(value = "uemail")
        private String email;
        @TableLogic
        private Integer deleted;
    }
    

4.测试

  • 测试删除

    @Test
    public void testLogicDeleted(){
        int ret = userMapper.deleteById(3L);
        System.out.println("删除受影响行数为:"+ret);
    }
    
  • 结果

    ==>  Preparing: UPDATE user SET deleted=1 WHERE id=? AND deleted=0
    ==> Parameters: 3(Long)
    <==    Updates: 1
    
  • 测试查询

    @Test
    public void testLogicDeletedSelect(){
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        List<User> user = userMapper.selectList(wrapper);
        System.out.println(user);
    }
    
  • 结果

    ==>  Preparing: SELECT id,name,uemail AS email,deleted FROM user WHERE deleted=0
    ==> Parameters: 
    <==      Total: 3
    
  • 数据库结果

    在这里插入图片描述

二、通用枚举

解决了繁琐的配置,让 mybatis 优雅的使用枚举属性! 从 3.5.2 版本开始只需完成 步骤1: 声明通用枚举属性 即可使用

1.修改表结构

  • 添加性别字段

    ALTER TABLE user ADD column `sex` int DEFAULT '1' COMMENT '1-0-女';
    

2.声明通用枚举属性

  • 枚举

    public enum SexEnum implements IEnum<Integer> {
        MAN(1, "男"),
        WOMAN(0, "女");
    
        private int value;
        private String desc;
    
        SexEnum(int value,String desc){
            this.value = value;
            this.desc = desc;
        }
    
        @Override
        public Integer getValue() {
            return this.value;
        }
    
        @Override
        public String toString() {
            return this.desc;
        }
    }
    

3.实体属性使用枚举类型

  • 实体属性添加枚举类型

    @Data
    public class User {
        @TableId(type = IdType.AUTO)
        private Long id;
        private String name;
        @TableField(select = false)
        private Integer age;
        @TableField(value = "uemail")
        private String email;
        @TableLogic
        private Integer deleted;
        private SexEnum sex;
    }
    

4.额外补充

如果是3.5.2版本之后的不需要配置了

  • 之前版本的按如下配置

    mybatis-plus:
        # 支持统配符 * 或者 ; 分割
        typeEnumsPackage: com.baomidou.springboot.entity.enums
    
  • 序列化给前端按如下两种方式都可以实现

4.1Fastjson

  • 添加如下注解

    @JSONField(serialzeFeatures= SerializerFeature.WriteEnumUsingToString)
    private UserStatus status;
    

4.2 jackson

  • 添加如下注解

    @JsonValue	//标记响应json值
    private final int code;
    

5.测试

  • 测试

    @Test
    public void testEnum(){
        User entity = new User();
        entity.setEmail("erew");
        entity.setAge(19);
        entity.setName("小红");
        entity.setSex(SexEnum.MAN);
        int insert = userMapper.insert(entity);
        System.out.println("受影响行数为:"+insert);
    }
    
  • 结果

    ==>  Preparing: INSERT INTO user ( name, age, uemail, sex ) VALUES ( ?, ?, ?, ? )
    ==> Parameters: 小红(String), 19(Integer), erew(String), 1(Integer)
    <==    Updates: 1
    
  • 数据库结果

    在这里插入图片描述

三、自动填充功能

开发中,比如

  • 插入数据的时候需要插入创建时间

  • 更新数据的时候需要添加更新时间

1.修改表结构

  • 修改表结构

    CREATE TABLE `user` (
      `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
      `name` varchar(30) DEFAULT NULL COMMENT '姓名',
      `age` int DEFAULT NULL COMMENT '年龄',
      `uemail` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '邮箱',
      `deleted` int DEFAULT '0' COMMENT '删除与否',
      `sex` int DEFAULT '1' COMMENT '性别',
      `create_time` datetime DEFAULT NULL COMMENT '创建时间',
      `update_time` datetime DEFAULT NULL COMMENT '更新时间',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
    

2.@TableField

  • FieldFill

    public enum FieldFill {
        DEFAULT,//不处理
        INSERT,//插入查出
        UPDATE,//更新处理
        INSERT_UPDATE;//插入和更新处理
    }
    
  • 添加字段

    @TableField(value = "create_time",fill = FieldFill.INSERT)
    private Date createTime;
    @TableField(value = "update_time",fill = FieldFill.UPDATE)
    private Date updateTime;
    

3.自定义实现类 MyMetaObjectHandler

  • 自定义实现类 MyMetaObjectHandler

    @Slf4j
    @Component
    public class MyMetaObjectHandler implements MetaObjectHandler {
        @Override
        public void insertFill(MetaObject metaObject) {
            log.info("start insert fill ....");
            setFieldValByName("createTime",new Date(),metaObject);
        }
    
        @Override
        public void updateFill(MetaObject metaObject) {
            log.info("start update fill ....");
            setFieldValByName("updateTime",new Date(),metaObject);
        }
    }
    

4.测试

  • 测试插入操作

    @Test
    public void testFillInsert(){
        User entity = new User();
        entity.setEmail("erew");
        entity.setAge(19);
        entity.setName("小红");
        entity.setSex(SexEnum.MAN);
        int insert = userMapper.insert(entity);
        System.out.println("受影响行数为:"+insert);
    }
    
  • 测试结果

    ==>  Preparing: INSERT INTO user ( name, age, uemail, sex, create_time ) VALUES ( ?, ?, ?, ?, ? )
    ==> Parameters: 小红(String), 19(Integer), erew(String), 1(Integer), 2022-12-03 11:34:41.169(Timestamp)
    <==    Updates: 1
    
  • 测试更新操作

    @Test
    public void testFillUpdate(){
        User entity = new User();
        entity.setId(15L);
        entity.setEmail("erew");
        entity.setAge(19);
        entity.setName("小红");
        entity.setSex(SexEnum.MAN);
        int insert = userMapper.updateById(entity);
        System.out.println("受影响行数为:"+insert);
    }
    
  • 测试结果

    ==>  Preparing: UPDATE user SET name=?, age=?, uemail=?, sex=?, update_time=? WHERE id=? AND deleted=0
    ==> Parameters: 小红(String), 19(Integer), erew(String), 1(Integer), 2022-12-03 11:37:10.716(Timestamp), 15(Long)
    <==    Updates: 1
    
  • 数据库结果

    在这里插入图片描述

四、SQL注入器

1.SQL注入的原理分析

MyBatisPlus 是使用 ISqlInjector 接口负责SQL注入工作

在这里插入图片描述

  • 具体实现注入

    public void inspectInject(MapperBuilderAssistant builderAssistant, Class<?> mapperClass) {
            Class<?> modelClass = ReflectionKit.getSuperClassGenericType(mapperClass, Mapper.class, 0);
            if (modelClass != null) {
                String className = mapperClass.toString();
                Set<String> mapperRegistryCache = GlobalConfigUtils.getMapperRegistryCache(builderAssistant.getConfiguration());
                if (!mapperRegistryCache.contains(className)) {
                    TableInfo tableInfo = TableInfoHelper.initTableInfo(builderAssistant, modelClass);
                    List<AbstractMethod> methodList = this.getMethodList(mapperClass, tableInfo);
                    if (CollectionUtils.isNotEmpty(methodList)) {
                        methodList.forEach((m) -> {
                            m.inject(builderAssistant, mapperClass, modelClass, tableInfo);
                        });
                    } else {
                        this.logger.debug(mapperClass.toString() + ", No effective injection method was found.");
                    }
    
                    mapperRegistryCache.add(className);
                }
            }
    
        }
    
  • 实际的实现代码

    methodList.forEach((m) -> {
                            m.inject(builderAssistant, mapperClass, modelClass, tableInfo);
                        });
    
  • m.inject 调用具体方法

    this.injectMappedStatement(mapperClass, modelClass, tableInfo);			
    
  • 最终具体的执行就是自己定义的类

    在这里插入图片描述

2.扩充BaseMapper中方法

2.1编写自己的BaseMapper

  • 编写MyBaseMapper

    public interface MyBaseMapper<T> extends BaseMapper<T> {
        List<T> listAll();
    }
    
  • 需要用到的mapper 直接继承即可

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

2.2编写MySqlInjector

  • MySqlInjector

    @Component	
    public class MySqlInjector extends DefaultSqlInjector {
        @Override
        public List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo) {
            //默认的mybatis-plus 的注入方法
            List<AbstractMethod> methodList = super.getMethodList(mapperClass, tableInfo);
            //添加自己的 listAll 类
            methodList.add(new ListAll());
            return methodList;
        }
    }
    

2.3编写ListAll类

  • 创建ListAll 类

    public class ListAll extends AbstractMethod {
        @Override
        public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
            String sqlMethod = "listAll";
            String sql = "select * from "+tableInfo.getTableName();
            SqlSource sqlSource = this.languageDriver.createSqlSource(this.configuration, sql, modelClass);
            return this.addSelectMappedStatementForTable(mapperClass,sqlMethod,sqlSource,tableInfo);
        }
    }
    

2.4测试

  • 测试

    @Test
    public void testInjector(){
        List<User> users = userMapper.listAll();
        System.out.println(users);
    }
    
  • 结果

    ==>  Preparing: select * from user
    ==> Parameters: 
    <==      Total: 13
    

五、插件

1.拦截器核心代码

MybatisPlusInterceptor

该插件是核心插件,目前代理了 Executor#queryExecutor#updateStatementHandler#prepare 方法

  • 拦截器核心代码

    @Intercepts({
            @Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class}),
    })
    @Component
    public class MyInterceptor implements Interceptor {
        @Override
        public Object intercept(Invocation invocation) throws Throwable {
            System.out.println("拦截前操作");
            //做拦截操作
            return invocation.proceed();
        }
    
        @Override
        public Object plugin(Object target) {
            System.out.println("装配插件");
            //装配插件
            return Plugin.wrap(target, this);
        }
    
        @Override
        public void setProperties(Properties properties) {
            System.out.println("设置属性");
            //属性设置
        }
    }
    
  • 交给容器管理即可实现拦截操作

2.分页插件

  • 使用

    @Configuration
    @MapperScan("cn.sycoder.mapper")
    public class MybatisPlusConfig {
        @Bean
        public MybatisPlusInterceptor mybatisPlusInterceptor() {
            MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
            interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
            return interceptor;
        }
    }
    

3.乐观锁插件

OptimisticLockerInnerInterceptor

当要更新一条记录的时候,希望这条记录没有被别人更新
乐观锁实现方式:

  • 取出记录时,获取当前 version
  • 更新时,带上这个 version
  • 执行更新时, set version = newVersion where version = oldVersion
  • 如果 version 不对,就更新失败

3.1乐观锁补充

  • 在数据库增加一个 version 字段来管理数据,假设没有其它人操作过这条数据,先读取本条数据的version,然后再修改的时候,判断之前拿出来的version 和现在的version是否一致,如果不一致,则表示被人操作过,不能够正常实现更新

  • sql 演示

    update user set age = 123123,version = version+1  where id = 16 and version = 0;
    

    在这里插入图片描述

3.2添加乐观锁配置

  • 添加配置

    @Configuration
    @MapperScan("cn.sycoder.mapper")
    public class MybatisPlusConfig {
        @Bean
        public MybatisPlusInterceptor mybatisPlusInterceptor() {
            MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
            interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
            interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
            return interceptor;
        }
    }
    

3.3修改表结构

  • 表结构

    CREATE TABLE `user` (
      `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
      `name` varchar(30) DEFAULT NULL COMMENT '姓名',
      `age` int DEFAULT NULL COMMENT '年龄',
      `uemail` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '邮箱',
      `deleted` int DEFAULT '0' COMMENT '删除与否',
      `sex` int DEFAULT '1' COMMENT '性别',
      `create_time` datetime DEFAULT NULL COMMENT '创建时间',
      `update_time` datetime DEFAULT NULL COMMENT '更新时间',
      `version` int DEFAULT NULL COMMENT '乐观锁控制',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
    

3.4添加 version 字段

  • 实体添加字段

    @Version
    private Integer version;
    

3.5测试

  • 测试乐观锁

    @Test
    public void testVersion(){
        User user = userMapper.selectById(16L);
        user.setName("云哥666");
        int count = userMapper.updateById(user);
        System.out.println("受影响行数:"+count);
    }
    
  • 结果

    ==>  Preparing: UPDATE user SET name=?, uemail=?, sex=?, create_time=?, update_time=?, version=? WHERE id=? AND version=? AND deleted=0
    ==> Parameters: 云哥666(String), sy@qq.com(String), 1(Integer), 2022-12-03 11:34:41.0(Timestamp), 2022-12-03 17:44:05.425(Timestamp), 3(Integer), 16(Long), 2(Integer)
    <==    Updates: 1
    

4.防全表更新与删除插件

BlockAttackInnerInterceptor

针对 update 和 delete 语句 作用: 阻止恶意的全表更新删除

4.1配置拦截器

  • 配置

    @Configuration
    @MapperScan("cn.sycoder.mapper")
    public class MybatisPlusConfig {
        @Bean
        public MybatisPlusInterceptor mybatisPlusInterceptor() {
            MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
            interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
            interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
            interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
            return interceptor;
        }
    }
    

4.2测试

  • 测试全表删除

    @Test
    public void testDeleteAll(){
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        int count = userMapper.delete(wrapper);
        System.out.println("受影响行数:"+count);
    }
    

六、代码生成器

  • 简化开发流程,提高开发效率,让程序写很少的代码就能实现开发

1.创建 mybatis-plus-02 模块

  • 任选创建方式创建

2.添加依赖

  • 依赖

    <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.7.5</version>
        </parent>
    
        <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>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
            </dependency>
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>3.5.2</version>
            </dependency>
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-generator</artifactId>
                <version>3.5.2</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-freemarker</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.freemarker</groupId>
                <artifactId>freemarker</artifactId>
                <version>2.3.31</version>
            </dependency>
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger-ui</artifactId>
                <version>2.10.1</version>
            </dependency>
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger2</artifactId>
                <version>2.10.1</version>
            </dependency>
        </dependencies>
    

3.使用

  • 使用

    public static void main(String[] args) {
            FastAutoGenerator.create("jdbc:mysql://localhost:3306/mybatis-plus", "root", "123456")
                    .globalConfig(builder -> {
                        builder.author("sy") // 设置作者
                                .enableSwagger() // 开启 swagger 模式
                                .fileOverride() // 覆盖已生成文件
                                .outputDir("F:\\03-Spring\\MyBatisPlus\\homework\\mybatis-plus-02\\src\\main\\java\\"); // 指定输出目录
                    })
                    .packageConfig(builder -> {
                        builder.parent("cn") // 设置父包名
                                .moduleName("sycoder") // 设置父包模块名
                                .pathInfo(Collections.singletonMap(OutputFile.xml, "F:\\03-Spring\\MyBatisPlus\\homework\\mybatis-plus-02\\src\\main\\resources\\cn\\sycoder")); // 设置mapperXml生成路径
                    })
                    .strategyConfig(builder -> {
                        builder.addInclude("user"); // 设置需要生成的表名
    //                            .addTablePrefix("t_", "c_"); // 设置过滤表前缀
                    })
                    .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
                    .execute();
    
        }
    

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【NR 定位】3GPP NR Positioning 5G定位标准解读(五)

前言 3GPP NR Positioning 5G定位标准&#xff1a;3GPP TS 38.305 V18 3GPP 标准网址&#xff1a;Directory Listing /ftp/ 【NR 定位】3GPP NR Positioning 5G定位标准解读&#xff08;一&#xff09;-CSDN博客 【NR 定位】3GPP NR Positioning 5G定位标准解读&#xff08;…

扑克牌翻牌记忆小游戏源码

源码由HTMLCSSJS组成&#xff0c;双击html文件可以本地运行效果&#xff0c;也可以上传到服务器里面 效果预览 下载地址 https://www.qqmu.com/2296.html

Spring学习笔记(七)SpringMVC入门

一.什么是Spring MVC 1.什么是MVC&#xff08;一种思想模式&#xff09; M:模型 V:视图 C:控制器 2、Java EE三层架构 在Java EE开发中&#xff0c;系统经典的三层架构包括表现层、业务层和持久层。 表现层&#xff08;Web层&#xff09;负责接收客户端请求&#xff0c;并…

Linux基本指令(下)

目录 1. less指令 2. head与tail指令 3. find指令 示例 4. grep指令 示例 ​编辑 5. zip/unzip 打包与压缩 示例 ​编辑 6. tar指令 7. find指令&#xff1a; -name 8. echo指令 9. 时间相关的指令 1.在显示方面&#xff0c;使用者可以设定欲显示的格式&#xff…

更详细的软件测试理论基础:流程,开发、测试模型,测试分类,测试用例及其设计方法,缺陷

文章目录 一、测试流程二、开发模型1、 瀑布模型2、增量模型3、快速模型4、其他 三、测试模型1、V模型2、W模型 四、测试分类五、测试用例 test case六、测试用例设计方法1、等价类划分法2、边界值分析法3、因果图法4、判定表法5、正交法6、场景法7、流程分析法8、错误推测法方…

OpenAI回击马斯克的起诉:GPT-4不是AGI,所以没必要开源

前情提要 上一集我们讲到&#xff0c;马斯克起诉了OpenAI&#xff0c;扬言其背叛了公司成立时达成的一项协议&#xff0c;即开发技术的目的是“造福人类”而非利润。 “OpenAI已经变成了微软的一个闭源形态的实际子公司。在其新的董事会领导下&#xff0c;公司不仅在开发&…

FreeCad 有限元分析入门

2024.3 最新版本 0.21.2 FreeCad 有限元分析入门 基本步骤&#xff1a; 一、零件制作 1、创建立方体 2、修改参数 二、建立力学分析 1、为零件附着材料 2、增加固定约束 3、增加均布在表面的受力 4、零件网格化 …

Decoupled Knowledge Distillation解耦知识蒸馏

Decoupled Knowledge Distillation解耦知识蒸馏 现有的蒸馏方法主要是基于从中间层提取深层特征&#xff0c;而忽略了Logit蒸馏的重要性。为了给logit蒸馏研究提供一个新的视角&#xff0c;我们将经典的KD损失重新表述为两部分&#xff0c;即目标类知识蒸馏&#xff08;TCKD&a…

2024 年广东省职业院校技能大赛(高职组)“云计算应用”赛项样题 2

#需要资源或有问题的&#xff0c;可私博主&#xff01;&#xff01;&#xff01; #需要资源或有问题的&#xff0c;可私博主&#xff01;&#xff01;&#xff01; #需要资源或有问题的&#xff0c;可私博主&#xff01;&#xff01;&#xff01; 某企业根据自身业务需求&#…

第八节 龙晰Anolis 8.8 安装 DDE 桌面环境

一、前言 最小化安装的龙晰 Anolis OS 8.8 是不带图形化界面的&#xff0c;只能使用命令行&#xff0c;有些时候需要用到桌面环境&#xff0c;而DDE (Deepin Desktop Enviroment) 就是很好的桌面环境&#xff0c;它是指龙晰 Anolis 所搭载的中国自主桌面环境&#xff0c;用起来…

常数项级数

定义 级数的形式如下&#xff1a; ∑ n 1 ∞ u n u 1 u 2 u 3 . . . u n . . . \sum_{n1}^{\infin}u_n u_1u_2u_3...u_n... n1∑∞​un​u1​u2​u3​...un​... 这个数列的项数是无穷多个&#xff0c;如果取其前n项 S n u 1 u 2 . . . u n S_n u_1u_2...u_n Sn…

Java集合相关面试题(2024大厂高频面试题系列)

1、说一说Java提供的常见集合&#xff1f;&#xff08;画一下集合结构图&#xff09; 在java中提供了量大类的集合框架&#xff0c;主要分为两类&#xff1a; 第一个是Collection 属于单列集合&#xff0c;第二个是Map 属于双列集合 在Collection中有两个子接口List和Set。…

C#中多语言编程原理及实例解析

文章目录 一、了解C#多语言编程原理1. 通用语言运行库&#xff08;CLR&#xff09;2. 通用类型系统&#xff08;CTS&#xff09;3. 微软中间语言&#xff08;MSIL&#xff09;4. 元数据和反射5. 公共语言规范&#xff08;CLS&#xff09; 二、实例说明 一、了解C#多语言编程原理…

sql基本语法+实验实践

sql语法 注释&#xff1a; 单行 --注释内容# 注释内容多行 /* 注释内容 */数据定义语言DDL 查询所有数据库 show databases;注意是databases而不是database。 查询当前数据库 select database();创建数据库 create database [if not exists] 数据库名 [default charset 字符…

大话设计模式——4.装饰模式(Decorator Pattern)

1.定义 1&#xff09;可以在不改动原有对象代码的情况下扩展对象的功能&#xff0c;通过聚合的方式相较于继承更加灵活。 2&#xff09;UML图 2.示例 汽车有很多装饰可选&#xff0c;如座椅、音响、轮胎等都可以进行自定义组装 1&#xff09;抽象汽车对象 public interfac…

【yolov8部署实战】VS2019环境下使用Onnxruntime环境部署yolov8目标检测|含源码

一、前言 部署yolo项目&#xff0c;是我这几个月以来做的事情&#xff0c;最近打算把这几个月试过的方法&#xff0c;踩过的坑&#xff0c;以博客的形式&#xff0c;分享一下。关于下面动态中讲到的如何用opencv部署&#xff0c;我在上一篇博客中已经详细讲到了&#xff1a;【…

项目-论坛系统

基于Spring前后端分离版本的论坛系统。 1、构建项目结构 common公共类&#xff1a;统一返回结果、全局变量、异常枚举信息config配置类&#xff1a;Swagger&#xff0c;用于自动生成CRUD和基本对象controller控制器类&#xff1a;用于接受前端信息和控制路由dao数据库访问类&…

LeetCode206题:反转链表(python3)

采用递归 class Solution:def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:cur headpre Nonewhile cur:temp cur.next # 保存下一轮循环的节点cur.next pre # 将当前节点 cur 的指针指向上一个节点 prepre curcur tempreturn pre

前缀和算法题(区间次方和、小蓝平衡和、大石头的搬运工、最大数组和)

一、前缀和的原理和特点 prefix表示前缀和&#xff0c;前缀和由一个用户输入的数组生成。对于一个数组a[]&#xff08;下标从1开始&#xff09;&#xff0c;我们定义一个前缀和数组prefix[]&#xff0c;满足&#xff1a; prefix有一个重要的特性&#xff0c;可以用于快速生成p…

sql注入之sqli-labs-less-1 错误注入

输入?id1 得到登录页面&#xff1a; 通过order by 函数试探&#xff1a; 5的时候报错 试探到3 的时候返回正确的值&#xff1a; 然后继续注入&#xff1a;?id -1 union select 1,2,3 -- 查看回显点&#xff1a; 开始查看数据库内容&#xff1a;id-1 union select 1,databa…