MyBatis-Plus的入门学习

news2024/11/25 21:27:00

简介

MyBatis-Plus是MyBatis的增强工具,在MyBatis的基础上做出增强改变,简化开发,提高效率

mybatis-plus的官网链接

特性

mybatis-plus官网的特性详解

快速开始

第一步:创建一张表

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

第二步:插入对应数据

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

第三步:初始化一个项目工程

在这里插入图片描述

第四步:引入依赖

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0+ 版本</version>
    <relativePath/>
</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>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>最新版本</version>
    </dependency>
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <scope>runtime</scope>
    </dependency>
</dependencies>

第五步:配置数据库连接信息

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

第五步:在SpringBoot项目的启动类中添加**@MapperScan注解**,用于对mapper的扫描

package com.example.mpdemo001;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("com.example.mpdemo001.mapper")
public class Mpdemo001Application {
    public static void main(String[] args) {
        SpringApplication.run(Mpdemo001Application.class, args);
    }

}

第六步:编码

实体类:

package com.example.mpdemo001.bean;

import lombok.Data;

/**
 * @Title: User
 * @Package com.example.mpdemo001.bean
 * @Author: CXY
 * @Copyright CXY
 * @CreateTime: 2023/3/9 12:35
 */
@Data
public class User {
    private Long id;
    private String name;
    private Integer age;
    private String email;
}

mapper接口(MyBatis-Plus不需要在接口中写很多方法,只需要继承 BaseMapper< T>即可,T表示泛型

package com.example.mpdemo001.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.mpdemo001.bean.User;
import org.apache.ibatis.annotations.Mapper;

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

**注意:**在mapper接口上面需要添加一个@Mapper的注解,用于将Mapper接口加入Spring管理

第七步:测试

package com.example.mpdemo001;

import com.example.mpdemo001.bean.User;
import com.example.mpdemo001.mapper.UserMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

@SpringBootTest
public class Mpdemo001ApplicationTests {

    @Autowired
    private UserMapper userMapper;

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


    }

}

UserMapper 中的 selectList() 方法的参数为 MP 内置的条件封装器 Wrapper,所以不填写就是无任何条件

测试结果:

User(id=1, name=Jone, age=18, email=test1@baomidou.com)
User(id=2, name=Jack, age=20, email=test2@baomidou.com)
User(id=3, name=Tom, age=28, email=test3@baomidou.com)
User(id=4, name=Sandy, age=21, email=test4@baomidou.com)
User(id=5, name=Billie, age=24, email=test5@baomidou.com)

可以配置MyBatis-Plus的日志文件,这样可以看到详细的SQL语句实现过程

日志文件的配置如下:

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

MyBatis-Plus的注解详解

@Tableld

IdType:顾名思义即表示主键的类型

主键生成策略

参考资料:分布式系统唯一ID生成方案汇总:https://www.cnblogs.com/haoxinyue/p/5208136.htm

1、数据库自动增长 AUTO

这个是指在建表的时候可以直接设置id自增,这样的话idType即为AUTO;

**缺点:**这样id自增的主键,不利于数据库的分表实现,因为id是按顺序递增的,所以每一次分表的时候都需要知道前一张表的最后一个id的值,再那个基础上进行id加一的操作

2、UUID

每次生成随机唯一的值

**优点:**每次分表的时候不需要知道上一张表的最后一个元素的id值

**缺点:**id无法进行排序

3、Redis生成id

Redis是单线程的,所以也可以用来生成全局唯一的id,可以用Redis的原子操作INCRINCRBY来实现

但是使用这个来进行id生成的时候,需要指定初始值和步长

使用Redis集群可以防止单点故障的问题

单点故障:(英语:single point of failure,缩写SPOF)是指系统中一点失效,就会让整个系统无法运作的部件,换句话说,单点故障即会整体故障。

**优点:**不依赖于数据库,灵活方便,且性能优于数据库,数字id天然排序,对分页或者需要排序的结果很有帮助

**缺点:**如果系统中没有Redis,还需引入新的主键,增加系统的复杂度;需要编码和配置的工作量比较大

