小菜鸟

java菜鸟号正在起航

SQL 关系分类与语言分类详解

SQL(结构化查询语言)是操作关系型数据库的标准语言,其体系可从关系类型语言功能两个维度进行分类。理解这些分类有助于清晰把握 SQL 的核心功能和应用场景。

SQL 关系分类(数据存储形式)

SQL 中涉及的 “关系” 本质上是二维表结构,根据存储方式和生命周期可分为三类:

1. 表(Table):物理存储的基础关系

  • 定义:数据库中永久存储的二维表,包含行(记录)和列(字段),是数据的物理载体。

  • 特性:

    • 独立存在于数据库中,数据持久化存储在磁盘上。
    • 支持 INSERTUPDATEDELETE 等操作修改数据。
    • 结构由 CREATE TABLE 定义,可通过 ALTER TABLE 修改。
  • 示例:

    -- 创建表(物理存储)
    CREATE TABLE users (
      id INT PRIMARY KEY,
      name VARCHAR(50) NOT NULL
    );

2. 视图(View):逻辑定义的虚拟关系

  • 定义:由 SELECT 查询定义的虚拟表,不实际存储数据,仅保存查询逻辑,使用时动态计算结果。

  • 特性:

    • 数据依赖于基础表(视图的数据源),基础表数据变化会实时反映到视图。
    • 可简化复杂查询(将多表关联逻辑封装为视图),并限制用户访问范围(如隐藏敏感字段)。
    • 支持 SELECT 操作,部分视图可通过 INSERT/UPDATE/DELETE 修改(需满足特定条件,如基于单表且包含主键)。
  • 示例:

阅读全文 »

Spring 依赖注入(DI)详解:从原理到实践

依赖注入(Dependency Injection,简称 DI)是 Spring 框架的核心特性之一,是控制反转(IoC)思想的具体实现。它通过容器自动管理对象之间的依赖关系,替代了传统代码中手动创建依赖对象的方式,大幅降低了代码耦合度。本文从 “DI 核心概念” 到 “两种注入方式实战”,系统解析 Spring DI 的工作原理与最佳实践。

DI 与 IoC:理解核心概念

1. 传统开发的痛点:主动依赖导致高耦合

在没有 DI 的时代,对象需要主动创建其依赖的对象,导致代码耦合严重,难以维护和测试:

public class Person {
    // 主动创建依赖对象,耦合度高
    private Car car = new Car();
    private House house = new House();
    
    // 业务逻辑依赖于具体的 Car 和 House 实现
    public void goOut() {
        car.drive(); // 直接依赖 Car 实例
    }
}

问题:若 Car 构造器变化(如新增参数),Person 类必须修改;更换 Car 实现(如从 Benz 改为 BMW),需修改 Person 代码。

2. 控制反转(IoC):反转依赖的创建权

IoC 核心思想:将对象的创建和依赖管理交给容器,对象只需 “被动接收” 依赖,无需主动创建。

  • 传统方式:对象 → 主动创建依赖(正转控制);
  • IoC 方式:容器 → 主动注入依赖给对象(反转控制)。

Spring 中,IoC 容器(如 BeanFactoryApplicationContext)是实现者,负责:

  • 管理对象的生命周期(创建、初始化、销毁);
  • 解析对象之间的依赖关系;
  • 在对象需要时自动注入依赖。

3. 依赖注入(DI):IoC 的具体实现

DI 是 IoC 的一种具体表现形式:容器在实例化对象时,自动将其依赖的对象注入进来,对象无需关心依赖的来源和创建过程。

阅读全文 »

Spring Bean 的继承与依赖:复用配置与控制实例化顺序

在 Spring 中,Bean 的继承和依赖是两种重要的配置机制。继承用于复用配置(减少重复代码),依赖用于控制 Bean 的实例化顺序。详细解析这两种机制的实现方式、使用场景及注意事项。

Bean 的继承:复用配置,减少冗余

Spring 中的 Bean 继承并非 Java 中的类继承(不涉及类的父子关系),而是配置的继承:子 Bean 可以继承父 Bean 的所有配置(属性、依赖等),并可覆盖父 Bean 的配置。这类似于 “模板模式”,父 Bean 定义通用配置,子 Bean 仅需定义差异化部分。

1. 基本使用:通过 parent 属性实现继承

(1)普通 Bean 作为父 Bean

父 Bean 可以是一个可实例化的普通 Bean,子 Bean 通过 parent 属性指定父 Bean 的 id,从而继承其配置。

示例:

<!-- 父 Bean:定义通用配置 -->
<bean id="parentPerson" class="com.zhanghe.study.spring4.beans.beantest.Person">
    <property name="name" value="张三"/> <!-- 通用属性:姓名 -->
    <property name="car" ref="car"/>     <!-- 通用依赖:Car 对象 -->
    <property name="cars">               <!-- 通用集合:List<Car> -->
        <list>
            <ref bean="car"/>
            <ref bean="car2"/>
        </list>
    </property>
</bean>

<!-- 子 Bean:继承父 Bean 并覆盖部分配置 -->
<bean id="sonPerson" parent="parentPerson">
    <!-- 覆盖父 Bean 的 name 属性 -->
    <property name="name" value="张飞"/>
    <!-- 继承父 Bean 的 car、cars 配置,无需重复定义 -->
