MySQL笔记·第2篇:MySQL外键——阿里巴巴为什么禁止使用?外键的坑与替代方案
一、外键是什么? 简单说,外键就是用来保证“两张表的数据能对上”。比如订单表的user_id必须指向用户表里存在的id。 1FOREIGN KEY (user_id) REFERENCES user(id) 加了外键,数据库会自动帮你检查:插入订单时,用户必须存在;删除用户时,要么拒绝,要么连带删订单。 听起来很完美,对吧?那为什么阿里巴巴开发手册明确写着“不得使用外键”?这篇文章讲清楚外键的坑和替代方案 二、为什么不推荐用外键? 外键像个负责任的保安,每次有人进出都查证件——安全是安全了,但门口排起了长队。 1. 性能损耗 每次插入、更新、删除订单,数据库都要去user表查一下这个user_id存不存在。这条select语句看着简单,但在高并发下,数据库累死。 一个订单操作变成:插入订单 + 查询用户。数据库要多干一份活。 2. 分库分表不友好 外键只能在一个数据库实例内生效。 业务大到一定程度,user表在一台机器,orders表在另一台机器。外键直接废了,代码还得大改——把所有数据完整性检查从数据库搬到代码里。 与其到时候哭着改代码,不如一开始就别用外键。 3. 耦合太紧 ...
MySQL笔记·第4篇:多表查询详解——内连接、左连接、自连接一篇搞定
一、多表查询是什么?简单来说,在实际的项目管理中,数据库的查询不仅仅是查询一张表的数据,是两张或两张以上的表,这时候是要用到多表查询。 我们在这建立两张表,一张是学生表,记录学生的学号和姓名,一张是成绩表,记录学生的成绩。接下来用这两张表为例,讲解多表查询。 1234567891011121314-- 学生表CREATE TABLE student ( id INT PRIMARY KEY, name VARCHAR(50));INSERT INTO student VALUES (1, '张三'), (2, '李四'), (3, '王五');-- 成绩表CREATE TABLE score ( id INT PRIMARY KEY, student_id INT, score INT);INSERT INTO score VALUES (1, 1, 90), (2, 1, 85), (3, 2, 78); 用表格表示如下: student表 score表 id name ...
Spring Boot 从零入门:请求响应、三层架构与 IOC、DI 实践总结
Spring Boot 从零入门:请求响应、三层架构与 IOC/DI 实践总结 1. 项目搭建与第一个接口使用 IDEA 的 Spring Initializr 创建项目,依赖仅选择 Spring Web。启动类 HttpStuApplication 自动生成。在 controller 包下创建 HelloController: 1234567@RestControllerpublic class HelloController { @RequestMapping("/hello") public String sayHello() { return "Hello, 请求响应学习开始!"; }} 运行后浏览器访问 http://localhost:8080/hello,输出文本 —— 标志着环境验证通过。 2. 请求响应:参数接收全解析2.1 哪些参数必须掌握? 优先级 参数类型 注解 使用频率 🔥 必须掌握 简单参数 @RequestPara...
搞懂Spring Boot登录认证:从UUID到JWT,一次完整的架构推演
从UUID到JWT再到Filter/Interceptor:Spring Boot登录认证进阶之路这篇文章要带你从零实现一个Spring Boot登录接口,并一步步将它从“临时UUID令牌”演变成无状态的JWT,再通过Filter → Interceptor → 统一异常处理,最终得到一个规范、可维护的认证架构。我们不依赖前端,只使用IDEA内置的HTTP Client做所有测试。所有代码都会给出,你可以复制即用。 1. 基础登录:模拟数据 + UUID令牌我们先从最简单的入手:接收用户名密码,验证后返回一个临时令牌。所有用户数据先用HashMap硬编码在内存里,令牌就用UUID随机生成。 1.1 项目结构12345678910111213141516171819src/main/java/com/example/demo├── DemoApplication.java // 启动类├── config│ └── WebConfig.java // 配置拦截器、跨域等├── con...
Java基础·第1篇:面向对象 vs 面向过程——Java和C语言到底有什么区别?
编程语言的分类面向对象(Java)和面向过程(C语言)是两种主流编程范式。 它们到底有什么区别?本文用锤子和咖啡两个例子,讲清楚编程范式的核心思想。 1、面向过程的编程语言面向对象的编程范式其实上是将我们需要解决的问题拆解,变成一个一个的步骤,先做什么,后做什么。典型的面向过程的编程语言是我们编程学习的启蒙语言————C语言,我们在学习的过程中大部分时候都是在编写函数,各种各样的函数,在主程序中不断的根据需求依次的去调用函数,将需要处理的数据给函数,函数返回一个处理后的结果。这个过程就像在制造工具来解决实际问题,比如制造一把锤子,你需要先砍树造木柄,然后挖铁矿冶炼铁,紧接着锻造锤头,最后组装,那么你就拥有了一把锤子,你可以拿他钉钉子或是其他的需要。 以下面的一个简单的C语言程序为例:在程序运行过程中,我们将需要计算的数据a和b,传给做加法运算的函数sum(),函数sum()将计算后的结果赋值给变量sum,然后通过printf()函数输出出来,至此程序结束。 12345678910#include<stdio.h>int main(){ int a=1;...
Java基础·第2篇:数据类型(基本+引用)和输入输出(Scanner)
引入Java数据类型分为基本数据类型和引用数据类型。本文整理了8种基本数据类型的表格,用“藏宝图”讲清引用数据类型。后半部分介绍Java的输入输出:System.out和Scanner的用法。 Java的数据类型一、基本数据类型为了让你一目了然,我将这8种基本数据类型整理成了如下表格,涵盖了它们的存储大小、取值范围及核心特性。 数据类型 关键字 占用空间 取值范围 默认值 核心特性与注意事项 字节型 byte 1字节 -128 ~ 127 0 节省内存,常用于文件IO或网络传输。 短整型 short 2字节 -32,768 ~ 32,767 0 较少直接使用,用于特定内存优化场景。 整型 int 4字节 约±21亿 0 最常用的整数类型,默认整数字面量。 长整型 long 8字节 约±922亿亿 0L 存储超大整数,赋值时数值后需加L。 单精度浮点 float 4字节 约±3.4E38 0.0f 精度较低(6-7位有效数字),赋值需加F。 双精度浮点 double 8字节 约±1.8E308 0.0d 最常用的小数类型,默认浮点字面量。 字符型...
Java基础·第3篇:Java封装——为什么要把数据藏起来?
前言在我们学习面向过程的编程语言,比如说C语言时,一定会出现下面的情况:假设你定义了一个全局变量 int balance = 1000;(余额)。在C语言里,程序中任何一个函数都可以直接访问并修改这个 balance。 12345678910// 面向过程风格(C语言)int balance = 1000;void buyCoffee() { balance -= 20; //直接修改}void hackFunction() { balance = 0; // 任何函数都能随意篡改,没有任何阻拦!} 因为没有数据的保护机制,数据对所有函数都是公开的,任何地方写错了一行代码,都可能导致数据被意外修改。如果在编写程序的时候,意外的写错了数据,造成bug出现,就要在几百行代码里找问题,很麻烦。 而在面向对象的编程语言中,可以对数据进行封装来实现对数据的保护。 为什么需要封装?从数据的“裸奔”说起在接触封装之前,我们定义的类通常长这样: 12345public class Student { public St...
Java基础·第5篇:Java多态——不用再写三个重载方法了!
引入 假设你要写一个宠物管理系统。系统里有一个“投喂”功能: 狗:吃狗粮 猫:吃猫粮 兔子:吃兔粮 如果没有多态,你可能需要这样写: 123public void feed(Dog d) { d.eat(); }public void feed(Cat c) { c.eat(); }public void feed(Rabbit r) { r.eat(); } 三种动物,三个方法。那如果是十种动物呢?写十个长得一模一样的方法? 多态要解决的问题就是:用一个方法,接收所有动物。 1public void feed(Animal a) { a.eat(); } 不管你传进来的是狗、猫还是兔子,只要它是Animal,就能调eat()。至于具体怎么吃,每个动物自己说了算。 这就是多态——同一个方法调用,表现出不同的行为。 下面我们来看多态在Java中怎么实现。 多态的定义与前提1234567891011121314151617181920212223242526272829303132333...
MyBatis 入门系列(二):增删改查 + 批量删除完整总结(含 @Param 和 foreach)
MyBatis 增删改查 + 批量删除完整总结(含 @Param 和 foreach)学习完Mybatis的基本操作流程之后,因为Mybatis本身就是用Java操作数据库的一项技术,我们躲不掉的要学习在Mybatis中怎么对数据库进行增删改查。接下来直接上实战: 一、Mapper 接口(UserMapper.java)1234567891011121314151617181920212223242526package org.example.mapper;import org.example.pojo.User;import org.apache.ibatis.annotations.Param;import java.util.List;public interface UserMapper { // 查询所有 List<User> findAll(); // 根据 id 查询单个 User findById(Integer id); // 新增(返回影响行数,并自动填充自增 id) int insert(User u...