4、MP主键自动生成

mp可以通过雪花算法自动生成一个19位数字的id,

@TableName

  • 描述:表名注解,标识实体类对应的表
  • 使用位置:实体类

在这里插入图片描述

@TableField

  • 描述:字段注解(非主键)

自动填充

将数据自动填充进去

项目中经常会遇到一些数据,每次都使用相同的方式填充,例如记录的创建时间,更新时间等。 我们可以使用MyBatis Plus的自动填充功能,完成这些字段的赋值工作

具体实现过程:

在实体类中需要自动进行自动填充的对象上面添加注解:**@TableField(fill=FieldFill.Xxx)**FieldFill的取值:

在这里插入图片描述

然后创建一个类用于实现MetaObjectHandler接口,实现接口中的方法,

注意:需要在这个类上面添加注解,让Spring进行管理

package com.example.mpdemo001.bean;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;

import java.util.Date;

/**
 * @Title: MyBatisMeta
 * @Package com.example.mpdemo001.bean
 * @Author: CXY
 * @Copyright CXY
 * @CreateTime: 2023/3/10 14:02
 */
@Component
//这个不能忘,忘了就无法进行了
public class MyBatisMeta implements MetaObjectHandler {
    @Override
    public void insertFill(MetaObject metaObject) {
        //插入时间,第一次创建的时候,需要插入创建时间和更新时间
        this.setFieldValByName("createTime",new Date(),metaObject);
        this.setFieldValByName("updateTime",new Date(),metaObject);
        
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        //每一次更新数据的时候,插入时间
        this.setFieldValByName("updateTime",new Date(),metaObject);
        

    }
}

测试结果:

在这里插入图片描述

测试方法:

update

@Test
public void testUpdateById(){
    User user=new User();
    user.setId(1L);
    user.setName("战三");
    int i = userMapper.updateById(user);
    System.out.println(i);

}

结果:
在这里插入图片描述

注意:update生成的是动态sql

乐观锁

针对一种特定问题的解决方案,主要解决的是丢失更新的问题

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

如果不考虑事务的隔离性的话,会产生的问题有:

1、产生读问题:脏读,不可重复读,幻读

