MyBatisPlus-基本配置与常见应用

news2024/9/24 3:25:47

MyBatisPlus

一、快速入门

MyBatis Plus是基于MyBatis的增强工具,提供了更简单、更便捷的方式来操作数据库。它是一个功能丰富的ORM(对象关系映射)框架,可以帮助开发人员更快速地进行数据库操作。

MyBatis Plus的主要特点如下:

  1. 自动生成代码:MyBatis Plus可以根据数据库表结构自动生成实体类、接口和XML映射文件,大大减少了手动编写重复代码的工作量。

  2. 强大的CRUD操作:MyBatis Plus提供了一系列的CRUD(创建、读取、更新、删除)方法,支持多种查询方式,如通过主键、条件查询和分页查询等。

  3. 简化的分页插件:MyBatis Plus提供了简单易用的分页插件,可以方便地进行分页查询,并支持多种数据库的分页方式。

  4. 条件构造器:MyBatis Plus提供了条件构造器,可以通过链式调用的方式来构建复杂的查询条件。这使得查询语句的编写更加灵活和简洁。

  5. 支持主键生成策略:MyBatis Plus支持多种主键生成策略,如自增、UUID和雪花算法等。

  6. 乐观锁支持:MyBatis Plus提供了乐观锁的支持,可以解决并发更新时的数据冲突问题。

  7. Lambda表达式:MyBatis Plus支持使用Lambda表达式进行查询,可以更直观地表达查询条件。

总之,MyBatis Plus是一个功能强大、易用性高的ORM框架,可以帮助开发人员更快速地进行数据库操作,减少开发工作量,提高开发效率

文档:https://mp.baomidou.com/

使用第三方组件

  1. 导入对应依赖
  2. 研究依赖如何配置
  3. 代码如何编写
  4. 提高扩展技术能力

步骤

1、创建数据库 mybatis_plus

2、创建user表

DROP TABLE IF EXISTS user;

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)
);
-- 真实开发中,version(乐观锁)、deleted(逻辑删除)、gmt_create、gmt_modified

3、创建项目

4、导入依赖

<!--数据库驱动-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.20</version>
</dependency>
<!--mybatis-plus-->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.0.5</version>
</dependency>
<!--lombok-->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>

说明:我们使用mybatis-plus可以节省我们大量的代码,尽量不要同时导入mybatis和mybatis-plus!

5、连接数据库,这一步和mybatis相同

# mysql
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis_plus?userSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

6、传统方式:pojo-dao(连接mybatis,配置mapper.xml文件)- service - controller

6、使用了mybatis-plus 之后

  • pojo
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    
    private Long id;
    private String name;
    private Integer age;
    private String email;
}
  • mapper接口
// 在对应的Mapper上面继承基本的接口 BaseMapper
@Repository // 代表持久层
public interface UserMapper extends BaseMapper<User> {
    // 所有的CRUD操作都已经基本完成了
    // 你不需要像以前的配置一大堆文件了
}

注意点:我们需要在主启动类上去扫描我们的mapper包下的所有接口 @MapperScan(“mapper的全路径”)

在这里插入图片描述

  • 测试类中测试
@SpringBootTest
class MybatisPlusApplicationTests {

    // 继承了BaseMapper,所有的方法都来自父类
    // 我们也可以编写自己的扩展方法
    @Autowired
    UserMapper userMapper;

    @Test
    void contextLoads() {
        // 参数是一个 Wrapper , 条件构造器,这里我们先不用 null
        // 查询全部用户
        List<User> users = userMapper.selectList(null);
        users.forEach(System.out::println);
    }
}

思考问题:

1、SQL是谁帮我们写的?MyBatis-Plus都写好了

去看一下BaseMapper的源码

2、方法哪里来的?MyBatis-Plus 都写好了

二、配置日志

我们所有的sqld现在都是不可见的,我们希望知道它是怎么执行的,所以我们必须要看日志!

# 配置日志 (系统自带的,控制台输出)
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

配置完毕日志之后,后面的学习就需要注意这个自动生成的SQL,你们就会喜欢上MyBatis-Plus !

自动生成的SQL语句

在这里插入图片描述

