【Spring Boot组件集成实战】集成Druid数据库连接池和MyBatis-Plus(含代码生成器)

2023-05-16

更多精彩内容,请访问 Spring Boot组件集成实战专栏 !

文章目录

    • 1. MyBatis-Plus产生的原因
    • 2. MyBatis-Plus解决的问题
    • 3. Spring Boot集成Druid
      • 2.1 引入依赖
      • 2.2 配置application.yml
    • 4. Spring Boot集成MyBatis-Plus
      • 4.1 引入依赖
      • 4.2 配置application.yml
      • 4.3 配置启动器、分页插件
    • 5. 集成MP代码生成器
      • 5.1 引入依赖
      • 5.2 完善并修改生成器
    • 6. 单元测试
      • 6.1 测试基本的增删改查
      • 6.2 测试分页查询
      • 6.3 自定义查询
    • 7. 本文源码下载

1. MyBatis-Plus产生的原因

一个技术的出现,必然有它的道理。

提起基于Web的项目框架,都会想到SSM,是由Spring+MyBatis框架整合而成的原始Web项目框架。

其中的MyBatis是一种操作数据库的框架,使用XML描述符或注释,将对象与存储过程或SQL语句耦合,将关系型数据库与面向对象应用程序结合使用变得更加容易。其支持定制化SQL、存储过程,以及高级映射。

MyBatis本身存在些许不足,比如配置文件繁多,以及当编写一个业务逻辑时,需要在Dao层写一个方法,再写一个与之对应的SQL语句。

所以,针对这些不足,一个MyBatis的增强工具,MyBatis-Plus就产生了。

当然,MyBatis的增强工具,除了MyBatis-Plus,还有TK.Mybatis等。

2. MyBatis-Plus解决的问题

MyBatis-Plus官网,是这样介绍MP的:

MyBatis-Plus是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

MP官网:https://mp.baomidou.com

MyBatis-Plus的简称是 MP,后文中,我们可能会过多使用此简称。

MP除了解决MyBatis的些许不足外,还具有如下特性。

图:MP的特性,来自官网

接下来,详细讲述如何在Spring Boot项目中集成MP

3. Spring Boot集成Druid

Druid 是阿里巴巴开源平台上的一个项目,整个项目由数据库连接池、插件框架和 SQL 解析器组成。该项目主要是为了扩展 JDBC 的一些限制,可以让程序员实现一些特殊的需求,比如向密钥服务请求凭证、统计 SQL 信息、SQL 性能收集、SQL 注入检查、SQL 翻译等,程序员可以通过定制来实现自己需要的功能。

Druid 是目前最好的数据库连接池,在功能、性能、扩展性方面,都超过其他数据库连接池,包括 DBCP、C3P0、BoneCP、Proxool、JBoss DataSource。Druid 已经在阿里巴巴部署了超过 600 个应用,经过多年生产环境大规模部署的严苛考验。Druid 是阿里巴巴开发的号称为监控而生的数据库连接池!

2.1 引入依赖

首先在 pom.xml 文件中引入 druid-spring-boot-starter 依赖:

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.2.6</version>
</dependency>

获取druid-spring-boot-starter依赖的其他版本,请访问:https://mvnrepository.com/artifact/com.alibaba/druid-spring-boot-starter

然后引入数据库连接 mysql-connector-java 依赖:

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>

引入结果如下图所示。

图:导入依赖图

通常情况下,增删改依赖项后,IDEA会自动做相应的加载。

如果未加载,可手动刷新依赖,如下图所示。

图:刷新Maven

2.2 配置application.yml

application.yml 文件中,增加如下配置信息。

spring:
  datasource:
    druid:
      # 链接地址,这里需要修改自己的数据库IP和数据库名
      url: jdbc:mysql://127.0.0.1:3306/db_study_mp?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTC
      username: root # 数据库用户名
      password: 123456 # 数据库密码
      initial-size: 1
      min-idle: 1
      max-active: 20
      test-on-borrow: true
      # 连接驱动类名
      # MySQL 8.x: com.mysql.cj.jdbc.Driver
      # MySQL 5.x: com.mysql.jdbc.Driver
      driver-class-name: com.mysql.cj.jdbc.Driver

