什么是ES
什么是ES了解ES
一款强大的开源搜索引擎
elasticsearch结合了kibana、Logstash、Beats,即elastic stack(ELK),ELK技术栈的核心是ES
广泛应用于搜索、日志分析、实时监控领域(数据可视化)
前身是Lucene,提供搜索引擎的API,记住这个人:Shay Banon
认识ES传统的数据库一般使用正向索引,ES使用倒排索引,倒排索引是term到document的索引结构(正向索引是document到term)
ducument可以理解成数据,term是数据的分词,ES面向文档(document)存储,文档以json序列化的格式存储在ES中
相同类型的json的集合(document的集合),作为索引(Index)
建立term到document的映射表,基于term来查询document编号;查询过程如图:
MySQL和ES各自的优势领域:
MySQL: 事务类型操作,数据安全性,一致性
ES:海量数据搜索、分析、计算
二者可以互补,如下图架构:
JVM基础
JVMJVM(Java Virtual Machine,Java 虚拟机)是 Java 程序的运行环境,是 Java 语言的核心和关键部分之一。
JVM负责将.class字节码转化成机器码,能够根据不同的硬件平台和操作系统进行了优化和适配。
基本组成
类加载子系统:
功能:加载类文件(.class),生成类对象
组成:启动类加载器、扩展类加载器、应用程序类加载器
运行时数据区:
功能:用于存放Java程序运行时的数据,包括类的信息、对象实例、方法调用栈、线程状态等
执行引擎:
功能:负责执行Java程序中的字节码指令,将字节码翻译成硬件支持的指令集格式
组成:解释器、即时编译器(JIT编译器)
本地接口:
功能:允许Java程序调用本地方法库中的本地方法,实现更底层的功能和操作
垃圾回收器(GC)和内存管理子系统:
功能:管理Java程序的内存资源,包括内存分配、回收、释放
组成:GC、堆内存管理器
从功能上看,可以分为类加载系统、内存管理系统、执行引擎、本地接口
类加载机制什么是类加载机制JVM将.class文件依次进行 加载 => 连接(验证、整备、解 ...
限流详解
限流(Rate Limiting)详解定义限流(Rate Limiting)是指在单位时间内限制某个操作的最大执行次数,以防止系统过载、资源枯竭或拒绝服务攻击(DDoS)。
通过限流,可以确保系统在高并发访问时仍能保持稳定性和高可用性。
使用场景限流在各种场景中都能发挥重要作用,主要包括但不限于以下几种:
API网关:限制客户端对后端服务的请求频率,防止恶意请求导致服务不可用。
用户操作:防止单个用户频繁操作,如频繁登录尝试、评论、点赞等。
分布式系统:在分布式系统中控制对某些共享资源的访问频率,防止资源竞争导致系统性能下降。
消息队列:控制消息的生产或消费速率,防止消息队列积压或系统过载。
如何使用限流限流的实现可以通过多种方式进行,常见的方法有以下几种:
客户端限流:在客户端对请求频率进行控制,防止过多请求发送到服务器。
服务器端限流:在服务器端对接收到的请求进行控制,常见的做法是在API网关或服务层实现限流逻辑。
中间件限流:使用第三方中间件或库实现限流,如Redis、Nginx等。
以下是一些具体的实现示例:
基于Redis的限流Redis是一个高性能的内存数据库,可以 ...
为什么需要不可变类?
为什么需要不可变类?不可变类一旦创建,其状态就不能被修改,这带来了多个方面的好处
包括:
线程安全性
简化代码
提高性能
…
不可变类不代表类内变量不可变,而是状态(字段值)不可变
线程安全性多线程环境中的安全性:由于不可变对象一旦创建就不能改变状态,它们天生是线程安全的。
多个线程可以安全地共享和访问同一个不可变对象,而不需要同步机制来避免并发修改的问题。
简化代码减少复杂性:不可变对象的状态不会改变,因此在处理它们时,不需要考虑对象状态的变化。这简化了代码,减少了错误的可能性。
安全性:不可变对象可以安全地传递给方法、存储在集合中或返回给调用者,而不需要担心它们会在其他地方被修改。
提高性能缓存:不可变对象可以被缓存和重用。一个典型的例子是字符串池(String Pool),其中相同的字符串字面量被缓存,以减少内存使用和提高性能。
哈希码缓存:由于不可变对象的状态不变,它们的哈希码也不会变化。因此,可以在创建对象时计算并缓存哈希码,以提高集合(如哈希表和哈希集)的性能。
易于维护和调试更容易理解和维护:由于不可变对象的状态一旦创建就不变,理解和维护这些对象的代码变得更加 ...
为什么Java不支持多继承
为什么Java不支持多继承第一,降低类关系复杂度
第二,避免菱形继承问题:A->B , A->C, B&C->D ,现在,D调用A的方法,B,C都有重写,产生冲突
接口与抽象类的区别
接口与抽象类的区别总览
特性
接口
抽象类
方法实现
只能包含抽象方法(Java 8 之后支持默认方法和静态方法)
可以包含抽象方法和具体方法
成员变量
只能包含常量(默认 public static final)
可以包含实例变量、静态变量和常量
多重继承
一个类可以实现多个接口
一个类只能继承一个抽象类
访问修饰符
方法默认是 public
方法可以是 public、protected 或 default
构造器
没有构造器
可以有构造器
适用场景
定义一组不相关类的共同行为
定义一组相关类的共同行为和属性
实现和继承
implements
extends
版本要求
Java 8 之前只能包含抽象方法
任意版本支持
区别
接口使用 interface ,抽象类使用 abstract
一个类可以实现多个接口,但只能继承一个抽象类
接口成员变量一定是public static final,抽象类成员变量没有约束
接口没有构造函数,抽象类可有可无
接口的方法一般是public abstract (Java8 后有default和stati ...
ForkJoinPool详解
ForkJoinPool详解是什么ForkJoinPool 是 Java 并发包(java.util.concurrent)中的一种特殊线程池,用于执行分治任务。
ForkJoinPool 使用了一种工作窃取(work-stealing)算法,允许线程动态获取其他线程队列中的任务,以最大化 CPU 利用率和任务处理效率。
使用场景ForkJoinPool 特别适合以下场景(CPU密集型):
递归分治算法:如快速排序、归并排序等,需要将问题分解成更小子问题的算法。
大规模数据处理:需要并行处理大数据集,如数组、集合的并行操作。
核心组件ForkJoinTask:这是 ForkJoinPool 中执行的任务的基本类型,有两个主要子类:
RecursiveTask:有返回结果的任务。
RecursiveAction:没有返回结果的任务。
工作窃取算法:每个工作线程都有自己的双端队列(deque),线程可以从自己的队列头部获取任务执行。当一个线程完成自己的任务时,它会从其他线程的队列尾部窃取任务,以减少空闲时间,提高并行性。
示例代码下面是一个使用 ForkJoinPool 计算 ...
MySQL如何实现数据排序
MySQL如何实现数据排序MySQL 实现排序的方式大概有两种,一种是索引排序,另一种是文件排序
索引排序顾名思义,使用索引排序,通常意味着 ORDER BY 的列都在索引中,可以直接通过索引进行排序,这种方式效率最高,因为索引本身就是有序的
文件排序当无法完全使用索引排序的时候,就需要进行文件排序。
文件排序有两种,内存排序和磁盘文件临时排序
内存排序MySQL在内存中有一个排序缓冲区,sort_buffer,如果待排序的列取出后没有超过这个缓冲区的大小,就会在 sort_buffer 中进行排序,这个过程也被称为内存排序
sort_buffer 有一个相关的参数,max_length_for_sort_data,超过这个值就会触发双路排序
内存排序有两种,单路排序和双路排序,单路排序可能需要回表一次,也可能不会表(如果SELECT的列全都是ORDER BY的列),双路排序至少要回表一次
假设执行
1SELECT a, b, c from your_table order by a, b
单路排序如果查询带a,b,c列的数据行的大小没有超过 max_length_for_sor ...
MySQL如何调整 sort_buffer_size的大小
MySQL如何调整 sort_buffer_size的大小sort_buffer_size 是 MySQL 中一个重要的系统变量,用于排序操作时分配的内存大小。
调整这个参数可以优化排序操作的性能,尤其是在执行大量排序操作时。
调整 sort_buffer_size 可以通过以下几种方式进行:
临时调整(会话级别)你可以在当前会话中临时调整 sort_buffer_size,这种调整只对当前会话有效。当会话结束后,设置会恢复为全局设置。
1SET SESSION sort_buffer_size = 1048576; -- 设置为 1MB
永久调整(全局级别)如果你希望永久调整 sort_buffer_size,需要修改 MySQL 的配置文件(通常是 my.cnf 或者 my.ini),然后重启 MySQL 服务。
打开 MySQL 配置文件(例如 /etc/my.cnf 或者 C:\ProgramData\MySQL\MySQL Server 8.0\my.ini),找到 [mysqld] 部分,添加或修改 sort_buffer_size 设置:
12[mysqld]sor ...
Spring Boot 集成 Servlet 带来的好处
Spring Boot 集成 Servlet 带来的好处Spring Boot 通过自动配置和简化配置的方式,使得开发者不需要直接与Servlet API频繁打交道,从而简化了Web应用的开发。
以下是Spring Boot封装Servlet的一些具体方式:
自动配置:Spring Boot 提供了很多自动配置类,这些类可以自动根据类路径中的依赖和应用程序的配置来配置常见的Servlet组件。例如,DispatcherServlet会被自动配置和注册。
Spring MVC:Spring Boot 默认集成了Spring MVC,这是一种基于Servlet的Web框架。通过Spring MVC,开发者可以使用注解(如@RestController、@RequestMapping)来定义控制器,而不需要直接编写Servlet类。
嵌入式Servlet容器:Spring Boot可以使用嵌入式的Servlet容器(如Tomcat、Jetty、Undertow),这使得开发者可以将Web应用打包成一个可执行的JAR文件,而不需要单独部署到外部的Servlet容器中。
过滤器和监听器:S ...
Spring Boot 配置 Servlet
Spring Boot 配置 ServletSpring Boot 集成了 Servlet,极大的简化了开发,一般俩说,我们只需要通过配置文件配置一个server端口就可以,以下内容了解即可
Spring Boot 提供了多种方式来修改 Servlet 的配置。
常见的方法包括:
通过 application.properties 文件进行配置
通过 Java 配置类进行配置
通过 application.properties 配置可以在 application.properties 文件中设置一些常见的 Servlet 参数。例如:
12345678# 设置服务器端口server.port=8081# 设置上下文路径server.servlet.context-path=/myapp# 设置session超时时间(单位:秒)server.servlet.session.timeout=3600
通过 Java 配置类进行配置如果你需要对 Servlet 做更复杂的配置,可以通过 Java 配置类来实现。以下是一个示例:
1234567891011121314151617imp ...
http从请求到响应
http从请求到响应在一个标准的Java Web应用中,当一个HTTP请求从Tomcat到Controller的过程中,会经历多个阶段,包括Tomcat的请求处理、Filter链的处理、Servlet的处理、Interceptor拦截以及最终的Controller处理。
Step 1. Tomcat 接收到请求当客户端(例如浏览器)发送一个HTTP请求时,Tomcat作为Web服务器首先接收到该请求。Tomcat会根据请求的URL找到对应的Web应用,并将请求交给该Web应用的Servlet容器进行处理。
Step 2. 创建 HttpServletRequest 和 HttpServletResponse 对象Tomcat会创建HttpServletRequest和HttpServletResponse对象,这两个对象封装了HTTP请求和响应的所有信息。
Step 3. 过滤器链(Filter Chain)在请求到达Servlet之前,Tomcat会先经过一系列的过滤器(Filter)。这些过滤器可以对请求和响应进行预处理和后处理。过滤器链的处理步骤如下:
过滤器初始化:在 ...
何为 ObjectFactory
何为 ObjectFactory
顾名思义,是一个对象工厂,封装了对象的创建过程
Spring单例模式的Bean在创建的过程会用到三级缓存机制,在三级缓存的Map中存储的就是ObjectFactory
ObjectFactory用于延迟代理对象的创建,用于判断这个Bean是否有代理,如果有代理就返回代理对象,否则返回原本的对象
FactoryBean 详解
FactoryBean 详解FactoryBean 是 Spring 框架提供的一种特殊的 Bean,它允许我们自定义实例化逻辑,并且可以控制 Spring 容器中 Bean 的创建过程。
使用 FactoryBean 可以实现一些复杂的实例化过程,或者用来创建一些第三方库的对象,这些对象可能并没有默认的构造方法,或者需要某种特定的初始化方式。
为什么需要 FactoryBean?FactoryBean使用了代理的思想,通过FactoryBean,可以实现:
复杂的实例化逻辑:有时候我们需要创建的对象比较复杂,无法通过简单的构造函数或属性注入完成,这时可以使用 FactoryBean。
延迟初始化:某些对象的创建可能比较耗时,或者依赖于某些运行时参数,使用 FactoryBean 可以更灵活地控制这些对象的创建时机。
封装第三方库对象的创建:有些第三方库的对象创建可能需要复杂的配置或初始化步骤,FactoryBean 可以很好地封装这些细节。
FactoryBean 的使用要使用 FactoryBean,需要实现 org.springframework.beans.fact ...
BeanFactory 详解
BeanFactory 详解简介BeanFactory 是 Spring 框架中最基础的接口之一,它定义了 Spring 容器中管理 bean 的基本功能。
BeanFactory 是 IoC(Inversion of Control,控制反转)容器的核心,它负责实例化、配置和管理应用程序中的对象(bean)。
BeanFactory 的核心概念BeanFactory 提供了一种从 Spring 容器中获取 bean 的方法。其核心概念包括:
Bean:由 Spring 容器管理的对象。
Factory:BeanFactory 作为工厂模式的实现,负责创建和管理 bean 的实例。
IoC 容器:BeanFactory 是 Spring IoC 容器的一种实现,负责管理应用程序的依赖关系。
BeanFactory 的实现BeanFactory 是一个接口,Spring 提供了多个实现类,其中最常用的是 DefaultListableBeanFactory。以下是一些常见的实现类:
XmlBeanFactory
1234567891011121314151617181920 ...
Spring Bean 详解
Spring Bean 详解Spring 的核心是依赖注入(Dependency Injection, DI)和面向切面编程(Aspect-Oriented Programming, AOP)。
在 Spring 框架中,Bean 是一个核心概念,是Spring管理的基本单位。
本文将详细介绍 Spring Bean 的相关内容,包括其定义、生命周期、配置方式和常见用法。
什么是 Spring Bean在 Spring 框架中,Bean 是由 Spring IoC 容器管理的对象。
简单来说,任何一个由 Spring 容器初始化、装配和管理的对象都可以被称为 Spring Bean。
Bean 是应用程序的核心构建块,通过配置文件或者注解来定义,Spring 容器负责它们的生命周期和依赖关系。
Spring Bean 的生命周期Spring Bean 的生命周期包括以下几个阶段:
实例化(Instantiation):Spring 容器通过反射机制创建 Bean 的实例。
属性赋值(Populate Properties):Spring 容器将配置文件中指定的属性赋值给 Bea ...
count(column_name),count(1),count(*)
count(column_name),count(1),count(*)count()用于统计行数,常见用法有:
count(column_name)
count(1)
count(*)
区别
count(column_name) 只能统计非空的数据行,而count(1)/count(*)则会统计所有行
count(1)和count(*)的效率一致,但是count(*)的成本更低
对于InnoDB,count(1)和count(*)都不适合大规模数据,对于MyISAM,维护了一个size属性来表示数据总数
为什么count(*)成本更低,因为二级索引比聚簇索引占用的存储空间更小
Maven创建子模块
Maven创建子模块在一个多模块的Maven项目中,通常使用<module>标签在父POM(Project Object Model)文件中来定义子模块。
这样可以将多个Maven项目组织在一起,使它们成为一个整体的构建单元。
如何定义子模块
首先,创建一个父项目的POM文件pom.xml,其中包含所有子模块的定义:
12345678910111213141516<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> ...
SQL必知必会-读书笔记(九)
SQL必知必会-读书笔记(九)何为查询(query)
本质上任何SQL都是查询。但此术语一般用于SELECT语句
子查询
子查询总是从内向外处理
MySQL 中,子查询并不局限于仅仅只能查询单列,但对于部分SQL语言来说,可能限制只能查询单列
子查询并不总是执行数据检索最有效的方法,视具体情况,联表的优先级会大于子查询
有多个查询时,尽量用完全限定列名(表名.列名)
子查询常用于 IN() 中
联表 JOIN
联表是关系型数据库最关键,最核心,最灵魂的操作
关系型数据库为了保证良好的可伸缩性,通常会将关系和具体内容分开存储,在查询完整信息时,就需要使用到 JOIN
JOIN 时不加条件,最终返回的结果将会是两张表的笛卡尔积,检索出的行数将是表1的行数×表2的行数,这种联结也叫叉联结
ON 条件为等值时也叫等值联结
联结是很消耗资源的,联结的表越多,性能下降越厉害,虽然SQL本身不限制每个联结约束中表的数量,但原则上联结的表越少越好
使用联结时可以多看执行计划,找出最合适的联结方案
lombok使用教程
lombok使用教程
Lombok 是一个用于简化 Java 编程的库,它通过注解来自动生成样板代码,从而减少了手动编写样板代码的繁琐。
@Getter 和 @Setter
自动为类中的字段生成 getter 和 setter 方法。
@Getter 和 @Setter 不具有可选参数。它们的作用是生成 getter 和 setter 方法,默认生成所有字段的 getter 和 setter。
@ToString
自动生成 toString() 方法。
**includeFieldNames**:是否包括字段名。
默认值:false
作用:设置为 true 时,生成的 toString() 方法会包含字段名,例如 "Person(name=John, age=30)"。
**exclude**:排除某些字段。
默认值:空数组
作用:指定要排除在 toString() 方法中的字段。例如,@ToString(exclude = "age") 将排除 age 字段。
**callSuper**:是否调用父类的 toString ...
Swagger Knife4j 使用总结
Swagger Knife4j 使用总结
使用 Swagger 和 Knife4j 来增强 API 文档和界面,方便开发者做一些简单的功能测试,也方便了前后端联调
Step 1. 导入依赖123456789101112<!-- https://doc.xiaominfo.com/docs/quick-start#openapi2 Swagger + Knife4j --><dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>knife4j-openapi2-spring-boot-starter</artifactId> <version>4.4.0</version></dependency><!-- Hibernate Validator for data validation --><dependency> <groupId>org.h ...
SQL必知必会-读书笔记(八)
SQL必知必会-读书笔记(八)GROUP BY
分组,可以和聚合函数配合,例如:
123456# 统计按照x_id分组后,每个分组的个数。如果不加 GROUP BY,相当于统计所有行的数量SELECT x_id, count(*) as x_num FROM your_tableGROUP BY x_id
GROUP BY子句可以包含任意数目的列,可以进行更精细的分组
不管有多少列,建立分组时,所有的列都是当成一个整体处理,所以不能从个别的列取回数据
GROUP BY子句的每个列都必须是检索列或有效表达式(不能是聚集函数),如果SELECT中使用了表达式,GROUP BY子句中也要指定相同的表达式,不能使用别名
大多数SQL不允许GROUP BY列带有长度可变的数据类型(MySQL允许,但是不建议,因为分组时处理字符数据比较慢)
除聚集计算语句外,SELECT的每一列都必须在GROUP BY子句中给出
如果分组中包含具有 NULL 值的行,则NULL会作为一个分组返回,如果列中有多行NULL值,它们将会被作为一个分组
GROUP BY必须出现在WHERE语句之后,O ...
Spring核心代码模块-总览
Spring核心代码模块-总览Spring 最主要的核心就是 IOC 容器,这个容器根据我们的配置文件创建了各种 Bean 且编织它们之间的依赖关系,管理这些 Bean 的生命周期。所以最核心的代码模块是:
spring-core:核心类库,包括资源访问等一些工具类,别的模块都会依赖此模块
spring-beans:对 Bean 的支持,包括控制反转和依赖注入,核心工厂 BeanFacotry 就在这个模块。
spring-context:Spring 的上下文,支持数据验证、国际化、事件传播等支持,ApplicationContet 就在这里,可以理解为运行时的 Soring 容器
基于上面的这些核心模块,Spring 也提供了很多重要的支持:
spring-aop:AOP 的支持
spring-jdbc:jdbc的支持
spring-orm: orm 的支持
spring-webmvc: mvc 的支持
SQL必知必会-读书笔记(七)
SQL必知必会-读书笔记(七)COUNT() 函数
COUNT(*) : 计算表中行的数目
COUNT(cloumn_name) : 计算column_name的行数,会忽略NULL
MAX() 函数
MAX() 函数会忽略表中的 NULL 值
MAX() 作用于非字符型数据时,返回排序后的最后面的行
MIN() 函数
MIN() 函数会忽略表中的 NULL 值
MIN() 作用于非字符型数据时,返回排序后的最前面的行
SUM() 函数
可以使用多个列的值计算 SUM,例如:SUM(column1 * column2)
SUM() 函数会忽略表中的 NULL 值
DISTINCT
DISTINCT 不能用于 COUNT(*)
DISTINCT 可以用于 MIN(),MAX(),但没有意义
MyBatis XML文件详解
MyBatis XML文件详解定义文件版本、编码、规范通常写在xml文件开头
12<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
定义命名空间定义这个xml文件对应到哪一个mapper接口文件上,namespace 建议写全路径名
正文部分可以定义各种 resultMap 和 CRUD的SQL语句
123<mapper namespace="com.jd.y.insight.domain.repository.mybatis.mapper.master.ext.IndustryCompanyRelationExtMapper"><!-- 正文 --></mapper>
定义result ...
MySQL查询时拼接列名
MySQL查询时拼接列名在 MySQL 中,拼接字段最常用的方法是使用 CONCAT() 函数和 CONCAT_WS() 函数。
使用 CONCAT() 函数CONCAT() 函数用于将多个字符串连接成一个字符串。如果任何一个参数为 NULL,CONCAT() 函数会将其视为空字符串并继续连接其他参数。
语法:1CONCAT(string1, string2, ..., stringN)
拼自定义字符串:12SELECT CONCAT('Hello, ', 'world!', ' How are you?') AS result;-- output:Hello, world! How are you?
拼字段:12SELECT CONCAT(first_name, ' ', last_name) AS full_nameFROM employees;
使用 CONCAT_WS() 函数CONCAT_WS() 函数与 CONCAT() 类似,但它允许你指定一个分隔符,将其插入到拼接的字符串之间。 ...
Spring 循环依赖详解
Spring 循环依赖详解什么是循环依赖循环依赖(Circular Dependency)是指两个或多个模块(组件、类、服务等)之间互相依赖,从而形成一个循环的依赖关系。
这种情况在软件开发中是比较常见的一个问题,尤其是在复杂的系统中。
为什么会出现循环依赖循环依赖通常是由于以下几个原因导致的:
模块间的紧密耦合:模块之间的耦合度过高,彼此依赖过于密切。
不合理的设计:系统设计时没有充分考虑模块的独立性和复用性。
单一职责原则的违反:模块的职责过于复杂,导致需要依赖多个其他模块来完成其功能。
循环依赖的问题
难以维护:模块之间的耦合度过高,修改一个模块可能需要修改多个相关模块。
难以测试:由于模块之间的依赖关系复杂,独立测试某个模块变得困难。
可能导致运行时错误:在某些情况下,循环依赖可能导致程序在运行时崩溃或出现异常,有时候甚至连编译的无法通过。
如何解决循环依赖使用构造器注入与Setter注入的结合使用构造器注入时,循环依赖会导致两个或多个bean无法实例化,因为每个bean在实例化时都需要另一个尚未实例化的bean。
Setter注入可以部分缓解这个问题,因为Spri ...
SQL必知必会-读书笔记(六)
SQL必知必会-读书笔记(六)LIKE 操作符
LIKE 只能用于搜索字符串
LIKE 可以使用通配符
LIKE 支持的通配符有:
‘%’ :任意数量任意字符
‘_’ :单一的任意字符
‘[JD]’ : ‘[…]’用于指定字符集
REGEXP 操作符REGEXP(也可以使用 RLIKE)用于更复杂的模式匹配,它支持正则表达式语法中的通配符:
**.**:表示任意单个字符。
1SELECT * FROM employees WHERE name REGEXP '^J.n$';
上述查询将返回名字是 “Jan”、”Jen”、”Jon” 等员工,但要求匹配的是完整的字符串。
**[ ]**:表示匹配括号内的任意字符。可以定义一个字符集或字符范围。
1SELECT * FROM employees WHERE name REGEXP '^[JH]en$';
上述查询将返回名字是 “Jen” 或 “Hen” 的员工。
**[^ ]**:表示匹配不在括号内的任意字符。
1SELECT * FROM employees WHERE nam ...
SQL必知必会-读书笔记(五)
SQL必知必会-读书笔记(五)AND 与 OR 执行顺序
和C语言等一众编程语言没有什么不同,在没有 ‘(‘ 和 ‘)‘ 时,SQL执行时也是先执行 AND 后执行 OR
IN 操作符为什么使用 IN 操作符
合法选项较多时,IN操作符更加清楚直观
IN 一般比 OR 执行得更快
IN 最大的优点是 IN 内部可以是一个子查询
NOT 操作符
NOT 操作符用于否定(取反)某一个查询条件
SQL必知必会-读书笔记(四)
SQL必知必会-读书笔记(四)SQL过滤与应用过滤
在实际开发中,我们可以选择SQL过滤,也可以选择应用过滤。但不管如何,都建议使用SQL过滤,
理由如下:
SQL过滤的效率通常高于应用过滤(尤其是SQL优化后)
在应用端处理数据库的工作会极大地影响应用性能,并使应用不具备可伸缩性
使用应用过滤时,服务器不得不通过网络发送大量数据,浪费了带宽
操作符兼容问题
我们知道 != 和 <> 的含义是一样的,但是从不同 DBMS 兼容性的角度考虑,更加推荐使用 <>
空值 NULL
空值 NULL 是一种特殊的值,通常使用 IS NULL 或 IS NOT NULL 来进行条件过滤
NULL 与任何值比较都是 NULL
NULL 在布尔类型中既不是 true 也不是 false
举个例子,假设执行:
1SELECT * FROM your_table WHERE column1 <> 1
该语句不会包括 column1 为 NULL,因为 NULL <> 1 -> NULL,而不是true
SQL必知必会-读书笔记(三)
SQL必知必会-读书笔记(三)何为子句(clause)
子句由关键字+数据组成
例如
12SELECT your_column -- 子句1FROM your_table -- 子句2
ORDER BY细节细节一
ORDER BY 默认只影响前一个列,例如
1SELECT your_column FROM your_table ORDER BY A,B,C,D DESC -- DESC 只影响了 D 字段
在 MySQL 中,ORDER BY 默认是 ASC,例如
123SELECT your_column FROM your_table ORDER BY A,B,C,D DESC -- DESC 只影响了 D 字段# 等价为SELECT your_column FROM your_table ORDER BY A ASC,B ASC,C ASC,D DESC
细节二
ORDER BY 可以用列的序号代替列名(序号从1开始)
1234# 假设字段A,B,C,D分别位于3,4,5,6列,序号从1开始SELECT your_column FROM your_table ORDER ...
SQL必知必会-读书笔记(二)
SQL必知必会-读书笔记(二)
结束SQL语句
多条SQL必须适用 ; 分割
单条SQL是否需要 ; 结束取决于DBMS
事实上,多个 ; 没有坏处
SQL语句大小写
SQL 语句不区分大小写,但是,一个关键字尽量全部大写或者全部小写
许多开发人员喜欢关键字大写,表名、列名小写,我也一样。但在实际开发时,可以选择保护你的右手小指关节,敲敲小写🤦
适当使用空格
SQL 语句在处理时会忽略空格,所以可以把SQL拆成多行,这样更好读
使用通配符
什么时候用通配符 * ?
当我们需要所有列的时候
当我们不知道列名的时候
事实上,应该尽可能减少通配符的使用,因为检索不需要的列会降低检索速度和应用程序的性能
DISTINCT 的使用
DISTINCT 用于去重,一旦使用就会作用于被检索的全部列,DISTINCT 不能仅作用于部分列
限制查询结果
对于 ANSI SQL
1SELECT TOP 5 your_column FROM your_table -- 只检索前 5 行
对于 DB2
1SELECT 5 your_column FROM your_t ...
ApplicationContext详解
ApplicationContext详解ApplicationContext 是 Spring 框架中的核心接口之一,代表了 Spring 容器的上下文。
ApplicationContext 提供了对应用程序的所有 Beans 的访问,并支持许多功能,包括依赖注入、事件发布和 AOP(面向切面编程)。
定义与功能ApplicationContext 是 Spring 的一种配置容器,它能够:
加载 Bean 的定义
创建 Bean 实例
管理 Bean 的生命周期
提供了配置、服务和其他功能的支持。
主要功能
Bean 的管理:负责 Bean 的创建、初始化和销毁。
依赖注入:自动将 Bean 的依赖注入到其他 Bean 中。
事件发布:发布应用程序事件,例如上下文刷新事件、Bean 创建事件等。
国际化支持:支持消息的国际化。
资源加载:可以加载资源文件,例如属性文件和 XML 文件。
常见实现Spring 提供了多种 ApplicationContext 的实现,以下是几个常见的实现:
**ClassPathXmlApplicationContext**:从类路径下 ...
Spring框架注解读取配置文件
Spring框架注解读取配置文件
Spring提供了多种方式来读取配置文件,包括使用@Value注解和@ConfigurationProperties注解。
使用 @Value 注解@Value 注解用于将配置文件中的单个属性值注入到Bean的字段、构造函数或方法参数中。
@Value 注解可以从application.properties 或 application.yml 文件中读取值。
1. application.properties 示例12app.name=MyAppapp.version=1.0.0
2. 读取 application.properties 中的值12345678910111213141516171819202122232425262728293031import org.springframework.beans.factory.annotation.Value;import org.springframework.stereotype.Component;@Componentpublic class AppConfig { @Va ...
Spring注解式依赖注入
Spring注解式依赖注入在Spring框架中,依赖注入(Dependency Injection, DI)是核心功能之一,通过DI可以使得组件之间的依赖关系解耦,方便管理和维护。
依赖注入(DI)是一种软件设计模式,用于实现对象之间的松耦合。这种模式通过将对象的依赖(即被依赖的对象)注入到对象中,而不是在对象内部直接创建依赖,从而实现对象之间的解耦。DI是控制反转(Inversion of Control, IoC)的一种实现方式。
本文将详细介绍常用的注解:@Autowired、@Resource、@Qualifier、@Inject、@Lookup,并说明它们的使用场景和区别。
@Autowired概述@Autowired是Spring框架中用于自动注入依赖的注解。它可以标注在字段、构造方法、Setter方法上。
使用方式
字段注入:
字段式注入是项目中最常见的DI方式
1234567@Componentpublic class MyService { @Autowired private MyRepository myRepository; ...
MyBatis一词的由来
MyBatis一词的由来Batis的含义:
MyBatis中的“Batis”实际上是“iBATIS”的一部分。
iBATIS最早是由Clinton Begin开发的一个数据持久化框架。
iBATIS这个名字中的“i”代表Internet,“BATIS”是一个英文单词“Baptist”的变形,原意是指“浸礼会的”,引申为“浸入、洗礼”的意思,寓意该框架可以帮助开发者浸入数据访问的世界。
MyBatis的来历:后来,iBATIS项目被Apache Software Foundation接管,并且继续开发和维护。2010年,iBATIS团队决定将项目迁移到Google Code,并且重新命名为MyBatis。这个名字有两个含义:
“My”表示个性化,强调开发者可以根据自己的需求对框架进行配置和使用。
“Batis”则延续了iBATIS的传统,保留了其浸入数据访问的含义。
MyBatis insert 的同时返回对应的行id
MyBatis insert 的同时返回对应的行id如何使用?123<insert id-"xx" paramType="xx.xx.xx" resultType="yy.yy.yy" useGeneratedKeys="true" keyProperty="id"> -- SQL --</insert>
useGeneratedKeys=”true” keyProperty=”id” : 添加这部分代码(属性),即可令MyBatis insert 返回id而不是插入的数量
注意点:
useGeneratedKeys="true"和keyProperty="id"这两个属性通常在MyBatis或类似的ORM框架中用于插入(INSERT)操作,当执行插入操作时,这些属性用于获取数据库自动生成的主键并将其赋值回对象的id属性。
在执行删除(DELETE)操作时,这些属性不适用。删除操作通常返回的是 ...
SQL必知必会-读书笔记(一)
SQL必知必会 - 读书笔记(一)何为数据库(DataBase)
保存有组织的数据的容器(通常是一个文件或者一组文件)
何为表(Table)
某种特定类型数据的结构化清单
使表成为唯一的,实际上是数据库名和表名的组合
何为行(Row)
表中的一个记录
有时人们提到行(Row)时也将其称为数据库记录(Record),这两个术语是互通的,但从技术上来讲,行才是正确术语
何为列(Column)
表中的一个字段。所有的表都是由一个或多个列组成的
Q:何为数据类型 ?
A:描述该列允许什么类型的数据
问题延申 - 数据类型兼容问题:
数据类型及名称是SQL不兼容的一个主要原因
虽然多数SQL都支持基本的数据类型,但是高级的数据类型却不互通
更糟的是,偶尔会有相同数据类型,但在DBMS里具有不同的名称
重要的是,我们要在创建表结构时记住这些差异
何为主键(primary key)
一列(或几列),其值能够唯一标识表中的每一行
关于主键:
任意两行都不具有相同的主键值
每一行都必须有主键值(Not NULL)
主键列不允许修改或更新
主键不能重用(如果某行从表中删除,它的主键 ...