理解一下sqlsessison对象创建的过程

三、CRUD

1. 插入操作

在这里插入图片描述

数据库插入的id默认值为:全局的唯一id

在这里插入图片描述

id自动生成,并且全局唯一

2. 主键生成策略(都测试一下)

在这里插入图片描述

①@TableId源码

在这里插入图片描述

主键的类型默认为空,需要指定

在这里插入图片描述

指定Id的类型

在这里插入图片描述

public enum IdType {
    AUTO(0), // 数据库id自增
    NONE(1), // 未设置主键
    INPUT(2), // 手动输入,自己写id
    ID_WORKER(3), // 默认的全局唯一id
    UUID(4), // 全局唯一id uuid
    ID_WORKER_STR(5); // ID_WORKER 字符串表示法
}

默认 ID_WORKER 全局唯一id

分布式系统唯一id生成:https://www.cnblogs.com/haoxinyue/p/5208136.html

雪花算法:

snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID。其核心思想是:使用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID),12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID),最后还有一个符号位,永远是0。可以保证几乎全球唯一!

主键自增

我们需要配置主键自增:

<1>实体类字段上 @TableId(type = IdType.AUTO)

<2>数据库字段上一定是自增的
在这里插入图片描述

3. 更新操作

在这里插入图片描述

//测试更新
@Test
public void testUpdate(){
    User user = new User();
    // 通过条件自动拼接动态sql
    user.setId(6L);
    user.setName("关注我的微信公众号");
    user.setAge(18);
    // 注意: updateById 但是参数是一个 对象
    int i = userMapper.updateById(user);
    System.out.println(i);
}

所有的sql都是自动帮你动态配置的!

4. 自动填充

创建时间、修改时间!这些个操作一般都是自动化完成的,我们不希望手动更新!

**阿里巴巴开发手册:**所有的数据库表:gmt_create、gmt_modified几乎所有的表都要配置上!而且需要自动化!

方式一:数据库级别(工作中不允许修改数据库)

1.在表中新增字段 create_time,update_time

在这里插入图片描述

2.再次测试插入方法,我们需要先把实体类同步

private Date createTime;
private Date updateTime;

3.再次查看更新结果即可

在这里插入图片描述

方式二:代码级别

1.删除数据库中的默认值、更新操作

在这里插入图片描述

2.实体类的字段属性上需要增加注解

在这里插入图片描述

//字段添加填充内容
@TableField(fill = FieldFill.INSERT)
private Date createTime;

@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;

查看一下源码理解一些可以设置的属性

3.编写处理器来处理这个注解即可

在这里插入图片描述

在这里插入图片描述

package com.kuang.handler;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.util.Date;

@Slf4j
@Component // 一定不要忘记把处理器加到IOC容器中
public class MyMetaObjectHandler implements MetaObjectHandler {

    // 插入时候的填充策略
    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("start insert fill ...");
        // setFieldValByName(String fieldName, Object fieldVal, MetaObject metaObject)
        this.setFieldValByName("createTime", new Date(), metaObject);
        this.setFieldValByName("updateTime", new Date(), metaObject);
    }

    // 更新时的填充策略
    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("start update fill ...");
        this.setFieldValByName("updateTime", new Date(), metaObject);
    }

}

4.测试插入

5.测试更新,观察时间

5. 乐观锁

在面试过程中,我们经常会被问到乐观锁,悲观锁。

乐观锁:顾名思义,它总是认为不会出现问题,无论干什么都不去上锁!如果出现了问题,再次更新值测试

悲观锁:顾名思义,它总是认为总是出现问题,无论干什么都上锁!再去操作!

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

①数据库添加字段

在这里插入图片描述

在这里插入图片描述

②实体类添加属性,添加乐观锁注解

在这里插入图片描述

@Version // 乐观锁的version注解
private Integer version;

③添加MybatisPlus的配置类,注册乐观锁插件

在这里插入图片描述

// 扫描我们的 mapper文件夹
@MapperScan("com.kuang.mapper")
@EnableTransactionManagement
@Configuration
public class MyBatisPlusConfig {

    // 注册乐观锁插件
    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor() {
        return new OptimisticLockerInterceptor();
    }
}