2、产生写问题:丢失更新(就是指多个人同时修改同一条数据,最后提交的把之前提交的数据覆盖了

解决丢失更新问题:

悲观锁:串行,只有一个人能在当前情况下进行操作

乐观锁:添加了一个version版本号,当一个人在进行数据操作的时候,提交数据时会比较当前数据版本号和数据库中的版本号是否一直,如果一致则可以进行修改,修改后版本号进行加一的操作。反之不能进行修改。

**乐观锁的使用例子有:**12306抢票系统,当别人把最后一张票抢走之后,另外的人就不能再进行抢票了

乐观锁的使用流程:

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

当有很多配置的时候,建议新建一个配置类,将所有配置写在配置类中

package com.example.mpdemo001.config;

import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @Title: MyBatisConfigurations
 * @Package com.example.mpdemo001.config
 * @Author: CXY
 * @Copyright CXY
 * @CreateTime: 2023/3/10 15:12
 */
@Configuration
@MapperScan("com.example.mpdemo001.mapper")
public class MyBatisConfigurations {
    /**
     * 乐观锁插件
    *
     * 新版
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return mybatisPlusInterceptor;
    }

    }

测试成功代码:

@Test
public void testOptimisticLockerFail() {
    User user = userMapper.selectById(1l);
    user.setName("死亡法师");
    user.setAge(10000);
 
    int i = userMapper.updateById(user);
    System.out.println(i);
}

测试成功的结果

在这里插入图片描述

测试失败代码:

@Test
public void testOptimisticLockerFail() {
    User user = userMapper.selectById(2l);
    user.setName("哈利波特");
    user.setAge(300);
    //模拟取出数据后,数据库中version实际数据比取出的值大,即已被其它线程修改并更新了version
    user.setVersion(user.getVersion()-1);
    int i = userMapper.updateById(user);
    System.out.println(i);
}

结果:

在这里插入图片描述

select

查所有

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

结果
在这里插入图片描述

根据id查

在这里插入图片描述

多个id批量查询

在这里插入图片描述

简单条件查询(通过map封装条件)

在这里插入图片描述

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

分页

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

添加插件:

/**
 * 分页插件(官网最新)
 */
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor1() {
    MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
    interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
    return interceptor;
}

测试分页实现:

@Test
public void testPageSelect(){
    Page page=new Page<>(1,3);
    userMapper.selectPage(page, null);
    page.getRecords().forEach(System.out::println);
    System.out.println(page.getCurrent());
    System.out.println(page.getPages());
    System.out.println(page.getSize());
    System.out.println(page.getTotal());
    System.out.println(page.getRecords());


}

测试结果

在这里插入图片描述

分页的各个属性:

在这里插入图片描述

delete

根据id删除

@Test
public void testDeletedById(){
    int i = userMapper.deleteById(4l);
    System.out.println(i);
}

批量删除

@Test
public void testDeletedByIds(){
    int i = userMapper.deleteBatchIds(Arrays.asList(1, 2, 3));
    System.out.println(i);
}

简单的条件查询删除

@Test
public void testDeleteByMap(){
    HashMap<String,Object> hashMap=new HashMap<>();
    hashMap.put("name","Tom");
    hashMap.put("age",28);
    int i = userMapper.deleteByMap(hashMap);
    System.out.println(i);
}

逻辑删除

逻辑删除就是指在数据中多加一个标志属性,删除的时候只对该属性进行修改,而不是真正的删除数据,逻辑删除有利于数据的恢复

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

在这里插入图片描述

在实体类上添加deleted属性

@TableLogic
@TableField(fill = FieldFill.INSERT)
private Integer deleted;

如果想修改默认属性值,则可在application.properties中进行配置

默认0表示未被删除,1表示被删除

在这里插入图片描述

在配置类中注册bean

@Bean
public ISqlInjector sqlInjector() {
    return new LogicSqlInjector();
}

高版本不用配置插件了,上述java代码无需编写。

测试删除:

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

在这里插入图片描述

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

性能分析

在配置类中添加性能优化插件

@Profile({“dev”,“test”})表示对什么环境起作用

dev:开发环境

test:测试环境

prod:生产环境,项目部署好之后的环境 最好不要在这里使用性能优化插件

环境配置在配置文件中设置:

spring.profile.active=xxx(dev,test,prod)

**参数:**maxTime: SQL 执行最大时长,超过自动停止运行,有助于发现问题。

**参数:**format: SQL是否格式化,默认false

Wrapper

在这里插入图片描述

  1. Wrapper : 条件构造抽象类,最顶端父类
  2. AbstractWrapper : 用于查询条件封装,生成 sql 的 where 条件
  3. QueryWrapper : Entity 对象封装操作类,不是用lambda语法(使用较多
  4. UpdateWrapper : Update 条件封装,用于Entity对象更新操作
  5. AbstractLambdaWrapper : Lambda 语法使用 Wrapper统一处理解析 lambda 获取 column。
  6. LambdaQueryWrapper :看名称也能明白就是用于Lambda语法使用的查询Wrapper
  7. LambdaUpdateWrapper : Lambda 更新封装Wrapper

wrapper条件构造器测试

1、ge、gt、le、lt、isNull、isNotNull

@Test
public void testQueryWrapper(){
    QueryWrapper<User> queryWrapper=new QueryWrapper<>();
    queryWrapper
            .isNull("email")
            .ge("age",30)
            .isNotNull("name");
    //上面代码可以表示多个条件
    int delete = userMapper.delete(queryWrapper);
    System.out.println(delete);
}

gt:大于;ge:大于等于;le:小于;lt:小于等于

2、eq、ne

eq表示等于

ne表示不等于

@Test
public void testSelectOne() {
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("name", "Tom");
    User user = userMapper.selectOne(queryWrapper);
    System.out.println(user);
}

注意:selectOne方法返回的是一条实体记录,如果返回多条时,会报错

3、between、notBetween

是包含边界值的查询条件

需要注意小值在前,大值在后

@Test
public void testSelectCount() {
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    queryWrapper.between("age", 20, 30);
    Long count = userMapper.selectCount(queryWrapper);
    System.out.println("==============="+count);
}

4、allEq

多条件均相等

@Test
public void testSelectList() {
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    Map<String, Object> map = new HashMap<>();
    map.put("id", 2);
    map.put("name", "Jack");
    map.put("age", 20);
    queryWrapper.allEq(map);
    List<User> users = userMapper.selectList(queryWrapper);
    users.forEach(System.out::println);
}

5、like、notLike、likeLeft、likeRight

like:模糊查询,表示like %内容%

notLike:不包含

likeLeft:表示like %内容

likeRight:表示 like 内容%

@Test
public void testQuerrySelectMaps() {
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    queryWrapper
            .notLike("name","san")
            .likeRight("email","test1");
    List<Map<String, Object>> maps = userMapper.selectMaps(queryWrapper);
    maps.forEach(System.out::println);


}

6、in、notIn、inSql、notInSql、exists、notExists

in notIn用法如下:

notIn(“age”,{1,2,3})—>age not in (1,2,3)

notIn(“age”, 1, 2, 3)—>age not in (1,2,3)

inSql、notInSql可以实现子查询

@Test
    public void testSelectObjs() {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
//queryWrapper.in("id", 1, 2, 3);
        queryWrapper.inSql("id", "select id from user where id < 3");
        List<Object> objects = userMapper.selectObjs(queryWrapper);//返回值是Object列表
        objects.forEach(System.out::println);
    }

7、or、and

不调用or则默认为使用 and 连

8、嵌套or、嵌套and

这里使用了lambda表达式,or中的表达式最后翻译成sql时会被加上圆括号

 @Test
    public void testUpdate2() {
//修改值
        User user = new User();
        user.setAge(99);
        user.setName("Andy");
//修改条件
        UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();
        userUpdateWrapper
                .like("name", "h")
                .or(i -> i.eq("name", "李白").ne("age", 20));
//        i -> i.eq("name", "李白").ne("age", 20)这一段是lambda表达式
        int result = userMapper.update(user, userUpdateWrapper);
        System.out.println(result);
    }

最后的sql语句为:

UPDATE user SET name=?, age=?, update_time=? WHERE deleted=0 AND name LIKE ?

OR ( name = ? AND age <> ?)

9、orderBy、orderByDesc、orderByAsc

**orderBy:**默认是升序

**orderByDesc:**表示升序排列,该方法可以有多个条件参与排列

**orderByAsc:**表示降序排列,该方法可以有多个条件参与排列

10、last

直接拼接到 sql 的最后

注意:只能调用一次,多次调用以最后一次为准 有sql注入的风险,请谨慎使用

@Test
public void testSelectListLast() {
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    queryWrapper.last("limit 1");
    List<User> users = userMapper.selectList(queryWrapper);
    users.forEach(System.out::println);
}

sql语句:SELECT id,name,age,email,create_time,update_time,deleted,version FROM user WHERE deleted=0 limit 1

11、set、setSql

最终的sql会合并 user.setAge(),以及 userUpdateWrapper.set() 和 setSql() 中 的字段

@Test
    public void testUpdateSet() {
//修改值
        User user = new User();
        user.setAge(99);
//修改条件
        UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();
        userUpdateWrapper
                .like("name", "h")
                .set("name", "老李头")//除了可以查询还可以使用set设置修改的字段
                .setSql(" email = '123@qq.com'");//可以有子查询
        int result = userMapper.update(user, userUpdateWrapper);
    }

sql语句:

UPDATE user SET age=?, update_time=?, name=?, email = ‘123@qq.com’ WHERE deleted=0 AND name LIKE ?

b站教学视频:
尚硅谷

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

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

相关文章

MySQL性能优化

MySQL性能调优 存储数据类型优化 尽量避免使用 NULL尽量使用可以的最小数据类型。但也要确保没有低估需要存储的范围整型比字符串操作代价更低使用 MySQL 内建的数据类型&#xff08;比如date、time、datetime&#xff09;&#xff0c;比用字符串更快 基本数据类型 数字 整数…

中国巨头在NLP领域的大模型布局

什么是大模型&#xff1f; 大规模模型&#xff08;large-scale model&#xff09;是近年来人工智能领域的一个热点话题&#xff0c;因为它们可以对自然语言处理&#xff08;NLP&#xff09;和其他任务进行更准确和深入的处理。由于大模型需要庞大的计算资源和数据支持&#xf…

论文投稿指南——中文核心期刊推荐(国家财政)

【前言】 &#x1f680; 想发论文怎么办&#xff1f;手把手教你论文如何投稿&#xff01;那么&#xff0c;首先要搞懂投稿目标——论文期刊 &#x1f384; 在期刊论文的分布中&#xff0c;存在一种普遍现象&#xff1a;即对于某一特定的学科或专业来说&#xff0c;少数期刊所含…

SpringSecurity第二讲

目录 二、SpringSecurity02 2.1 JWT概述 2.1.1 JWT介绍 2.1.2 跨域认证问题 2.2 JWT的原理 2.3 JWT的数据结构 2.3.1 Header 2.3.2 Payload 2.3.3 Signature 2.4 JWT的使用方式 2.5 JWT的使用 2.5.1 引入JWT依赖 2.5.2 编写JWT工具类 2.6 编写前后端不分离的项目…

【C语言】每日刷题 —— 牛客语法篇(3)

前言 大家好&#xff0c;继续更新专栏c_牛客&#xff0c;不出意外的话每天更新十道题&#xff0c;难度也是从易到难&#xff0c;自己复习的同时也希望能帮助到大家&#xff0c;题目答案会根据我所学到的知识提供最优解。 &#x1f3e1;个人主页&#xff1a;悲伤的猪大肠9的博客…

sd卡格式化后数据恢复怎么操作

有时候我们需要清空SD卡数据文件&#xff0c;有时候则是因为需要修复SD卡所以需要格式化&#xff0c;但是却被提示无法格式化SD卡。这种情况往往是由于平时SD卡使用时的一些不良习惯或是SD卡中病毒&#xff0c;病毒在运行SD卡中的软件所造成的。那么sd卡格式化后数据恢复怎么操…

[数据结构]栈的深入学习-java实现

CSDN的各位uu们你们好,今天千泽带来了栈的深入学习,我们会简单的用代码实现一下栈, 接下来让我们一起进入栈的神奇小世界吧!0.速览文章一、栈的定义1. 栈的概念2. 栈的图解二、栈的模拟实现三.栈的经典使用场景-逆波兰表达式总结一、栈的定义 1. 栈的概念 栈&#xff1a;一种…

国密SM4分组密码算法

前言密码&#xff0c;是指使用特定变换对数据等信息进行加密保护或安全认证的物项&#xff08;承载算法、密钥、密文的介质&#xff09;和技术&#xff0c;主要用于加密和安全认证&#xff08;身份识别、完整性、抗抵赖性&#xff09;。密码按照保密等级&#xff0c;又分为核密…

06 电力电子仿真 MATLAB/Simulink

文章目录01 单相半波整流电路02 单相全波整流电路&#xff08;子系统封装模块&#xff09;03 三相桥式整流电路&#xff08;三相模块与示波器使用&#xff09;04 相控与斩控交交调压&#xff08;THD计算&#xff09;05 Buck电路&#xff08;PWM实现与闭环反馈&#xff09;06 单…

【STL】Vector剖析及模拟实现

✍作者&#xff1a;阿润菜菜 &#x1f4d6;专栏&#xff1a;C vector的常用接口 首先贴上&#xff1a;vector的文档介绍,以备查阅使用。 vector的基本框架&#xff1a; vector的成员变量分别是空间首部分的_start指针和最后一个元素的下一个位置的_finish指针&#xff0c;以…

Tomcat安装及启动

日升时奋斗&#xff0c;日落时自省 目录 1、Tomcat下载 2、JDK安装及配置环境 3、Tomcat配置环境 4、启动Tomcat 5、部署演示 1、Tomcat下载 直接入主题&#xff0c;下载Tomcat 首先就是别下错了&#xff0c;直接找官方如何看是不是广告&#xff0c;或者造假 搜索Tomc…

【强度混合和波段自适应细节融合:PAN-Sharpening】

Intensity mixture and band-adaptive detail fusion for pansharpening &#xff08;用于全色锐化的强度混合和波段自适应细节融合&#xff09; 全色锐化的目的是通过高分辨率单通道全色&#xff08;PAN&#xff09;图像锐化低分辨率多光谱&#xff08;MS&#xff09;图像&a…

ChatGPT、人工智能、人类和一些酒桌闲聊

© 2023 Conmajia Initiated 10th March, 2023 昨天跟某化学家喝酒&#xff0c;期间提到了 ChatGPT。他的评价是&#xff1a;这鬼东西大量输出毫无意义、错漏百出甚至是虚假的信息&#xff0c;“in a confident accent”。例如某次 GPT 针对“描述某某记者”这一问题&#…

C++的入门

C的关键字 C总计63个关键字&#xff0c;C语言32个关键字 命名空间 我们C的就是建立在C语言之上&#xff0c;但是是高于C语言的&#xff0c;将C语言的不足都弥补上了&#xff0c;而命名空间就是为了弥补C语言的不足。 看一下这个例子。在C语言中会报错 #include<stdio.h>…

【C++】C++11——左右值|右值引用|移动语义|完美转发

文章目录一、左值与右值1.概念2.引用3.注意二、右值引用的意义1.左值引用意义2.右值引用和移动语义3.容器新增三、万能引用四、完美转发一、左值与右值 1.概念 左值是什么&#xff1f;右值是什么&#xff1f; 左值是一个表示数据的表达式&#xff08;如变量名或解引用的指针&…

学校学生心理测评系统

青少年在线心理测评系统 这款系统&#xff0c;是和北大合作开发&#xff0c;并真实用于线上测评场景&#xff0c;该项目有完整后台&#xff0c;以及学生管理等模块。 我们欢迎以下形式合作&#xff1a; 单纯研究项目。合作对该测评平台进行升级。单纯使用。 请联系我们 silv…

MyBatis里面用了多少种设计模式?

在MyBatis的两万多行的框架源码中&#xff0c;使用了大量的设计模式对工程架构中的复杂场景进行解耦&#xff0c;这些设计模式的巧妙使用是整个框架的精华。经过整理&#xff0c;大概有以下设计模式&#xff0c;如图1所示。图101类型&#xff1a;创建型模式▊ 工厂模式SqlSessi…

英飞凌Tricore原理及应用介绍04_中断请求及仲裁过程

目录1.概述2. 中断请求及过程仲裁3. 中断传到CPU会被即时响应吗&#xff1f;1.概述 在Tricore架构中允许有多个中断源包括片上外设及外部中断世间产生的中断请求&#xff0c;以打断中断服务的提供者如CPU或DMA通道&#xff0c;那你知道在Tricore里中断请求在内核中的仲裁及处理…

【java基础】ArrayList源码解析

文章目录基本介绍构造器指定初始容量默认创建通过集合创建添加add扩容机制批量添加addAll添加指定位置add添加多个元素到指定位置addAll删除删除指定元素remove删除指定索引元素remove条件删除removeIf批量删除removeAll修改修改指定位置set替换所有满足要求元素replaceAll一些…

vscode环境配置(支持跳转,阅读linux kernel)

目录 1.卸载clangd插件 2.安装C插件 3. 搜索框内输入 “intell”&#xff0c;将 C_Cpp&#xff1a;Intelli Sense Engine 开关设置为 Default。 4.ubuntu安装global工具 5.vscode安装插件 6.验证是否生效 7.建立索引 1.卸载clangd插件 在插件管理中卸载clangd插件 2.安…