这里需要注意:

  • 如果MySQL的版本是8.X连接URL中需要追加:serverTimezone=UTC 来设置时区,否则报错。

  • 不同版本的数据库,连接类名driver-class-name也不同,均在上述源码中体现。

配置结果如下图所示。

图:数据库连接配置

至此,项目已经集成了Druid

4. Spring Boot集成MyBatis-Plus

4.1 引入依赖

pom.xml 文件中引入 mybatis-plus-boot-starter 依赖,这是MP的核心依赖。

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.4.3.2</version>
</dependency>

获取mybatis-plus-boot-starter 依赖的其他版本,请访问:https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter

4.2 配置application.yml

application.yml 文件中,增加如下配置信息。

# Mybatis Plus 相关配置
mybatis-plus:
  # 配置Mapper映射文件
  mapper-locations: classpath*:/mapper/**/**Mapper.xml
  # 实体扫描,多个package用逗号或者分号分隔
  typeAliasesPackage: com.cxhit.mybatisplus.system.entity;
  configuration:
    # 自动驼峰命名
    map-underscore-to-camel-case: true
    auto-mapping-behavior: full
    cache-enabled: false
    # 打印SQL
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  global-config:
    db-config:
      # 主键类型  0:"数据库ID自增", 1:"用户输入ID", 2:"全局唯一ID (数字类型唯一ID)", 3:"全局唯一ID UUID";
      id-type: auto
      # 驼峰下划线转换
      table-underline: true
      # 逻辑删除
      logic-delete-value: 1
      logic-not-delete-value: 0

此配置的详细说明,注释已经标明,这里不再赘述。

只需要注意 typeAliasesPackage 处,要填写系统实体的包路径。多个包下的实体,可以使用英文分号英文逗号间隔。

关于逻辑删除,将在测试部分演示。

配置结果如下图所示。

图:MP配置

4.3 配置启动器、分页插件

1、增加包扫描路径

首先在启动类 ExciteCmsApplication中增加包扫描的路径。

@MapperScan({"com.cxhit.mybatisplus.system.mapper", ""})

如果有多个包,可以根据此格式,继续追加。

添加后的结果,如下图所示。

图:包扫描配置

2、添加分页插件配置信息

config 包下,新建一个名为 MybatisPlusConfigjava class 文件,并写入如下配置信息。

package com.cxhit.mybatisplus.config;

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

/**
 * <p>
 * Mybatis Plus 配置信息
 * </p>
 *
 * @author 拾年之璐
 * @since 2021-09-01 0001 18:34
 */
@Configuration
@MapperScan({"com.cxhit.mybatisplus.mapper", ""})
public class MybatisPlusConfig {

    /**
     * 分页插件配置
     *
     * @return MP拦截器
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }

}

如下图所示。

图:分页配置

至此,项目已集成MP。

5. 集成MP代码生成器

5.1 引入依赖

pom.xml 文件中引入 mybatis-plus-generator 依赖,这是代码生成器的核心依赖。

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.4.1</version>
</dependency>
<!-- freemarker,作为代码生成器mapper文件的模板引擎使用(当然也可以使用velocity,二选一即可) -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>

获取mybatis-plus-boot-starter 依赖的其他版本,请访问:https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-generator

注:如果使用的MP代码生成器版本大于 3.4.1 ,如使用3.5.1版本,请 点击此处 查看最新版使用示例!

5.2 完善并修改生成器

测试文件夹下,新建一个名为 CodeGeneratorjava class 文件,如下图所示。

图:代码生成器

然后在项目 CodeGenerator 类中,写入如下代码。

package com.cxhit.mybatisplus;


import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

/**
 * MP 代码生成器
 *
 * @author 拾年之璐
 * @since 2021-09-01 0001 18:51
 */
public class CodeGenerator {
    /**
     * <p>
     * 读取控制台内容
     * </p>
     */
    private static String scanner(String tip) {
        Scanner scanner = new Scanner(System.in);
        StringBuilder help = new StringBuilder();
        help.append("请输入").append(tip).append(":");
        System.out.println(help.toString());
        if (scanner.hasNext()) {
            String ipt = scanner.next();
            if (StringUtils.isNotBlank(ipt)) {
                return ipt;
            }
        }
        throw new MybatisPlusException("请输入正确的" + tip + "!");
    }