④测试乐观锁更新成功

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

⑤测试乐观锁更新失败

在这里插入图片描述

测试:

在这里插入图片描述

线程1先查询,再到线程2查询,查询到的version=2,但是线程2先完成更新操作,此时数据库的version=3,所以线程2将无法完成更新操作,这就是乐观锁的作用

    // 测试乐观锁成功
    @Test
    public void testVersionSuccess(){
        // 1. 查询用户信息
        User user = userMapper.selectById(1L);
        // 2. 修改用户信息
        user.setName("fan");
        user.setAge(24);
        // 3. 执行更新操作
        userMapper.updateById(user);
    }

    // 测试乐观锁失败!多线程下
    @Test
    public void testVersionFall(){
        // 线程1
        User user1 = userMapper.selectById(1L);
        user1.setName("fan111");
        user1.setAge(14);

        // 线程2
        User user2 = userMapper.selectById(1L);
        user2.setName("fan222");
        user2.setAge(24);
        userMapper.updateById(user2);
        
        //自旋锁来多次尝试提交!
        userMapper.updateById(user1); //如果没有乐观锁就会覆盖插队线程的值
    }
}

6. 查询操作

// 测试查询
@Test
public void testSelectById(){
    User user = userMapper.selectById(1);
    System.out.println(user);
}

// 批量查询
@Test
public void testSelectByBatchIds(){
    List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));
    users.forEach(System.out::println);
}

// 按照条件查询之一使用 map
@Test
public void testSelectByMap(){
    HashMap<String, Object> map = new HashMap<>();
    // 自定义要查询
    map.put("name","Dainel");
    map.put("age","6");
    List<User> users = userMapper.selectByMap(map);
    users.forEach(System.out::println);
}

测试:

7. 分页查询

分页网站频繁使用

  1. 原始使用limit进行分页
  2. pageHelper第三方插件
  3. MybatisPlus内置了分页插件
使用分页

①配置拦截器

在这里插入图片描述

// 分页插件
@Bean
public PaginationInterceptor paginationInterceptor() {
    return new PaginationInterceptor();
}

②直接使用Page对象即可

在这里插入图片描述

在这里插入图片描述

得到记录条数,实际上查询时,使用了count函数

在这里插入图片描述

测试:

在这里插入图片描述

底层都使用limit

在这里插入图片描述

8. 删除操作

// 测试删除
@Test
public void testdelete(){
    userMapper.deleteById(6L);
}

// 测试批量删除
@Test
public void testdeleteBatchId(){
    userMapper.deleteBatchIds(Arrays.asList(1287326823914405893L,1287326823914405894L));
}

//通过map删除
@Test
public void testDeleteByMap(){
    HashMap<String, Object> map = new HashMap<>();
    map.put("name","KUANG");
    userMapper.deleteByMap(map);
}

测试:

在这里插入图片描述

9. 逻辑删除

物理删除:从数据库中直接移除

逻辑删除:在数据库中没有被移除,而是通过一个变量让他生效!deleted=0 --> deleted=1

管理员可以查看被删除的记录!防止数据的丢失!类似于回收站!

测试

①在数据库表中增加一个deleted字段

在这里插入图片描述

②实体类中增加属性

在这里插入图片描述

③配置

<1>配置逻辑删除组件

在这里插入图片描述

<2>配置逻辑删除

在这里插入图片描述

测试:

在这里插入图片描述

使用注解后,虽然是删除操作,但是只是逻辑删除,即是更新操作,将deleted=0–>deleted=1

在这里插入图片描述

注:数据库的数据还在,只是deleted的值发生变化

<4>再查询一下,也查不出来,因为多了个判断条件

在这里插入图片描述

以上所有的CRUD操作及其扩展操作,我们必须精通掌握!会大大提高工作效率!

四、性能分析插件

我们在平时的开发中,会遇到一些慢sql。解决方案:测试,druid监控…

作用:性能分析拦截器,用于输出每条SQL语句及其执行时间

MyBatisPlus也提供性能分析插件,如果超过这个时间就停止运行!

1、导入插件

在这里插入图片描述