</bean>
阅读全文 »

Spring 配置 Bean 全指南:从 XML 到注解的完整实践

Spring 配置 Bean 的核心目标是将 Bean 的创建、依赖管理交给 IOC 容器,通过 XML 或注解定义 Bean 的元数据(如类名、依赖、生命周期),最终由容器统一实例化并装配。从 “XML 配置” 到 “注解配置”,系统拆解 Bean 的配置方式、依赖注入逻辑、自动装配规则及歧义性处理,同时对比两种配置方式的优缺点与最佳实践。

XML 配置 Bean:传统且灵活的配置方式

XML 是 Spring 早期最主流的 Bean 配置方式,支持复杂的 Bean 定义(如工厂 Bean、集合属性),适合需要明确配置流程的场景。其核心是通过 <bean> 标签定义 Bean,配合 <property>/<constructor-arg> 注入依赖。

1. 基础 Bean 配置:构造器与 Setter 注入

Spring 实例化 Bean 主要依赖构造器(默认无参构造器),依赖注入(DI)分为 Setter 注入(属性注入)和 构造器注入,分别对应不同的使用场景。

(1)Setter 注入(最常用)

核心原理:Spring 先通过无参构造器实例化 Bean,再调用属性的 setter 方法注入依赖。
关键要求:Bean 类必须提供无参构造器(若未显式定义任何构造器,JVM 会默认生成;若显式定义有参构造器,需手动添加无参构造器)。

1.1 简单类型注入(value 属性)

注入基本类型(String、int、double 等)或字符串,使用 value 属性:

<!-- 配置 HelloWorld Bean,Setter 注入 name 属性 -->
<bean id="helloWorld" class="com.zhanghe.study.spring4.beans.helloworld.HelloWorld">
    <!-- name:对应 setName() 方法(去掉 set 后首字母小写,与成员变量名无关) -->
    <!-- value:注入简单类型值 -->
    <property name="name" value="Spring Hello"/>
</bean>

对应的 Java 类:

阅读全文 »

Spring 容器深度解析:从 BeanFactory 到 ApplicationContext 的体系与实践

Spring 容器是 IOC(控制反转)思想的具体实现,核心职责是管理 Bean 的生命周期(创建、装配、销毁)与依赖关系,是 Spring 框架的 “心脏”。Spring 提供了两类核心容器:BeanFactory(基础容器)和 ApplicationContext(高级容器),二者在功能、初始化策略和适用场景上存在显著差异。从 “容器体系→核心实现→关键区别→Bean 定义元数据” 四个维度,彻底拆解 Spring 容器的工作机制。

Spring 容器体系总览

Spring 容器基于 “分层设计”,从基础到高级形成完整体系,核心接口与实现类的关系如下:

spring容器

核心设计思路:BeanFactory 定义基础规范,ApplicationContext 在其之上扩展高级功能,满足不同场景需求(轻量级 vs 企业级)。

基础容器:BeanFactory 详解

BeanFactory 是 Spring 容器的顶层接口,定义了 IOC 容器的最小功能集 ——“获取 Bean、判断 Bean 状态”,是 Spring 框架内部使用的基础容器(面向框架基础设施)。

1. BeanFactory 核心接口与方法

public interface BeanFactory {
    // 关键常量:区分 FactoryBean 本身与它生成的对象(前缀 "&")
    String FACTORY_BEAN_PREFIX = "&";

    // 1. 获取 Bean(核心方法,支持按名称、类型、带参数构造)
    Object getBean(String name) throws BeansException; // 按名称获取(返回 Object,需强转)
    <T> T getBean(String name, Class<T> requiredType) throws BeansException; // 按名称+类型(无需强转)
    Object getBean(String name, Object... args) throws BeansException; // 带构造参数(创建原型 Bean 时用)
    <T> T getBean(Class<T> requiredType) throws BeansException; // 按类型获取(推荐,更类型安全)
    <T> T getBean(Class<T> requiredType, Object... args) throws BeansException; // 按类型+构造参数

    // 2. 判断 Bean 状态
    boolean containsBean(String name); // 容器中是否存在该名称的 Bean
    boolean isSingleton(String name) throws NoSuchBeanDefinitionException; // 是否为单例(默认)
    boolean isPrototype(String name) throws NoSuchBeanDefinitionException; // 是否为原型(每次 getBean 新建)
    boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException; // Bean 类型是否匹配
    Class<?> getType(String name) throws NoSuchBeanDefinitionException; // 获取 Bean 的类型
    String[] getAliases(String name); // 获取 Bean 的别名(一个 Bean 可多个别名)
}
关键方法解析:
  • FACTORY_BEAN_PREFIX = "&":特殊前缀,用于获取FactoryBean本身(而非其生成的对象)。例如:
    • getBean("userFactory"):获取 userFactory 这个 FactoryBean 生成的 User 对象;
    • getBean("&userFactory"):获取 userFactory 这个 FactoryBean 实例本身。
  • getBean 重载:支持多种获取方式,按类型获取(getBean(Class<T>))是最常用的,避免强转,更安全。
  • 单例 / 原型判断isSingletonisPrototype 对应 Bean 的 scope 配置(默认单例)。

2. BeanFactory 的核心子类

BeanFactory 接口本身不实现具体逻辑,其功能通过三个核心子类扩展:

阅读全文 »
0%