    /**
     * 执行此处
     */
    public static void main(String[] args) {
        // 代码生成器
        AutoGenerator mpg = new AutoGenerator();

        // 项目根目录
        // 这里注意,追加的是本项目的模块目录。如果是单项目,此行注释掉,更换成下一行
        String projectPath = System.getProperty("user.dir") + "/study-mybatis-plus";
//        String projectPath = System.getProperty("user.dir");

        // 1. 全局配置
        GlobalConfig globalConfig = new GlobalConfig();
        globalConfig
                // TODO 代码生成的目录
                .setOutputDir(projectPath + "/src/main/java")
                .setAuthor("拾年之璐")       // TODO 修改项目作者
                .setOpen(false)             // 是否打开输出目录
                .setIdType(IdType.AUTO)     // 主键策略
                .setFileOverride(false)     // TODO 是否覆盖已有文件
                .setBaseResultMap(true)     // 是否开启 BaseResultMap(XML文件)
                .setBaseColumnList(true);   // 是否开启 baseColumnList(XML文件)
//                .setServiceName("");

        //把全局配置添加到代码生成器主类
        mpg.setGlobalConfig(globalConfig);

        // 2. 数据源配置
        DataSourceConfig dsConfig = new DataSourceConfig();
        dsConfig
                // 数据库链接URL
                .setUrl("jdbc:mysql://localhost:3306/db_study_mp?useUnicode=true&serverTimezone=UTC&useSSL=false&characterEncoding=utf8")
                // .setSchemaName("public")     //数据库 schema name
                .setDbType(DbType.MYSQL)        // 数据库类型
                // 数据库驱动,MySQL5.X:com.mysql.jdbc.Driver
                .setDriverName("com.mysql.cj.jdbc.Driver")
                .setUsername("chen")            // TODO 数据库用户名
                .setPassword("123456");         // TODO 数据库密码

        // 把数据源配置添加到代码生成器主类
        mpg.setDataSource(dsConfig);

        // 3. 包配置
        PackageConfig pkConfig = new PackageConfig();
        // 添加这个后 会以一个实体为一个模块 比如user实体会生成user模块 每个模块下都会生成三层
        pkConfig.setModuleName(scanner("模块名(系统端建议system,客户端建议client)"));
        // TODO 父包名。如果为空,将下面子包名必须写写完整的包路径。如果不为空,只需写子包名。
        pkConfig.setParent("com.cxhit.mybatisplus")
                // TODO 子包名
                .setEntity("entity")                // 实体类 Entity包名
                .setXml("mapper")                   // 持久层 Mapper.xml 包名
                .setMapper("mapper")                // 持久层 Mapper.java 包名
                .setService("service")              // 服务层 Service.java 包名
                .setServiceImpl("service.impl")     // 服务层 ServiceImpl.java 包名
                .setController("controller");       // 控制层 Controller.java 包名

        // 把包配置添加到代码生成器主类
        mpg.setPackageInfo(pkConfig);

        // 4. 自定义配置【这是MyBatisPlus 3.x 新增的】
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
                // to do nothing
            }
        };
        // 如果模板引擎是 freemarker
        String templatePath = "/templates/mapper.xml.ftl";
        // 如果模板引擎是 velocity
        // String templatePath = "/templates/mapper.xml.vm";