// SQL执行效率插件
@Bean
@Profile({"dev","test"})
public PerformanceInterceptor performanceInterceptor(){
    PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
    performanceInterceptor.setMaxTime(100); //ms 设置sql执行的最大时间,如果超过了则不执行
    performanceInterceptor.setFormat(true); // 是否格式化
    return performanceInterceptor;
}

② 测试使用

// 测试查询
@Test
public void testSelectById(){
    User user = userMapper.selectById(3);
    System.out.println(user);
}

测试:

在这里插入图片描述

只要超出时间就会抛出异常

使用性能分析插件可以提高效率,新版本MP已经移除该拆件了,可以使用druid

五、条件构造器

十分重要:wrapper

我们写一些复杂的sql就可以使用它来代替!

注:将wrapper作为条件放入crud的方法中,作为参数传递,wrapper可以定制化条件SQL语句

在这里插入图片描述

1、非空 大于

在这里插入图片描述

结果:

在这里插入图片描述

在这里插入图片描述

2、查询一个名字

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

3、使用between

在这里插入图片描述

结果:

在这里插入图片描述

在这里插入图片描述

4、like模糊查询

在这里插入图片描述

结果:

在这里插入图片描述

5、连接查询(内查询)

在这里插入图片描述

结果:

在这里插入图片描述

6、升序排序

在这里插入图片描述

结果:

在这里插入图片描述

多测试一下,需要用到回来看看

六、代码生成器

dao、pojo、service、controller都给我自己去编写完成!

AutoGenerator 是 MyBatis-Plus 的代码生成器,通过 AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各个模块的代码,极大的提升了开发效率。

注意:在全局配置中总有一句代码,怎么写都是爆红,我一开始以为是依赖冲突,一直去换依赖,步步排查才发现原来是有依赖导错了

在这里插入图片描述

在这里插入图片描述

有空多用用

// 代码自动生成器
public class AutoGeneratorTest {
    public static void main(String[] args) {
        // 需要构建一个 代码自动生成器 对象
        AutoGenerator mpg = new AutoGenerator();
        // 配置策略

        // 1、全局配置
        GlobalConfig gc = new GlobalConfig();
        String projectPath = System.getProperty("user.dir");
        gc.setOutputDir(projectPath + "/src/main/java");
        gc.setAuthor("小爽帅到拖网速");
        gc.setOpen(false);
        gc.setFileOverride(false);  // 是否覆盖
        gc.setServiceName("%Serive"); // 服务接口,去Service的I前缀
        gc.setIdType(IdType.ID_WORKER); // 主键生成策略
        gc.setDateType(DateType.ONLY_DATE);
        gc.setSwagger2(true);

        // 给代码自动生成器注入配置
        mpg.setGlobalConfig(gc);

        // 2、 设置数据源
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://localhost:3306/mybatis_plus?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2b8");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("83821979Zs");
        dsc.setDbType(DbType.MYSQL);
        mpg.setDataSource(dsc);

        // 3、包的配置

        PackageConfig pc = new PackageConfig();
        pc.setModuleName("blog");
        pc.setParent("com.shuang");
        pc.setEntity("entity");
        pc.setMapper("mapper");
        pc.setService("service");
        pc.setController("controller");

        mpg.setPackageInfo(pc);

        // 4、策略配置
        StrategyConfig strategy = new StrategyConfig();
        strategy.setInclude("user"); // 设置要映射的表名
        strategy.setNaming(NamingStrategy.underline_to_camel);  // 内置下划线转驼峰命名
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        strategy.setEntityLombokModel(true);  // 自动Lombok

        strategy.setLogicDeleteFieldName("deleted");  // 逻辑删除字段

        // 自动填充策略
        TableFill gmtCreate = new TableFill("gmt_create", FieldFill.INSERT);
        TableFill gmtModifid = new TableFill("gmt_modifid", FieldFill.INSERT);

        ArrayList<TableFill> tableFills = new ArrayList<>();
        tableFills.add(gmtCreate);
        tableFills.add(gmtModifid);
        strategy.setTableFillList(tableFills);

        // 乐观锁
        strategy.setVersionFieldName("version");

        strategy.setRestControllerStyle(true);
        strategy.setControllerMappingHyphenStyle(true); // Localhost:8080/hello_id_2

        mpg.setStrategy(strategy);

        // 执行
        mpg.execute();
    }
}

