Roookie博客 | 记录 · 收纳 · 分享 - Java
type: channel
link: https://www.wlplove.com/index.php/category/Java/
items: SpringMVC学习笔记
items: Spring学习笔记（四） - SSM框架整合
items: Spring学习笔记（三） - 注解
items: Spring学习笔记（二） - 通过XML配置整合框架
items: Spring学习笔记（一） - Bean与依赖注入
items: MySQL数据表中的auto_increment自增值属性及修改
items: 目前最流行的版本控制软件：Git的基本使用
items: SQL系列总结（四）：DCL（数据控制语言）
items: SQL系列总结（三）：DML（数据操纵语言）
items: SQL系列总结（二）：DQL（数据查询语言）

SpringMVC学习笔记
type: item
date: 2021-11-26T14:56:00+00:00
description: 目录 一、SpringMVC介绍 二、映射请求路径 2.1、使用@ResquestMapping进行路径映射 2.2、@ResquestMapping的属性 2.2.1、value或path 2.2.2、method 2.2.3、params 2.2.4、headers 2.2.5、consumes 2.2.6、produces 2.3、@ResquestMapping的衍生注解 三、请求参数传递 3.1、GET/POST请求传递基础参数 3.2、传递复杂参数 3.2.1、日期类型 3.2.2、引用类型 3.2.3、数组 3.2.4、集合（List/Set/Map） 3.3、传递Json数据 四、响应 4.1、返回Json数据 4.2、封装返回结果 五、REST风格 5.1、简介 5.2、规则 5.3、相关注解 5.3.1、@RestController 5.3.2、@PathVariable 5.3.3、@RequestParam 5.3.4、@RequestBody 5.4、Rest风格开发示例 5.3.1、查询 5.3.2、新增 5.3.3、修改（更新） 5.3.4、删除 六、异常处理 6.1、自定义异常 6.2、处理异常的方式 6.2.1、使用@ControllerAdvice和@ExceptionHandler 6.2.2、实现HandlerExceptionResolver接口 七、拦截器 7.1、创建拦截器 7.2、注册和配置拦截器 7.3、执行流程和顺序 一、SpringMVC介绍 Spring MVC 是 Spring 框架中的一个模块，专门用于构建基于模型-视图-控制器（Model-View-Controller，MVC）设计模式的 Web 应用程序。 相关依赖坐标： <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.0.RELEASE</version> </dependency> 在 IDEA 中根据 “maven-archetype-webapp” 模板创建 Webapp 项目： 创建基本项目结构： 在 config 包里面新建初始化 Servlet 的配置类： public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer { protected Class<?>[] getRootConfigClasses() { return new Class[]{SpringConfig.class}; } protected Class<?>[] getServletConfigClasses() { return new Class[]{SpringMvcConfig.class}; } protected String[] getServletMappings() { return new String[]{"/"}; } } 再新建 SpringMVC 配置类： @Configuration @ComponentScan("com.wlplove.controller") public class SpringMvcConfig { } 二、映射请求路径 2.1、使用@ResquestMapping进行路径映射 @RequestMapping 是 Spring MVC 中将 HTTP 请求映射到控制器方法的注解，它用于类级别或方法级别，可以根据请求的 URL、HTTP 请求方法（GET、POST 等）、请求参数、请求头等信息来匹配对应的处理逻辑。 @RequestMapping 注解应用在方法上，可以为该方法映射 URL 请求路径： public class UserController { @RequestMapping("/save") public String save() { // ... } } 也可以应用在类上，为该类中的所有方法设置基础的 URL 请求路径： @RequestMapping("/user") public class UserController { @RequestMappi…

Spring学习笔记（四） - SSM框架整合
type: item
date: 2021-11-13T14:56:00+00:00
description: 目录 一、创建Webapp项目 二、Spring配置类 三、数据源对象（以Druid为例） 四、整合MyBatis 4.1、数据库配置 4.2、MyBatis配置 五、整合SpringMVC 六、整合Log4j 七、整合Junit 环境说明： 数据库：MySQL 8.0 Java版本：JDK8 通过注解整合 SSM 框架流程： 创建 Web 工程 SSM 整合 Spring 框架：SpringConfig MyBatis 框架：JdbcConfig / jdbc.properties / MybatisConfig SpringMVC 框架：ServletConfig / SpringMvcConfig 一、创建Webapp项目 在 IDEA 中根据 “maven-archetype-webapp” 模板创建 Webapp 项目： 创建基本项目结构： 二、Spring配置类 引入 spring-conext 的依赖坐标： <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.25.RELEASE</version> </dependency> 创建一个 Java 类 SpringConfig 作为 Spring 配置类，类上面添加 @Configuration 注解标识这是一个配置类，添加 @ComponentScan 注解来设置扫描注解的路径 @Configuration @ComponentScan("com.xxx") /** * 如果有多个要扫描的包路径，可以用数组格式： * @ComponentScan({"com.xxx.dao","com.xxx.service"}) */ public class SpringConfig { } 三、数据源对象（以Druid为例） 导入 Druid 数据源的依赖坐标： <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.2.22</version> </dependency> 新建一个配置数据库连接信息的类 JdbcConfig，里面引入配置文件中的数据库信息，然后用一个方法构造并返回一个 DataSource 对象，最后用 @Bean 注解设置这个方法的返回值成为 Spring IoC 容器的一个 Bean： public class JdbcConfig { @Value("${jdbc.driver}") private String driver; @Value("${jdbc.url}") private String url; @Value("${jdbc.username}") private String username; @Value("${jdbc.password}") private String password; /** * 数据源Bean * @return */ @Bean public DataSource dataSource() { DruidDataSource ds = new DruidDataSource(); ds.setDriverClassName(driver); ds.setUrl(url); ds.setUsername(username); ds.setPassword(password); return ds; } } Spring 配置类 SpringConfig 中用 Import 注解引入 JdbcConfig 这个类： @Configuration @ComponentScan("com.xxx") +@Import({JdbcConfig.class}) public class SpringConfig { } 四、整合MyBatis 4.1、数据库配置 在 src/main/resources 目录下新建一个配置数据库连接信息的配置文件 jdbc.properties： jdbc.driver=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql://127.0.0.1:3306/spring_db?useSSL=false&setUnicode=true&characterEncoding=utf8 jdbc.username=root jdbc.password=root 使用 @PropertySource 注解在 Spring 配置类 SpringConfig 上加载外部的 prope…

Spring学习笔记（三） - 注解
type: item
date: 2021-11-10T12:24:00+00:00
description: 目录： 一、通过注解定义Bean 1.1、启用注解支持 1.2、定义Bean 1.3、@Component的派生注解 1.3.1、@Repository 1.3.2、@Service 1.3.3、@Controller 1.3.4、@Configuration 1.4、用注解代替XML配置文件 1.4.1、配置类 1.4.2、初始化IoC容器 二、通过注解使用Bean 2.1、自动装配 2.1.1、@Autowired 2.1.2、@Qualifier 2.1.3、@Resource 2.1.4、@Primary 2.1.5、@Value 2.2、读取properties文件配置 2.3、作用域 2.4、自定义Bean初始化/销毁操作 2.5、总结 三、整合框架 3.1、数据源对象（以Druid为例） 3.2、整合Mybatis 3.3、整合Log4j 3.4、整合Junit 四、Spring事务 一、通过注解定义Bean 1.1、启用注解支持 <context:annotation-config /> 若要以注解方式注入 Bean，则需要开启扫描包中的组件，并用 base-package 属性指定扫描的基本包路径： <context:component-scan base-package="com.xxx" /> 使用 <context:annotation-scan> 标签时，默认将隐式启用对注解的支持。 1.2、定义Bean 在 XML 配置中如果要将一个 Bean 交给 Spring IoC 容器管理，需要进行如下配置： <bean id="userService" class="com.wlplove.service.impl.UserServiceImpl" /> 若用注解要实现相同目的，只需要在要被管理的 Java 类上添加 @Component 注解，并在后面的括号中指定 Bean 的名称： // 注解后面的括号里是 bean 的名称 @Component("userServiceImpl") public class UserServiceImpl implements UserService { // ... } @Component 注解也可以不指定 Bean 名称，Spring 会自动为该 Bean 生成一个默认的名称，通常是类名的首字母小写形式： @Component // 可以用名称“userServiceImpl”来获取这个Bean public class UserServiceImpl implements UserService { // ... } 所以只需要在 Java 类上加入 @Component 注解，用于标识这个类是 Spring 容器中的组件（即 Bean），就可以实现与 XML 配置中的 <bean> 标签相同的作用。 1.3、@Component的派生注解 此外，Spring 还提供了 @Component 的几个派生注解：@Repository、@Service、@Controller、@Configuration，这几个注解的功能和用法与 @Component 相同，但它们在使用场景上有所不同。 1.3.1、@Repository 用于数据访问层（Dao 层）中与数据库交互的类。 Spring 会对使用 @Repository 注解的类进行特定的异常处理（将数据访问层的异常，如 SQLException 等转换为 Spring 的 DataAccessException 异常，方便统一处理和异常传播）。 @Repository public interface UserMapper { // ... } 1.3.2、@Service 用于标识业务逻辑层（Service 层）中处理核心业务逻辑的类。 使用 @Service 注解可以将一个类声明为业务逻辑组件，将其对象存入 Spring 容器中，以便在其他组件（如Controller）中通过注入该 service 类的实例来使用其业务逻辑。 @Service public class UserServiceImpl implements UserService { // ... } 1.3.3、@Controller 用于标识控制层（Controller 层）中处理响应和请求的类。 被 @Controller 标记的类实际上就是一个 Spring MVC Controller 对象，它可以处理请求，并通过 @RequestMapping 等注解将不同的请求分发到对应的方法上。 @Controller public class UserController { // ... } 1.3.4、@Configuration 用于…

Spring学习笔记（二） - 通过XML配置整合框架
type: item
date: 2021-11-07T10:59:00+00:00
description: 目录： 一、创建Webapp项目 二、加载properties文件 2.1、新建properties文件 2.2、指定要加载的properties文件 2.3、读取properties文件属性值的方式 三、数据源对象（以Druid为例） 3.1、导入Druid数据源依赖坐标 3.2、在XML文件中配置数据源对象为Spring管理的Bean 四、整合MyBatis 4.1、导入依赖坐标 4.2、配置SqlSessionFactoryBean 4.3、配置MapperScannerConfigurer 五、整合Junit 六、整合Log4j 在 pom.xml 文件中导入 Spring 的坐标依赖： <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.10.RELEASE</version> </dependency> 一、创建Webapp项目 在 IDEA 中根据 “maven-archetype-webapp” 模板创建 Webapp 项目： 创建基本项目结构： 在 src/main/resources 目录下新建一个 spring-config.xml 文件作为 Spring 的配置文件： <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> </beans> 二、加载properties文件 2.1、新建properties文件 在 src/main/resources 目录下新建一个配置数据库连接信息的配置文件 jdbc.properties： jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://127.0.0.1:3306/spring_db jdbc.username=root jdbc.password=root 2.2、指定要加载的properties文件 在 Spring 的 XML 配置文件中加载指定 properties 文件，写法有多种： 加载资源路径（src/main/java/resources）下指定的一个 properties 文件： <context:property-placeholder location="classpath:jdbc.properties"/> 也可以加载资源路径下的多个 properties 文件： <context:property-placeholder location="classpath:jdbc.properties,classpath:jdbc2.properties"/> 使用通配符加载 properties 文件：在资源路径或 jar 包中搜索并加载所有 properties 文件 <context:property-placeholder location="classpath*:*.properties"/> 再加上 system-properties-mode="NEVER"，表示 Spring 容器在解析 properties 配置文件时，不使用系统属性来替换配置文件中的属性，从而避免系统属性对配置产生影响： <context:property-placeholder location="classpath:*.properties" system-properties-mode="NEVER"/> 2.3、读取properties文件属性值的方式 <property name="driverClassName" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> 三、数据源对象（以Druid为例） 3.1、导入Druid数据源依赖坐标 <dep…

Spring学习笔记（一） - Bean与依赖注入
type: item
date: 2021-11-05T14:53:00+00:00
description: 目录： 一、Spring简介 二、Bean配置 2.1、基础配置 2.2、别名配置 2.3、作用域 三、Bean的生命周期 3.1、实例化 3.2、属性赋值 3.3、初始化 3.4、使用 3.5、销毁 3.6、示例：通过XML配置自定义初始化和销毁操作 四、实例化Bean的方式 4.1、无参构造方法 4.2、静态工厂 4.3、实例工厂 4.3.1、方式一 4.3.2、方式二（重要） 五、依赖注入（DI） 5.1、setter 注入 5.1.1、注入简单类型 5.1.2、注入引用类型 5.2、构造器注入 5.2.1、注入简单类型 5.2.2、注入引用类型 5.2.3、构造器注入的其他XML配置写法 5.2.3.1、type方式 4.2.3.2、index索引方式 5.3、基于XML文件的自动装配 5.3.1、byType 5.3.2、byName 5.3.3、constructor 5.4、基于注解的自动装配 六、集合的注入 6.1、注入数组 6.2、注入 Set 对象 6.3、注入 List 对象 6.4、注入 Map 类型数据 6.5、注入 property 类型数据 七、Spring容器的核心操作 7.1、创建容器 7.2、从Srping容器获取Bean 7.2.1、根据Bean名称/ID 7.2.2、根据Bean类型获取 7.2.3、根据Bean名称获取并指定类型 八、一图流总结 8.1、Bean： 8.2、依赖注入： 一、Spring简介 Spring 是一个开源的 Java 平台框架，广泛用于构建企业级应用程序。它由 Rod Johnson 在 2003 年首次发布，旨在简化 Java 开发，提供全面的基础设施支持。Spring 的核心特性包括依赖注入（DI）和面向切面编程（AOP），是开发Java EE应用程序的必备。 在 pom.xml 文件中导入 Spring 的坐标依赖： <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.10.RELEASE</version> </dependency> 二、Bean配置 Bean 是 Spring 框架中最核心的概念之一，它是构成应用程序主干并由 Spring IoC 容器管理的对象。 Spring Bean 本质上是由 Spring IoC 容器实例化、组装和管理的对象，可以是任何 Java 类的实例，如一个简单的 POJO（Plain Old Java Object），比如一个表示用户信息的 User 类，在 Spring 容器中可以被定义为一个 Bean，然后 Spring 可以对 User 类的实例进行各种诸如依赖注入等的管理操作。除此之外，Bean 也可以是一个复杂的企业级组件。 在 Java 中，对象通常通过 new 关键字来创建，但在 Spring 中，对象的创建和依赖注入由 Spring IoC 容器负责。这种机制允许开发者将对象的生命周期管理和依赖关系交给 Spring 容器，从而简化了开发过程并提高了代码的可维护性和灵活性。 2.1、基础配置 <bean id="userDao" class="com.wlplove.dao.impl.UserDaoImpl"/> <bean id="userService" class="com.wlplove.service.impl.UserServiceImpl"> <property name="userDao" ref="userDao"/> </bean> 在 XML 文件中经过上面的配置之后，就将这个类交给了 Spring IoC 容器进行管理，之后需要使用该类时就可以从容器中获取到实例对象了。 2.2、别名配置 name 属性表示 Bean 的别名，可以设置多个，使用逗号、分号、空格分开。 别名配置完成后，就可以通过别名获取 Bean 或者在其他 Bean 的配置中通过别名引用这个 Bean。 <bean id="bookService" name="service service2 bookEbi" class="com.wlplove.service.impl.BookServiceImpl"/> 2.3、作用域 Spring Bean 的 Scope 指的是 Bean 的作用域，它定义了 Bean 实例在 Spring 容器中的生命周期和可见性。一般常用的是 singleton（单例）、prototype（原型/非单例）： singleton：默认作用域，Spring 容器只会创建一个 Bean 实例，并在整个应用程序中共享。这个实例从容…

MySQL数据表中的auto_increment自增值属性及修改
type: item
date: 2021-10-31T09:31:00+00:00
description: 目录： 0x01. 查看自增值 1、查看全局自增值 2、查看特定数据表的自增值 0x02. 自增值的取值问题 1、默认取值 2、建表时指定 3、直接指定 4、修改自增字段属性 环境说明： MySQL 5.7 、MySQL 8.0 长期以来，我的博客数据库中连续文章的主键编号一直都不是连续的，让我这个强迫症晚期患看着很不舒服。在忍受了这么长时间以后，趁着给博客换域名的时机，我把所有的文章编号全部改成了连续的，可算是舒服多了。 把改完主键编号的文章数据导入新数据库之后，就产生了一个新问题：现在新数据表的主键自增值还是旧数据表的主键自增值。比如说博客数据库的文章表中有80条数据，下次新创建文章的编号是以旧数据库的自增值202开始递增，生成的新文章编号是203，而不是81。如果要保持文章编号能连续的话，就只能每次发布完新博客之后再去改数据库中的编号，可谓是相当麻烦。 所以我便想着是否可以通过修改数据表里主键的 AUTO_INCREMENT 自动递增值来一步到位，查了一些资料之后，就有了这篇博客。 0x01. 查看自增值 一般来说，数据表中具有自增属性 AUTO_INCREMENT 的字段主要是数据表的主键或者具有唯一性的字段。 如果要查阅其递增值，有这么两种方式： 1、查看全局自增值 SHOW VARIABLES LIKE 'AUTO_INC%'; 这条命令的执行结果会返回两条数据： AUTO_INCREMENT_INCREMENT 表示自增的初始值，AUTO_INCREMENT_OFFSET 表示自增的步长，即每次的自增量。 修改自增初始值与自增量的命令： SET @@AUTO_INCREMENT_INCREMENT=新初始值; SET @@AUTO_INCREMENT_OFFSET=新步长; 注意：这个表示的是数据库全局的自增设置，因此修改以后只会影响到下次新增的带有 AUTO_INCREMENT 属性的列，其自增初始值与自增步长就是新设置的值，对当前已经带有 AUTO_INCREMENT 属性的列的自增初始值与自增步长不起作用。 2、查看特定数据表的自增值 要想查看某个数据表中自增字段的当前自增值，可用以下命令： SHOW TABLE STATUS FROM [数据库名] LIKE [表名]; FROM [数据库名] 与 LIKE [表名] 这两个子句是可选的。 FROM [数据库名] 表示指定查询所在的数据库；LIKE [表名] 指定该数据库下要查询的某个表，如果省略了 LIKE [表名] 子句，则表示查看该数据库下的所有表的信息。 另外，需要注意的是，表名要加引号。 比如查询 TEST 数据库下 test 表的信息： SHOW TABLE STATUS FROM TEST LIKE 'test'; 查询结果中有一个字段名为 “AUTO_INCREMENT”，表示的就是自增值，该表下一条记录的编号就是这个值。 0x02. 自增值的取值问题 1、默认取值 默认情况下，自增值从1开始，每增加一条新记录，自增值便会自增 1。 所以，对于具有 AUTO_INCREMENT 属性的列，不用特意设置列值，而是直接将 NULL 值插入到自增列中去，数据库会自动根据当前的自增值生成列值。 注意： 将 0 插入到自增列中的效果等同于插入 NULL 值； 当插入记录时，如果没有为自增列指明一个值，那么也等同于插入 NULL； 使用 INSERT 语句插入记录时，如果为自增列设置了一个值，那么会出现这样三种情况： 情况一，插入的值与已有的编号重复，则会出现报错 情况二，插入的值大于列的自增值，成功插入这条记录，并且会更新自增值为新值 情况三，插入的值小于列的自增值且与已有的编号不重复，则成功插入这条记录，但自增值不会更新，如果插入的值与已有的值重复，参考情况一 如果用 UPDATE 语句更新自增列，情况与 INSERT 语句相同。 2、建表时指定 我们也可在建表时使用 “AUTO_INCREMENT=自增值” 来指定一个自增的初始值，比如： CREATE TABLE TEST{ -- 建表语句 }AUTO_INCTEMENT=自增值; 3、直接指定 ALTER TABLE [表名] AUTO_INCREMENT=自增值; 如果执行完以后没有效果，那么可以再执行一次 commit 指令以提交更改，使其生效。 4、修改自增字段属性 ALTER TABLE [表名] MODIFY [字段名] [字段类型和约束条件], AUTO_INCREMENT=自增值; 同样的，如果执行完以后没有效果，再执行一次 commit 提交更改。 这个语句相当于直接修改自增字段的属性，包括其数据类型和约束条件。 另外，我在尝试中发现，使用 SQL 语句更改了自增值以后再执行 …

目前最流行的版本控制软件：Git的基本使用
type: item
date: 2021-09-14T15:20:00+00:00
description: 前排提示： 本篇博客篇幅较长，建议结合目录查看！ 目录： 写在前面 1、关于版本控制系统 定义 版本控制的必要性： 常见的版本控制系统 2、Git与Github 0x01.安装Git 0x02.Github中的一些基本概念 Repository Issue Star Fork Pull Request Watch Wiki Gist 0x03.添加SSH key 0x04.克隆仓库 0x05.初始化仓库 0x06.提交修改 0x07.分支操作 查看分支 建立新分支 切换分支 建立并切换到新分支 推送本地分支到远程仓库 合并分支 删除分支 重命名分支 0x08.标签操作 附注标签 轻量标签 切换标签 推送标签 删除标签 查看所有标签 给提交打标签 写在前面 1、关于版本控制系统 定义 版本控制（Version control）是维护项目的标准作法，能追踪项目从诞生一直到定案的过程。此外，版本控制也是一种软件工程技巧，借此能在软件开发的过程中，确保由不同人所编辑的同一程序文件都得到同步，记录项目内各个模块的改动历程，并为每次改动都编上序号。 一种简单的版本控制形式如下：工程的初代版本为“1.0”，当做了第一次改变后，版本等级改为“1.1”，以此类推。因此，版本控制能提供给开发者将项目恢复到之前任一状态的选择权，这种选择权在设计过程进入死胡同时特别重要。 版本控制的必要性： 常会利用版本控制来追踪维护源代码、文件以及配置文件等的改动，并且提供控制这些改动控制权的程序； 有时候，一个程序同时存有两个以上的版本，例如：在一个稳定版本中程序错误已经被修正、但没有加入新功能；在另一个开发版本则有新的功能正在开发、也有新的错误待解决，这使得同时间需要不同的版本； 此外，为了找出只存在于某一特定版本中（由于修正了某些问题、或新加功能所导致）的程序错误，或找出程序错误出现的版本，开发者也需要比对不同版本的代码以找出问题的位置。 常见的版本控制系统 集中式版本控制系统：由一台或多台主计算机组成中心服务器，所有业务单元和项目版本库都集中存储在这个中心服务器上，开发时，要先从中央服务器取得项目最新的版本，一次开发完毕之后，再将工作量推送给中央服务器。就像是一个图书馆，如果要改一本书的内容，则需要把书先从图书馆借出来，然后修改，改完之后再放回图书馆。 因此，集中式版本控制系统最的大缺点就是中央服务器出了问题，所有人都没法工作了。 常见的集中式版本控制系统有SVN、CVS等。 分布式版本控制系统：分布式版本系统没有绝对的中央服务器，每个人的电脑上都是一个完整的版本库，多个人进行协同工作时，只需将自己的修改与其他人的修改进行交换即可 和集中式版本控制系统相比，分布式版本控制系统的安全性要高很多，因为每个人电脑里都有完整的版本库，其中一个人的电脑坏了不要紧，从其他人那里复制一个就可以了。 Git就是常见的分布式版本控制系统之一，也是目前最流行的版本控制系统。 2、Git与Github 准确地说，Git与Github根本不是同一个概念。 Git是指由Linus（就是那位二十多年前徒手撸出Linux内核的大佬）编写的分布式版本控制系统，于2005年以GPL发布。最初目的是为了更好地管理Linux内核开发。 自2002年以来，Linus一直使用BitKeeper作为Linux内核主要的版本控制系统以维护代码。在Linux社区中，主张应该使用开放源代码的软件来作为Linux内核的版本控制系统。Linus曾考虑过采用现成软件作为版本控制系统（例如Monotone），但这些软件都存在一些问题，特别是性能不佳。 2005年，Linux社区中的安德鲁·垂鸠写了一个可以连接BitKeeper的存储库的简单程序，BitKeeper著作权拥有者拉里·麦沃伊便认为安德鲁·垂鸠对BitKeeper内部使用的协议进行了逆向工程，决定收回无偿使用BitKeeper的许可。Linux内核开发团队与BitMover公司进行磋商无果后，Linus决定自行开发版本控制系统以替代BitKeeper，在十天的时间编写出git第一个版本。于是，世界上最流行的版本控制系统就这么戏剧式地诞生了。 而GitHub是通过Git进行版本控制的软件源代码托管服务平台，由GitHub公司（曾称Logical Awesome）的开发者Chris Wanstrath、P. J. Hyett和Thomas Preston-Werner使用Ruby on Rails编写而成，于2007年10月1日开始开发。beta版本开始上线于2008年2月，4月份正式上线。这是他们的logo，名字叫Octocat： 截止到2020年1月，GitHub已经有超过4000万注册用户和1.9亿代码库（包括至少2800万开源代码库），事实上已经成…

SQL系列总结（四）：DCL（数据控制语言）
type: item
date: 2021-08-05T08:56:00+00:00
description: 前排提示： 本篇博客篇幅较长，建议结合目录进行阅读！ 目录： 前言 0x01.权限的授予与收回 GRANT REVOKE 0x02.数据库角色 角色的创建 ——CREATE ROLE 给角色授权 ——GRANT 将角色授予给其他角色或用户 ——GRANT 收回角色权限 ——REVOKE 0x03.用户管理 创建用户： 删除用户： 重命名用户名： 修改用户密码： 环境说明： 数据库：Mysql 5.5 连接软件：Navicat 前言 SQL总结系列目录： SQL系列总结（一）：DDL（数据定义语言）- Roookie博客 | 记录 · 收纳 · 分享 (wlplove.com) SQL系列总结（二）：DQL（数据查询语言）- Roookie博客 | 记录 · 收纳 · 分享 (wlplove.com) SQL系列总结（三）：DML（数据操纵语言） - Roookie博客 | 记录 · 收纳 · 分享 (wlplove.com) SQL系列总结（四）：DCL（数据控制语言） - Roookie博客 | 记录 · 收纳 · 分享 (wlplove.com) SQL系列总结（五）：TCL（事务控制语言） - Roookie博客 | 记录 · 收纳 · 分享 (wlplove.com) 数据控制语言(Data Control Language，DCL)，是一种可对数据访问权进行控制的指令，它可以控制特定用户账户对数据表、查看表、存储程序、用户自定义函数等数据库对象的控制权。由GRANT和REVOKE两个指令组成。 0x01.权限的授予与收回 用户对某一数据对象的操作权称为权限。 数据库管理员拥有对数据库中所有对象的所有权限。 用户对自己建立的基本表和视图拥有全部的操作权限。 关系数据库系统中数据库模式的存取权限： 对象 操作权限 SCHEMA（模式） CREATE VIEW（视图） CREATE TABLE（基本表） CREATE、ALTER INDEX（索引） CREATE 关系数据库系统中数据的存取权限： 对象 操作权限 TABLE（基本表）、VIEW（视图） CREATE、INSERT、SELECT、UPDATE、DELETE、REFERENCES、ALL PRIVILEGES 属性列 SELECT、INSERT、UPDATE、REFERENCES、ALL PRIVILEGES SQL中使用GRANT和REVOKE语句向用户授予或收回对数据的操作权限。 GRANT GRANT语句向用户授予权限，一般格式为： GRANT <权限> ON <对象类型><对象名> TO <用户> [WITH GRANT OPTION]; 其语义为：将对某个操作对象（基本表、视图等）的指定操作权限授予某个用户 执行GRANT语句的可以是数据库管理员，也可以是数据库对象创建者（即owner）或者已经拥有该权限的用户 接受权限的用户可以是一个或多个具体用户，也可以是PUBLIC，即全体用户 [WITH GRANT OPTION]子句是可选的，如果指定了这个子句，则表示获得权限的用户还可以把这种权限再授予其他的用户（仅限于获得的这些权限），此时这些权限可以称为依赖权限。反之则该用户不能传播该权限 SQL标准允许具有WITH GRANT OPTION的用户把相应权限或其子集传递授予其他用户，但不允许循环授权，即被授权者不能把权限再授回给授权者或其祖先 例1：把查询Student表的权限授给用户U1，并允许U1将此权限授予给其他用户 GRANT SELECT ON TABLE Student TO U1 WITH GRANT OPTION; 例2：把对Student表和Course表的全部操作权限授予用户U2和U3 GRANT ALL PRIVILEGES ON TABLE Student,Course TO U2 U3; 例3：把对表SC的所有权限授予给全体用户 GRANT ALL PRIVILEGES ON TABLE SC TO PUBLIC; 例4：把查询Student表格修改学生学号的权限授给用户U4 GRANT ALTER(Sno) ON TABLE Student TO U4; 查看当前用户拥有的权限： SHOW GRANTS; 查看指定用户拥有的权限，前提是有超级用户权限： SHOW GRANTS FOR <用户名>; REVOKE REVOKE语句收回已经授予给用户的权限，一般格式为： REVOKE [GRANT OPTION FOR] <权限> ON <对象类型> <对象名> FROM <用户> [CASCADE | RESTRICT] [GRANT OPTION FOR]是可选项。如果声明了GRANT OPTION FOR，那么只是撤销对该权…

SQL系列总结（三）：DML（数据操纵语言）
type: item
date: 2021-08-02T21:17:00+00:00
description: 前排提示： 本篇博客篇幅较长，建议结合目录进行阅读！ 目录： 前言 准备数据 0x01.插入数据 1.插入元组 2.插入子查询结果 0x02.修改数据 1.普通修改 2.带有子查询的修改语句 0x03.删除数据 1.普通删除 2.带有子查询的删除语句 环境说明： 数据库：Mysql 5.5 连接软件：Navicat 前言 SQL总结系列目录： SQL系列总结（一）：DDL（数据定义语言）- Roookie博客 | 记录 · 收纳 · 分享 (wlplove.com) SQL系列总结（二）：DQL（数据查询语言）- Roookie博客 | 记录 · 收纳 · 分享 (wlplove.com) SQL系列总结（三）：DML（数据操纵语言） - Roookie博客 | 记录 · 收纳 · 分享 (wlplove.com) SQL系列总结（四）：DCL（数据控制语言） - Roookie博客 | 记录 · 收纳 · 分享 (wlplove.com) SQL系列总结（五）：TCL（事务控制语言） - Roookie博客 | 记录 · 收纳 · 分享 (wlplove.com) 数据操纵语言（Data Manipulation Language, DML）是对于数据库中的数据的基本操作。具体操作增、删、改这三种，对应的关键词是：增——INSERT、删——DELETE、改——UPDATE。 在使用数据库的系统开发过程中，对于数据库的基本操作就是“增、删、改、查”，以“CRUD”(分别为 Create, Read, Update, Delete)来称呼。 准备数据 本篇博客中出现的SQL语句实例基于下面的三张数据表： {tabs} {tabs-pane label="学生表"} Student(Sno,Sname,Ssex,Sage,Sdept) -- 创建表： CREATE TABLE Student(Sno CHAR(6) Primary KEY, -- 学号 主键 Sname VARCHAR(20), -- 名字 Ssex CHAR(2), -- 性别 Sage INT, -- 年龄 Sdept VARCHAR(20) -- 系部 )ENGINE=INNODB DEFAULT CHARSET=utf8; -- 插入数据： INSERT INTO Student VALUES('202101','李勇','男',20,'计算机系'); INSERT INTO Student VALUES('202102','刘晨','女',19,'计算机系'); INSERT INTO Student VALUES('202103','王敏','女',18,'数学系'); INSERT INTO Student VALUES('202104','张立','男',18,'信息系'); {/tabs-pane} {tabs-pane label="课程表"} Course(Cno,Cname,Cpno,Ccredit) -- 创建表： CREATE TABLE Course(Cno CHAR(1) PRIMARY KEY, -- 课程号 主键 Cname VARCHAR(20), -- 课程名 Cpno CHAR(1), -- 前置学科课程号 Ccredit INT -- 学分 )ENGINE=INNODB DEFAULT CHARSET=utf8; -- 插入数据： INSERT INTO Course VALUES('1','数据库','5',4); INSERT INTO Course VALUES('2','数学','null',2); INSERT INTO Course VALUES('3','信息系统','1',4); INSERT INTO Course VALUES('4','操作系统','6',3); INSERT INTO Course VALUES('5','数据结构','7',4); INSERT INTO Course VALUES('6','数据处理','',2); INSERT INTO Course VALUES('7','C语言','6',4); {/tabs-pane} {tabs-pane label="学生选课表"} SC(Sno,Cno,Grade) -- 创建表： CREATE TABLE SC(Sno CHAR(6), -- 学号 主键 Cno CHAR(1), -- 课程号 主键 Grade INT, -- 成绩 PRIMARY key(Sno,Cno) -- 设置表级约束条件 )ENGINE=INNODB DEFAULT CHARSET=utf8; -- 插入数据： INSERT INTO SC VALUE…

SQL系列总结（二）：DQL（数据查询语言）
type: item
date: 2021-07-30T05:17:00+00:00
description: 前排提示： 本篇博客篇幅较长，建议结合目录进行阅读！ 目录： 前言 准备数据 0x01.单表查询 1.基本查询 2.条件查询 比较大小 确定范围 确定集合 字符匹配 判断是否为空 多重条件 3.分页查询 0x02.连接查询 ——待完成 0x03.嵌套查询 ——待完成 0x04.集合查询 ——待完成 0x05.基于派生表的查询 ——待完成 环境说明： 数据库：Mysql 5.5 连接软件：Navicat 前言 SQL总结系列目录： SQL系列总结（一）：DDL（数据定义语言）- Roookie博客 | 记录 · 收纳 · 分享 (wlplove.com) SQL系列总结（二）：DQL（数据查询语言）- Roookie博客 | 记录 · 收纳 · 分享 (wlplove.com) SQL系列总结（三）：DML（数据操纵语言） - Roookie博客 | 记录 · 收纳 · 分享 (wlplove.com) SQL系列总结（四）：DCL（数据控制语言） - Roookie博客 | 记录 · 收纳 · 分享 (wlplove.com) SQL系列总结（五）：TCL（事务控制语言） - Roookie博客 | 记录 · 收纳 · 分享 (wlplove.com) 数据查询是数据库的核心操作。因此，数据查询语言DQL（Data Query Language）是SQL中的核心部分，它允许用户查询数据，这也是通常最频繁的数据库日常操作。 SQL提供了SELECT进行语句查询，该语句具有灵活的使用方式和丰富的功能。SELECT语句既可以完成简单的单表查询，也可以完成复杂的连接查询和嵌套查询。 准备数据 本篇博客中出现的SQL语句实例基于下面的三张数据表： {tabs} {tabs-pane label="学生表"} Student(Sno,Sname,Ssex,Sage,Sdept) -- 创建表： CREATE TABLE Student(Sno CHAR(6) Primary KEY, -- 学号 主键 Sname VARCHAR(20), -- 名字 Ssex CHAR(2), -- 性别 Sage INT, -- 年龄 Sdept VARCHAR(20) -- 系部 )ENGINE=INNODB DEFAULT CHARSET=utf8; -- 插入数据： INSERT INTO Student VALUES('202101','李勇','男',20,'计算机系'); INSERT INTO Student VALUES('202102','刘晨','女',19,'计算机系'); INSERT INTO Student VALUES('202103','王敏','女',18,'数学系'); INSERT INTO Student VALUES('202104','张立','男',18,'信息系'); {/tabs-pane} {tabs-pane label="课程表"} Course(Cno,Cname,Cpno,Ccredit) -- 创建表： CREATE TABLE Course(Cno CHAR(1) PRIMARY KEY, -- 课程号 主键 Cname VARCHAR(20), -- 课程名 Cpno CHAR(1), -- 前置学科课程号 Ccredit INT -- 学分 )ENGINE=INNODB DEFAULT CHARSET=utf8; -- 插入数据： INSERT INTO Course VALUES('1','数据库','5',4); INSERT INTO Course VALUES('2','数学','null',2); INSERT INTO Course VALUES('3','信息系统','1',4); INSERT INTO Course VALUES('4','操作系统','6',3); INSERT INTO Course VALUES('5','数据结构','7',4); INSERT INTO Course VALUES('6','数据处理','',2); INSERT INTO Course VALUES('7','C语言','6',4); {/tabs-pane} {tabs-pane label="学生选课表"} SC(Sno,Cno,Grade) -- 创建表： CREATE TABLE SC(Sno CHAR(6), -- 学号 主键 Cno CHAR(1), -- 课程号 主键 Grade INT, -- 成绩 PRIMARY key(Sno,Cno) -- 设置表级约束条件 )ENGINE=INNODB DEFAULT CHARSET=utf8; -- 插入数据： IN…