        // 自定义输出配置
        List<FileOutConfig> focList = new ArrayList<>();
        // 自定义配置会被优先输出
        focList.add(new FileOutConfig(templatePath) {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输出文件名称,如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
                return projectPath + "/src/main/resources/mapper/" + pkConfig.getModuleName()
                        + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
            }
        });
        cfg.setFileOutConfigList(focList);
        mpg.setCfg(cfg);
        // 配置模板
        TemplateConfig templateConfig = new TemplateConfig();
        templateConfig.setXml(null);
        mpg.setTemplate(templateConfig);

        // 5. 策略配置(数据库表配置)
        StrategyConfig strategyConfig = new StrategyConfig();

        strategyConfig
                .setNaming(NamingStrategy.underline_to_camel)           // 数据库表映射到实体的命名策略:下划线转驼峰
                .setColumnNaming(NamingStrategy.underline_to_camel)     // 数据库表字段映射到实体的命名策略:下划线转驼峰
                .setEntityLombokModel(false)                             // 实体是否为lombok模型(默认 false)
                // .setSuperEntityClass("com.zxdmy.wx.mp.wechat.common.BaseEntity")                 // 设置实体类的父类(如果启用,实体类会增加BaseEntity的继承)
                // .setSuperControllerClass("com.zxdmy.wx.mp.wechat.common.BaseController")         // 设置控制类的父类(如果启用,控制类会增加BaseController的继承)
                // 提示输入生成的表名
                .setInclude(scanner("表全名,多个英文名称,使用英文逗号间隔").split(","))
                // .setExclude("***")                                   // 需要排除的表名,允许正则表达式
                // .setSuperEntityColumns("id");                        // 实体类主键名称设置(如果启用,生成的实体类没有此字段)
                // .setTablePrefix(pc.getModuleName() + "_")            // 表前缀符(如果启用,生成的所有文件名没有此前缀)
                .setControllerMappingHyphenStyle(true);                 // 驼峰转连字符

        // 把数据库配置添加到代码生成器主类
        mpg.setStrategy(strategyConfig);

        // 在代码生成器主类上配置模板引擎,选择 freemarker 引擎需要指定如下加,注意 pom 依赖必须有!
        mpg.setTemplateEngine(new FreemarkerTemplateEngine());
        // 开始执行
        mpg.execute();
    }
}

如果报错,请检查导入的是否一致。

代码中已经给出了详细的注释

你需要仔细逐行阅读,将需要修改的地方(比如作者、数据库名、包路径等信息),修改为自己的项目信息。

在执行代码生成器之前,我们在测试数据库中创建了一个名为sys_user的表单,其内容如下。

图:测试数据库表

此数据库的SQL脚本,在文末的源代码中。

然后点击下图所示的运行按钮,即可执行代码生成器。

图:执行代码生成器按钮

然后根据控制台的提示,输入相应的信息。

图:输入代码生成器信息

回车键后,即可看到生成文件的日志信息,如下图所示。

图:代码生成器日志

生成的6个文件详情如下图所示。

图:生成文件示例

至此,项目已集成代码生成器。

如果项目是分模块,则可以使用上图左下角的CodeGeneratorMultiModule代码生成器,其有详细的配置。

6. 单元测试

接下来通过测试类,对前文集成的数据库连接池MP进行测试。

首先进入前文创建的ISysUserService 服务接口类中,光标放置在 ISysUserService 接口名上,按 Alt+Enter,选择 Create Test 选项,如下图所示。

图:创建测试类

新弹窗直接点击 OK 即可。

图:创建测试类

这时,在测试文件夹下,系统为我们新建了一个测试类,如下图所示。

图:测试类

以下测试均写在此测试文件中。

6.1 测试基本的增删改查

我们可以从 mapper层或者service层进行测试,如下图所示。

图:测试类

如果mapper层提示Could not autowire. No beans of 'SysUserMapper' type found. ,可以通过为mapper接口添加 @Repository 注解解决此提示。

如果不添加此注解,虽然有红线提示,但也可以运行,请自行测试。

接下来,通过几个测试方法,对基本的增删改查进行测试。

1、添加一条数据

编写方法如下。

/**
 * 测试添加一个用户
 */