MyBatisPlus-基本配置与常见应用 到此完结,笔者归纳、创作不易,大佬们给个3连再起飞吧

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

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

相关文章

【知识点】:ECMAScript简介及特性

一.简介 什么是ECMAScript&#xff1f; ECMAScript是由网景的布兰登艾奇开发的一种脚本语言的标准化规范&#xff1b;最初命名为Mocha&#xff0c;后来改名为LiveScript&#xff0c;最后重命名为JavaScript。1995年12月&#xff0c;升阳与网景联合发表了JavaScript。1996年11月…

华为HarmonyOS 创建第一个鸿蒙应用 运行Hello World

使用DevEco Studio创建第一个项目 Hello World 1.创建项目 创建第一个项目&#xff0c;命名为HelloWorld&#xff0c;点击Finish 选择Empty Ability模板&#xff0c;点击Next Hello World 项目已经成功创建&#xff0c;接来下看看效果 2.预览 Hello World 点击右侧的预…

K8s-应用数据

应用数据 1 应用数据解析 k8s应用数据类型和步骤解析 k8s如何使用数据功能 k8s使用各种数据类型的配置 2 应用数据实践 emptyDir实践 资源对象文件内容 apiVersion: v1 kind: Pod metadata:name: sswang-emptydir spec:containers:- name: nginx-webimage: kubernetes-reg…

操作系统内存碎片

大家好&#xff0c;我叫徐锦桐&#xff0c;个人博客地址为www.xujintong.com&#xff0c;github地址为https://github.com/jintongxu。平时记录一下学习计算机过程中获取的知识&#xff0c;还有日常折腾的经验&#xff0c;欢迎大家访问。 一、前言 内存碎片是指无法被利用的内…

C# 关于反射的简单示例

写在前面 在日常开发中&#xff0c;我们经常使用反射来动态获取关于类的信息&#xff0c;或者是动态给类实例成员赋值&#xff1b;反射提供了封装程序集、模块和类型的对象&#xff08;Type 类型&#xff09;。可以使用反射动态创建类型的实例&#xff0c;将类型绑定到现有对象…

关闭stp环路的实验演示

在日常的网络规划设计中&#xff0c;为了提高网络的可靠性&#xff0c;通常会采取链路冗余&#xff0c;但是会导致网络中形成环路。有的小伙伴就会发问了&#xff0c;明明增加了链路&#xff0c;网络的可靠性不仅没有提高&#xff0c;怎么反而导致了通信异常呢&#xff1f; 拓…

如何使用csdn中的c知道进行学习?

1.c知道 猜测是通过chatgpt训练链接到CSDN内部的文章内容等&#xff0c;进行生成的一款应用。 2.如何使用呢 打比方说&#xff0c;我想学习下多目标跟踪中的ukf&#xff0c;那么就可以输入这个关键字。 那既然是学习&#xff0c;就要进一步深究&#xff0c;有三种方式&#…

nacos server控制台打开页面空白

总结一下最近遇到的一个纠结很久的坑&#xff1b;通过docker的方式部署nacos server在服务器&#xff0c;部署启动一切正常&#xff0c;然后通过safari浏览器打开控制台的时候页面空白&#xff0c;只有一个标题&#xff1b;打开控制台报错&#xff1a;Failed to load resource:…

纳什议价解

纳什议价解 局中人在网络中所处的位置决定了他们的议价权&#xff0c;并最终导致不同的局中人在博弈中所获得的收益大小不同。下图给出了A、B、 C、D 四人参加网络交换博弈的一个稳定结局&#xff0c;其中粗线相连的节点之间达成交换&#xff0c;交换所得效益标记在了节点上方…

docker 安装elasticsearch、kibana、cerebro、logstash

安装步骤 第一步安装 docker 第二步 拉取elasticsearch、kibana、cerebro、logstash 镜像 docker pull docker.elastic.co/elasticsearch/elasticsearch:7.10.2 docker pull docker.elastic.co/kibana/kibana:7.10.2 docker pull lmenezes/cerebro:latest docker pull l…

【SpringCloud Alibaba笔记】(2)Sentinel实现熔断与限流

Sentinel 概述 官网&#xff1a;https://github.com/alibaba/Sentinel 中文文档&#xff1a;https://sentinelguard.io/zh-cn/docs/introduction.html 类似Hystrix&#xff0c;以流量为切入点&#xff0c;从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热…

JVM中虚拟机栈和本地方法栈等

jvm Java虚拟机栈本地方法栈 Java虚拟机栈 Java虚拟机栈&#xff08;VM Stack&#xff09; ​ 虚拟机栈是线程执行Java程序时&#xff0c;处理Java方法中内容的内存区域。虚拟机栈也是线程私有的区域&#xff0c;每个Java方法被调用的时候&#xff0c;都会在虚拟机栈中创建出…

实战-docker方式给自己网站部署prometheus监控ecs资源使用情况-2024.1.7(测试成功)

title: 实战-docker方式给自己网站部署prometheus监控ecs资源使用情况-2024.1.7(测试成功) date: 2024-1-7 categories: linux tags: promtheues summary: prometheusgrafana 更新于&#xff1a;2024年1月7日 实战-docker方式给自己网站部署prometheus监控ecs资源使用情况-2024…

二叉树与堆的深度解析:数据结构中的关键概念及应用

. 个人主页&#xff1a;晓风飞 专栏&#xff1a;数据结构|Linux|C语言 路漫漫其修远兮&#xff0c;吾将上下而求索 文章目录 前言树概念注意&#xff1a; 树的基本概念及术语基本概念及术语以家谱为例 树的表示孩子兄弟表示法简介优势应用示例 树在实际中的运用文件系统的目录树…

【Maven笔记3】Maven基础入门案例

本篇通过一个最基础的入门案例&#xff0c;熟悉一下maven最基础的使用方法。 编写POM maven项目的核心是pom.xml文件&#xff0c;pom定义了项目的基本信息&#xff0c;用于描述项目如何构建&#xff0c;声明项目依赖等等。 这里我们新建一个maven-demo-hello项目&#xff0c;…

VS Code结合Live Server插件快速搭建小游戏并发布至公网可随时远程访问

文章目录 前言1. 编写MENJA小游戏2. 安装cpolar内网穿透3. 配置MENJA小游戏公网访问地址4. 实现公网访问MENJA小游戏5. 固定MENJA小游戏公网地址 前言 本篇教程&#xff0c;我们将通过VS Code实现远程开发MENJA小游戏&#xff0c;并通过cpolar内网穿透发布到公网&#xff0c;分…

黑莓系统的安全性如何?

黑莓系统的安全性非常高&#xff01; 在过去很长一段时间里&#xff0c;都被认为是手机市场上最安全的操作系统。这主要得益于黑莓在安全性方面的重视和投入。 &#xff08;在世界上最安全的 6 款手机排名中&#xff0c;iPhone未能入围&#xff09; 世界上最安全的 6 款手机&…

CNN——ResNet

深度残差网络&#xff08;Deep residual network, ResNet&#xff09;的提出是CNN图像史上的一件里程碑事件&#xff0c;并且让深度学习真正可以继续做下去&#xff0c;斩获2016 CVPR Best Paper。此外ResNet的作者都是中国人&#xff0c;一作何恺明。ResNet被提出以后很多的网…

Mac 16g约等于Windows多少g?

Mac 16g 内存等于 Windows 320g 内存 何为“黄金内存”&#xff1f; Mac 的内存是用黄金做的&#xff0c;而 Windows 的内存是用铁做的。 黄金的密度是 19.32 g/cm&#xff0c;而铁的密度是 7.874 g/cm。 因此&#xff0c;16g 的黄金体积是 0.082 cm&#xff0c;而 16g 的铁…

交换机_05VLAN

一、VLAN技术的引入 VLAN&#xff08;Virtual Lan&#xff09;主要应用在交换机上 一台交换机默认情况下连接一个广播域&#xff0c;因为默认情况下所有的接口都是属于同一个vlan的&#xff0c;默认vlan1&#xff0c;所以是在同一个广播域中。 结合交换机工作原理&#xff0…