@Test
void createOneTest() {
    SysUser user = new SysUser();
    user.setNickname("测试用户名");
    user.setEmail("10066@domain.com");
    user.setPassword("sfdnfjdsfhdsjk");
    user.setIsDelete(0);
    if (userService.save(user)) {
        System.out.println("新增用户成功");
        System.out.println(user);
    } else {
        System.out.println("新增用户失败");
    }
}

点击方法左侧的执行按钮,即可进行测试运行,控制台输出信息如下图所示。

图:测试结果

2、添加一系列数据

编写方法如下。

/**
 * 测试添加一系列数据
 */
@Test
void createListTest() {
    // 定义用户列表
    List<SysUser> userList = new ArrayList<>();
    // 随机生成 5个用户
    for (int i = 101; i <= 105; i++) {
        // 定义用户实体
        SysUser user = new SysUser();
        // 随机填充数据
        user.setNickname("用户" + i);
        user.setEmail("10" + i + "@domain.com");
        user.setPassword(DigestUtils.md5DigestAsHex(("password" + i).getBytes()));
        // 添加至列表
        userList.add(user);
    }
    // 打印用户列表
    System.out.println(userList);
    // 执行添加
    if (userService.saveBatch(userList)) {
        System.out.println("新增用户成功");
    } else {
        System.out.println("新增用户失败");
    }
}

执行此方法,输出结果如下图所示。

图:测试结果

3、修改一条数据

我们将上图中id10018用户名修改为李四

编写代码如下。

/**
 * 更新一条数据
 */
@Test
void updateOneTest() {
    // 定义用户实体
    SysUser user = new SysUser();
    user.setId(10018);
    user.setNickname("李四");
    // 执行修改
    if (userService.updateById(user)) {
        System.out.println("修改用户信息成功");
    } else {
        System.out.println("修改用户信息失败");
    }
}

执行此方法,输出结果如下图所示。

图:测试结果

4、删除一条数据

我们这里测试一下逻辑删除

本文 4.2节 配置MP的application.yml 处,已经开启了逻辑删除

首先修改 SysUser 实体,在 isDelete 字段上,增加 @TableLogic 注解,如下图所示。

图:配置实体的逻辑删除

然后编写删除的测试方法如下。

/**
 * 逻辑删除测试
 */
@Test
void logicDeleteTest() {
    if (userService.removeById(10018)) {
        System.out.println("删除成功");
    } else {
        System.out.println("删除失败");
    }
}

执行此方法,输出结果如下图所示。

图:测试结果

我们可以看到,其执行的是Update语句。

5、查询一条数据

前文我们删除了ID=10018的数据。我们执行查询该ID,测试代码如下。

/**
 * 查询单个用户测试
 */
@Test
void getOneTest() {
    SysUser user = userService.getById(10018);
    if (null != user) {
        System.out.println(user);
    } else {
        System.out.println("查无此用户");
    }
}

执行此方法,输出结果如下图所示。

图:测试结果

我们可以看到,其执行的SQL语句,末尾自动追加了判断条件。

6.2 测试分页查询

编写分页测试的代码如下。

/**
 * 测试分页删除
 */
@Test
void pageTest() {
    // 进行分页查询
    Page<SysUser> userPage = userService.page(new Page<>(1, 5), null);
    // 获取查询的用户列表
    List<SysUser> userList = userPage.getRecords();
    System.out.println(userList);
    System.out.println("当前页:" + userPage.getCurrent());
    System.out.println("当前页显示条数:" + userPage.getSize());
    System.out.println("总数:" + userPage.getTotal());
}

执行此方法,输出结果如下图所示。

图:测试结果

6.3 自定义查询

更多复杂的查询,需要使用QueryWrapper,其中部分示例,放在本文的项目源码中了,这里就不再赘述。

7. 本文源码下载

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Spring Boot组件集成实战】集成Druid数据库连接池和MyBatis-Plus(含代码生成器) 的相关文章

  • 安装LINUX的过程中

    下载 xff0d 安装 xff0d 注意细节问题 xff0d 设置用户名 xff0d 权限 xff0d TMPFS xff0d 用户权限 安装VBOX插件 xff0c 还要解决个输入法 xff0c 差不多就行了
  • Linux tmpfs的使用问题解析 调整linux内核尽量用内存,而不用swap

    调整linux内核尽量用内存 xff0c 而不用swap lovemysea 2017 10 21 21 27 27 1641 收藏 分类专栏 xff1a linux unix linux unix专栏收录该内容 35 篇文章0 订阅 订阅
  • 开始,就是这样的过程

    开始 xff0c 就是这样的过程 变成了自己的人生 所以 xff0c 努力的过程 xff0c 就是这样了 人生在世 xff0c 无非名利 而我选择的是什么 选择不重要 xff0c 感受最重要 知道了山峰的高度就要攀登 知道自己的路径就要前行
  • Mate Linux 桌面的什么受GNOME 2 粉丝喜欢 ?

    导读 如果你以前听过这个传闻 xff1a 当 GNOME3 第一次发布时 xff0c 很多 GNOME 用户还没有准备好放弃 GNOME 2 Mate xff08 以马黛茶yerba mate植物命名 xff09 项目的开始是为了延续 GN
  • 寻找最快的debian源sources.list

    ubuntu和debian都有很多的源和镜像 xff0c 也有不少的国内镜像 一些爱好者为了寻找镜像已经自己 憋 出来了一些pl脚本用于寻找最快的镜像 实际上debian的爱好者早准备了更厉害的武器等你来用 xff0c 就是apt spy
  • Tmpfs

    tmpfs是一种文件系统 xff0c 在2 4以上内核 xff08 ubuntu8 4及以后的系统 xff09 已经默认开启该文件功能 首先我们体验一下 xff0c 在你的家文件中建立名为tmpfs的文件夹存一些测试文件 xff0c 然后
  • Debian 中DNS服器配置

    大赛要求 xff1a 4 DNS bind 安装bind服务 xff1b 建立sdskills com域 xff0c 为所有除Internet区域的主机或服务器建立正 反的域名解析 当出现无法解析的域名时 xff0c 向域skills co
  • 添加用户到sudoers

    xff08 用户不在sudoers文件中 xff09 处理这个问题很简单 xff0c 但应该先理解其原理再操作 首先要明白root的密码一般用户是不应改知道的 xff0c 但一般用户有时可能要用到root的一些权限 这里就有了一个 etc
  • 汉化linux软件

    weixin 34197488 2010 11 06 15 10 18 295 收藏 文章标签 xff1a 操作系统 版权 前方火热讨论中 xff1a 做开源 VS 赚钱 xff0c 能兼得吗 xff1f 亮出你的观点 你认为做开源是理想主
  • svn的功能及好处,以及弊端

    1 性能提高 SVN不管文件是文本还是二进制类型 xff0c 在内部都是以二进制差异比较算法来表示文件的更新部分 这表示所有的文件在文件库中都是以差异的形式储存 而且在网络上传输的 xff0c 都是较小的文件差异部分 这也使创建分支 打标签
  • 解决virtualbox共享文件夹没有访问权限的问题

    Virtualbox是一款免费试用的虚拟机软件 基本功能完全可替代需要购买或crack的VMware 在Windows主机上用Virtualbox搭建Linux虚拟机 xff0c 虚拟机和主机之间传递文件最方便的方法就是共享文件夹 假设将W
  • debian9的dns文件默认为resolv.conf

    debian9的dns文件默认为resolv conf sudo vim etc resolv conf nameserver 114 114 114 114 nameserver 8 8 8 8 这只能暂时性的修改DNS 下次系统重启后
  • 驅動Intel無線網卡(IPW2100/IPW2200)

    分类 xff1a LINUX 2007 09 05 12 38 21 驅動 Intel 無線網卡 IPW2100 IPW2200 目前 DFB 預設並沒有安裝 wireless tools xff0c 所以請手動安裝 apt get ins
  • 解决 debian TAB 键不能自动补全命令的原因

    weixin 33928137 2015 04 23 10 46 00 512 收藏 文章标签 xff1a 操作系统 版权 预约直播 xff1a 9月9日 12日 xff0c 携手众开源社区 xff0c 开发者们的年度盛会 开源大咖与开发者
  • 为debian8.2更换官方源

    最近 xff0c 配置一个韩国vps xff0c 里面用的是163的源 xff0c 感觉不如官方的好用 xff0c 就改为官方源 地址为 xff1a ftp cn debian org 输入命令 xff1a vi etc apt sourc
  • debian装好了。之后开始js的旅程了。~

    xff5e
  • 2021-08-28

    卸载无用依赖 Ubuntu卸载软件的几种方法 xff0c 你会用哪种 xff1f 九乡河龙牙 2021 01 12 07 48 13 306 收藏 1 文章标签 xff1a 卸载无用依赖 版权 9月11日 xff0c 腾讯Techo Hub
  • Debian中apache服务,htts,认证网站

    网络技能大赛A模块第一套 xff0c 涉及到apache的配置 xff0c 认证网站 加密https网站 debian中apache配置和Centos有点不太一样 xff0c 各类配置放在子配置文件中 5 Webserver apache
  • 使用Apache转发,解决jQuery的跨域问题!

    一 下载Apache 登录Apache官网 http httpd apache org 点击 Download xff08 我下载的是最新的版本 xff09 下载Windows版本 选择下载平台 ApacheHaus 选择下载相应的32或者
  • 我在这里面写学习程序的博客了

    我在这里面写学习程序的博客了

随机推荐

  • 第一次参加技术类的活动应该还是在十年前

    第一次参加技术类的活动应该还是在十年前 xff0c 当时应该是参加LINUX的一个技术类的活动 具体情况想不起来了 xff0c 地点应该是在中关村上地那个地方的一个什么楼里面 xff0c 当时记的好荒凉的地方 xff0c 没有什么树木 xf
  • 提问

    程序员日记吗 xff1f 我去写日记 xff0c 说着说着 xff0c 晚上吃了个火锅 然后正事没办 就算是什么也不学 xff0c 也要写日记啊 先去提问 什么是程序 xff1f 什么是语言 xff1f 程序是怎么运行的 xff1f 程序和
  • 我遭报应了?游戏过度之后的反弹反应 其实呢?

    我遭报应了 xff1f 过度游戏的之后反应反弹 其实呢 xff1f 我队最近只要沾电子产品就会起不舒服的反应 手机放在裤兜里面 xff0c 皮肤就会疼 之前在香山住的时候 xff0c 旁边有人用电脑 xff0c 之后睡醒死就像一样了 只有在
  • php是啥

    php是啥 有没有技术树 它们的因果关系是什么 xff1f 尝试着写一下 xff1f php的基本格式是什么 PHP的环境怎么装 第一个PHP的程序怎么写 PHP的组成部分有什么 差不多就是这样的问题了吧
  • ubuntu php 乱码解决,为何访问ubuntu的apache服务器下的php文件出现乱码

    这不是 apache 的问题 是 php 本身编码 xff0c 或者 数据库编码问题 给你看一篇别人的问题 让人烦恼的 PHP 43 UTF8 乱码解决方案 088月2009 一般来说 xff0c 如果将 各个文件类型 xff0c HTML
  • easyexcel读取合并单元格

    easyexcel读取合并单元格 文章目录 easyexcel读取合并单元格一 设置读取额外信息二 重写Listener中的extra 方法 xff0c 获取合并单元格的信息三 遍历合并单元格的信息四 代码清单1 UploadDataLis
  • 【Debian 10】win10 远程连接 Debian 10

    1 查询虚拟机的IP地址 使用ifconfig 查询虚拟机的IP地址 xff1a 2 出错问题 直接连接会报错 xff1a 首先需要排除一下网络原因 xff1a Debian需要安装对应的软件才能远程连接 xff1a 3 成功连接上 安装完
  • C/C++ 中typedef关键字

    文章目录 C C 43 43 中typedef关键字1 简介2 1 常规变量类型定义2 2 指针类型定义2 3 结构体定义2 4 数组类型定义2 5 函数定义2 5 1 函数声明2 5 2 函数指针 C C 43 43 中typedef关键
  • 解决“Failed to start bean ‘documentationPluginsBootstrapper‘; nested exception is java.lang.NullPoint”

    当你的spring boot版本是2 6 x并且你的swagger版本是3 0 0以上的时候 xff0c 项目启动会报错 org springframework context ApplicationContextException Fai
  • 3.汇编指令:【寻址方式】立即数寻址、寄存器寻址、存储器寻址

    文章目录 指令格式指令中的 xff08 目标 源 xff09 操作数来源一 立即数寻址二 寄存器寻址三 存储器寻址3 1 直接寻址3 2 寄存器间接寻址3 3 基址寻址 xff08 寄存器相对寻址 xff1f xff09 3 4 变址寻址
  • 51单片机定时器/计数器

    一 课前须知 xff1a 1 51单片机有两组定时器 计数器 xff0c 因为既可以定时 xff0c 也可以计数 xff0c 所以称之为定时器 计数器 2 定时器 计数器和单片机CPU是相互独立的 定时器 计数器的工作过程是自动完成的 xf
  • matlab中矩阵某列最大值,MATLAB怎么取出矩阵每列中最大的数

    你说的列到底是指什么 xff1f a 61 2 3 3 6 4 9 是三行两列 xff0c a 61 2 3 3 6 4 9 如果你要得到b 61 4 9 则程序为 a 61 2 3 3 6 4 9 或者 a 61 2 3 3 6 4 9
  • debian10 安装jdk8

    下载Oracle JDK 8 在 Debian 上安装 Oracle JDK 需要从官网上下载可供安装的软件包 这里我们使用curl命令来从 Oracle 网站下载 Oracle Java 8 默认情况下curl命令工具并未在系统中安装可以
  • debian10 安装nodejs

    从Debian存储库安装Node js和npm Node js和npm可以从标准的Debian存储库安装 xff0c 在选写本文时 xff0c 存储库中的版本是v10 x xff0c 这是最新的LTS版本 要在Debian上安装Node j
  • Grafana+MySQL(3)grafana展示mysql源数据:表格展示

    背景 grafana展示mysql源数据 xff0c 且以table形式 MySQL表内数据格式如下 xff1a 表格展示 Dashboard 添加panel xff0c 右侧菜单选择 Table xff0c 添加Query xff0c 选
  • debian使用php+mysql+nginx快速搭建网站

    1 apt get update 更新插件库 2 apt get install nginx 安装nginx 3 apt get install php5 fpm php5 curl 安装php一系列拓展 xff0c 可以使用tab查看ph
  • ECS简介

    Amazon Elastic Container Service ECS 是一个有高度扩展性的容器管理服务 它可以轻松运行 停止和管理集群上的Docker容器 xff0c 你可以将容器安装在EC2 实例上 xff0c 或者使用Fargate
  • 刷爆朋友圈!程序员怒斥:凉透吧!月薪40k的Python人!

    作为一名老码农 xff0c 我的心这次凉透了 xff01 事情起因是这样的 xff1a 前天我晚上正在全国最大的同性组织某Hub上浏览时候 xff0c 发现这样的一条信息 xff1a Python 116K 超过 C 43 43 JS 薪酬
  • ABAQUS设置云图的显示

    1 单击云图选项 2 边界 指定 xff08 设定指定值 xff09 值设置的越大 xff0c 变形效果越小
  • 【Spring Boot组件集成实战】集成Druid数据库连接池和MyBatis-Plus(含代码生成器)

    更多精彩内容 xff0c 请访问 Spring Boot组件集成实战专栏 xff01 文章目录 1 MyBatis Plus产生的原因2 MyBatis Plus解决的问题3 Spring Boot集成Druid2 1 引入依赖2 2 配置