Java 后端开发复习指南

1. Java 基础语法

1.1 数据类型和变量

Java 是强类型语言,分为基本数据类型和引用数据类型。

java 复制代码
// 基本数据类型
public class DataTypeExample {
    public static void main(String[] args) {
        // 整型
        byte b = 127;           // 8位,-128到127
        short s = 32767;        // 16位,-32768到32767
        int i = 2147483647;     // 32位,约21亿
        long l = 9223372036854775807L; // 64位,L后缀
        
        // 浮点型
        float f = 3.14f;        // 32位,f后缀
        double d = 3.14159;     // 64位,默认浮点类型
        
        // 字符型
        char c = 'A';           // 16位Unicode字符
        
        // 布尔型
        boolean flag = true;    // true或false
        
        System.out.println("基本数据类型示例:" + i + ", " + d + ", " + flag);
    }
}

1.2 运算符

java 复制代码
public class OperatorExample {
    public static void main(String[] args) {
        int a = 10, b = 5;
        
        // 算术运算符
        System.out.println("a + b = " + (a + b));
        System.out.println("a - b = " + (a - b));
        System.out.println("a * b = " + (a * b));
        System.out.println("a / b = " + (a / b));
        System.out.println("a % b = " + (a % b));
        
        // 比较运算符
        System.out.println("a > b = " + (a > b));
        System.out.println("a == b = " + (a == b));
        
        // 逻辑运算符
        boolean x = true, y = false;
        System.out.println("x && y = " + (x && y));
        System.out.println("x || y = " + (x || y));
        System.out.println("!x = " + (!x));
        
        // 三元运算符
        int max = (a > b) ? a : b;
        System.out.println("max = " + max);
    }
}

1.3 控制流程

java 复制代码
public class ControlFlowExample {
    public static void main(String[] args) {
        int score = 85;
        
        // if-else 语句
        if (score >= 90) {
            System.out.println("优秀");
        } else if (score >= 80) {
            System.out.println("良好");
        } else if (score >= 60) {
            System.out.println("及格");
        } else {
            System.out.println("不及格");
        }
        
        // switch 语句
        switch (score / 10) {
            case 10:
            case 9:
                System.out.println("A等级");
                break;
            case 8:
                System.out.println("B等级");
                break;
            case 7:
                System.out.println("C等级");
                break;
            default:
                System.out.println("D等级");
        }
        
        // for 循环
        for (int i = 1; i <= 5; i++) {
            System.out.println("循环第" + i + "次");
        }
        
        // while 循环
        int j = 1;
        while (j <= 3) {
            System.out.println("while循环第" + j + "次");
            j++;
        }
        
        // 增强for循环
        int[] numbers = {1, 2, 3, 4, 5};
        for (int num : numbers) {
            System.out.println("数组元素:" + num);
        }
    }
}

2. 面向对象编程

2.1 类和对象

java 复制代码
// 定义一个简单的类
public class Person {
    // 成员变量(属性)
    private String name;
    private int age;
    private String gender;
    
    // 构造方法
    public Person() {
        // 无参构造方法
    }
    
    public Person(String name, int age, String gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }
    
    // Getter和Setter方法
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    public int getAge() {
        return age;
    }
    
    public void setAge(int age) {
        if (age > 0 && age < 150) {
            this.age = age;
        } else {
            System.out.println("年龄不合法");
        }
    }
    
    public String getGender() {
        return gender;
    }
    
    public void setGender(String gender) {
        this.gender = gender;
    }
    
    // 成员方法
    public void introduce() {
        System.out.println("我是" + name + ",今年" + age + "岁,性别是" + gender);
    }
    
    // 重写toString方法
    @Override
    public String toString() {
        return "Person{name='" + name + "', age=" + age + ", gender='" + gender + "'}";
    }
}

// 测试类
class PersonTest {
    public static void main(String[] args) {
        // 创建对象
        Person person1 = new Person();
        person1.setName("张三");
        person1.setAge(25);
        person1.setGender("男");
        person1.introduce();
        
        Person person2 = new Person("李四", 30, "女");
        System.out.println(person2.toString());
    }
}

2.2 继承、封装、多态

java 复制代码
// 父类 - 动物
public class Animal {
    protected String name;
    protected int age;
    
    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    // 封装 - Getter和Setter
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public int getAge() { return age; }
    public void setAge(int age) { this.age = age; }
    
	// 普通方法,同样可以被子类重写
	public void eat() {
	    System.out.println(name + "正在吃东西");
	}
	
	// 这个方法将被子类重写,以演示多态
	public void makeSound() {
	    System.out.println("动物发出声音");
	}
}

// 子类 - 狗
class Dog extends Animal {
    private String breed; // 品种
    
    public Dog(String name, int age, String breed) {
        super(name, age); // 调用父类构造方法
        this.breed = breed;
    }
    
    // 重写父类方法(多态体现)
    @Override
    public void makeSound() {
        System.out.println(name + "汪汪叫");
    }
    
    // 子类特有方法
    public void wagTail() {
        System.out.println(name + "摇尾巴");
    }
    
    public String getBreed() { return breed; }
    public void setBreed(String breed) { this.breed = breed; }
}

// 子类 - 猫
class Cat extends Animal {
    private boolean isIndoor; // 是否室内猫
    
    public Cat(String name, int age, boolean isIndoor) {
        super(name, age);
        this.isIndoor = isIndoor;
    }
    
    // 重写父类方法
    @Override
    public void makeSound() {
        System.out.println(name + "喵喵叫");
    }
    
    public boolean isIndoor() { return isIndoor; }
    public void setIndoor(boolean indoor) { isIndoor = indoor; }
}

// 测试多态
class PolymorphismTest {
    public static void main(String[] args) {
        // 多态 - 父类引用指向子类对象
        Animal animal1 = new Dog("旺财", 3, "金毛");
        Animal animal2 = new Cat("咪咪", 2, true);
        
        // 调用重写的方法 - 体现多态
        animal1.makeSound(); // 输出:旺财汪汪叫
        animal2.makeSound(); // 输出:咪咪喵喵叫
        
        // 向下转型(需要类型检查)
        if (animal1 instanceof Dog) {
            Dog dog = (Dog) animal1;
            dog.wagTail(); // 调用子类特有方法
        }
    }
}

2.3 抽象类和接口

java 复制代码
// 抽象类 - 形状
public abstract class Shape {
    protected String color;
    
    public Shape(String color) {
        this.color = color;
    }
    
    // 具体方法
    public String getColor() {
        return color;
    }
    
    public void setColor(String color) {
        this.color = color;
    }
    
    // 抽象方法 - 子类必须实现
    public abstract double getArea();
    public abstract double getPerimeter();
    
    // 可以有具体方法
    public void displayInfo() {
        System.out.println("这是一个" + color + "色的形状");
    }
}

// 具体类 - 矩形
class Rectangle extends Shape {
    private double width;
    private double height;
    
    public Rectangle(String color, double width, double height) {
        super(color);
        this.width = width;
        this.height = height;
    }
    
    @Override
    public double getArea() {
        return width * height;
    }
    
    @Override
    public double getPerimeter() {
        return 2 * (width + height);
    }
    
    public double getWidth() { return width; }
    public void setWidth(double width) { this.width = width; }
    public double getHeight() { return height; }
    public void setHeight(double height) { this.height = height; }
}

// 接口 - 可移动的
interface Movable {
    void move(int x, int y);
    default void showPosition() { // Java 8 默认方法
        System.out.println("当前位置:(" + getX() + ", " + getY() + ")");
    }
    
    // 抽象方法
    int getX();
    int getY();
}

// 接口 - 可绘制的
interface Drawable {
    void draw();
    static void printSupportedShapes() { // Java 8 静态方法
        System.out.println("支持绘制的形状:圆形、矩形、三角形");
    }
}

// 实现多个接口的类
class MovableRectangle extends Rectangle implements Movable, Drawable {
    private int x, y; // 位置坐标
    
    public MovableRectangle(String color, double width, double height, int x, int y) {
        super(color, width, height);
        this.x = x;
        this.y = y;
    }
    
    @Override
    public void move(int x, int y) {
        this.x = x;
        this.y = y;
        System.out.println("移动到位置:(" + x + ", " + y + ")");
    }
    
    @Override
    public void draw() {
        System.out.println("绘制一个" + getColor() + "色的矩形,宽:" + 
                          getWidth() + ",高:" + getHeight());
    }
    
    @Override
    public int getX() { return x; }
    
    @Override
    public int getY() { return y; }
}

// 测试抽象类和接口
class AbstractInterfaceTest {
    public static void main(String[] args) {
        // 使用抽象类
        Rectangle rect = new Rectangle("红色", 5.0, 3.0);
        System.out.println("矩形面积:" + rect.getArea());
        System.out.println("矩形周长:" + rect.getPerimeter());
        
        // 使用接口
        MovableRectangle movableRect = new MovableRectangle("蓝色", 4.0, 6.0, 0, 0);
        movableRect.draw();
        movableRect.move(10, 20);
        movableRect.showPosition();
        
        // 调用接口静态方法
        Drawable.printSupportedShapes();
    }
}

3. 集合框架

3.1 List 集合

java 复制代码
import java.util.*;

public class ListExample {
    public static void main(String[] args) {
        // ArrayList - 动态数组
        List<String> arrayList = new ArrayList<>();
        arrayList.add("苹果");
        arrayList.add("香蕉");
        arrayList.add("橙子");
        arrayList.add(1, "葡萄"); // 在指定位置插入
        
        System.out.println("ArrayList: " + arrayList);
        System.out.println("第2个元素: " + arrayList.get(1));
        System.out.println("元素个数: " + arrayList.size());
        
        // LinkedList - 双向链表
        LinkedList<String> linkedList = new LinkedList<>();
        linkedList.add("第一个");
        linkedList.add("第二个");
        linkedList.addFirst("开头");
        linkedList.addLast("结尾");
        
        System.out.println("LinkedList: " + linkedList);
        System.out.println("第一个元素: " + linkedList.getFirst());
        System.out.println("最后一个元素: " + linkedList.getLast());
        
        // 遍历方式
        System.out.println("=== 遍历 ArrayList ===");
        // 1. 增强for循环
        for (String fruit : arrayList) {
            System.out.println(fruit);
        }
        
        // 2. 迭代器
        Iterator<String> iterator = arrayList.iterator();
        while (iterator.hasNext()) {
            System.out.println("迭代器: " + iterator.next());
        }
        
        // 3. Lambda表达式 (Java 8+)
        arrayList.forEach(System.out::println);
    }
}

3.2 Map 集合

java 复制代码
import java.util.*;

public class MapExample {
    public static void main(String[] args) {
        // HashMap - 哈希映射
        Map<String, Integer> hashMap = new HashMap<>();
        hashMap.put("张三", 25);
        hashMap.put("李四", 30);
        hashMap.put("王五", 28);
        hashMap.put("张三", 26); // 会覆盖原来的值
        
        System.out.println("HashMap: " + hashMap);
        System.out.println("张三的年龄: " + hashMap.get("张三"));
        System.out.println("是否包含键'李四': " + hashMap.containsKey("李四"));
        System.out.println("是否包含值30: " + hashMap.containsValue(30));
        
        // 遍历Map
        System.out.println("=== 遍历 HashMap ===");
        // 1. 遍历键值对
        for (Map.Entry<String, Integer> entry : hashMap.entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }
        
        // 2. 遍历键
        for (String key : hashMap.keySet()) {
            System.out.println(key + " -> " + hashMap.get(key));
        }
        
        // 3. 遍历值
        for (Integer value : hashMap.values()) {
            System.out.println("年龄: " + value);
        }
        
        // LinkedHashMap - 保持插入顺序
        Map<String, Integer> linkedHashMap = new LinkedHashMap<>();
        linkedHashMap.put("第一", 1);
        linkedHashMap.put("第二", 2);
        linkedHashMap.put("第三", 3);
        System.out.println("LinkedHashMap: " + linkedHashMap);
        
        // TreeMap - 按键排序
        Map<String, Integer> treeMap = new TreeMap<>();
        treeMap.put("banana", 2);
        treeMap.put("apple", 1);
        treeMap.put("cherry", 3);
        System.out.println("TreeMap: " + treeMap);
    }
}

3.3 Set 集合

java 复制代码
import java.util.*;

public class SetExample {
    public static void main(String[] args) {
        // HashSet - 无序,不允许重复
        Set<String> hashSet = new HashSet<>();
        hashSet.add("Java");
        hashSet.add("Python");
        hashSet.add("C++");
        hashSet.add("Java"); // 重复元素不会添加
        hashSet.add("JavaScript");
        
        System.out.println("HashSet: " + hashSet);
        System.out.println("元素个数: " + hashSet.size());
        System.out.println("是否包含'Python': " + hashSet.contains("Python"));
        
        // LinkedHashSet - 保持插入顺序
        Set<String> linkedHashSet = new LinkedHashSet<>();
        linkedHashSet.add("第一个");
        linkedHashSet.add("第二个");
        linkedHashSet.add("第三个");
        System.out.println("LinkedHashSet: " + linkedHashSet);
        
        // TreeSet - 排序Set
        Set<Integer> treeSet = new TreeSet<>();
        treeSet.add(5);
        treeSet.add(2);
        treeSet.add(8);
        treeSet.add(1);
        System.out.println("TreeSet: " + treeSet);
        
        // Set的常用操作
        Set<Integer> set1 = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5));
        Set<Integer> set2 = new HashSet<>(Arrays.asList(4, 5, 6, 7, 8));
        
        // 并集
        Set<Integer> union = new HashSet<>(set1);
        union.addAll(set2);
        System.out.println("并集: " + union);
        
        // 交集
        Set<Integer> intersection = new HashSet<>(set1);
        intersection.retainAll(set2);
        System.out.println("交集: " + intersection);
        
        // 差集
        Set<Integer> difference = new HashSet<>(set1);
        difference.removeAll(set2);
        System.out.println("差集: " + difference);
    }
}

4. 异常处理

4.1 异常基础

java 复制代码
public class ExceptionExample {
    public static void main(String[] args) {
        // try-catch-finally 基本用法
        try {
            int result = 10 / 0; // 会抛出 ArithmeticException
            System.out.println("结果: " + result);
        } catch (ArithmeticException e) {
            System.out.println("捕获到算术异常: " + e.getMessage());
        } finally {
            System.out.println("finally块总是执行");
        }
        
        // 多重catch
        try {
            String str = null;
            System.out.println(str.length()); // 会抛出 NullPointerException
            int[] arr = new int[3];
            System.out.println(arr[5]); // 会抛出 ArrayIndexOutOfBoundsException
        } catch (NullPointerException e) {
            System.out.println("空指针异常: " + e.getMessage());
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("数组越界异常: " + e.getMessage());
        } catch (Exception e) {
            // 捕获所有其他异常
            System.out.println("其他异常: " + e.getMessage());
        }
        
        // try-with-resources (Java 7+)
        try (Scanner scanner = new Scanner(System.in)) {
            System.out.println("请输入一个数字:");
            // int num = scanner.nextInt();
            // System.out.println("输入的数字是: " + num);
        } catch (Exception e) {
            System.out.println("输入异常: " + e.getMessage());
        }
        // Scanner会自动关闭
        
        // 自定义异常测试
        try {
            validateAge(-5);
        } catch (InvalidAgeException e) {
            System.out.println("自定义异常: " + e.getMessage());
        }
    }
    
    public static void validateAge(int age) throws InvalidAgeException {
        if (age < 0) {
            throw new InvalidAgeException("年龄不能为负数: " + age);
        }
        if (age > 150) {
            throw new InvalidAgeException("年龄不能超过150: " + age);
        }
        System.out.println("年龄合法: " + age);
    }
}

// 自定义异常类
class InvalidAgeException extends Exception {
    public InvalidAgeException(String message) {
        super(message);
    }
}

4.2 异常处理最佳实践

java 复制代码
public class ExceptionBestPractice {
    
    // 1. 不要忽略异常
    public void badPractice() {
        try {
            // 一些可能出错的代码
            int result = 10 / 0;
        } catch (Exception e) {
            // 错误做法:什么都不做
        }
    }
    
    // 2. 正确做法:记录异常或重新抛出
    public void goodPractice() throws Exception {
        try {
            // 一些可能出错的代码
            int result = 10 / 0;
        } catch (ArithmeticException e) {
            // 记录日志
            System.err.println("发生算术异常: " + e.getMessage());
            // 重新抛出或抛出自定义异常
            throw new Exception("计算过程中发生错误", e);
        }
    }
    
    // 3. 异常链
    public void exceptionChaining() {
        try {
            // 模拟数据库操作
            performDatabaseOperation();
        } catch (DatabaseException e) {
            // 包装异常并重新抛出
            throw new ServiceException("服务调用失败", e);
        }
    }
    
    private void performDatabaseOperation() throws DatabaseException {
        throw new DatabaseException("数据库连接失败");
    }
}

// 自定义异常类层次
class ServiceException extends RuntimeException {
    public ServiceException(String message) {
        super(message);
    }
    
    public ServiceException(String message, Throwable cause) {
        super(message, cause);
    }
}

class DatabaseException extends Exception {
    public DatabaseException(String message) {
        super(message);
    }
}

5. 多线程

5.1 线程基础

java 复制代码
// 1. 继承 Thread 类
class MyThread extends Thread {
    private String threadName;
    
    public MyThread(String name) {
        this.threadName = name;
    }
    
    @Override
    public void run() {
        for (int i = 1; i <= 5; i++) {
            System.out.println(threadName + " 执行第 " + i + " 次");
            try {
                Thread.sleep(1000); // 暂停1秒
            } catch (InterruptedException e) {
                System.out.println(threadName + " 被中断");
                return;
            }
        }
        System.out.println(threadName + " 执行完毕");
    }
}

// 2. 实现 Runnable 接口
class MyRunnable implements Runnable {
    private String taskName;
    
    public MyRunnable(String name) {
        this.taskName = name;
    }
    
    @Override
    public void run() {
        for (int i = 1; i <= 3; i++) {
            System.out.println(taskName + " 处理任务 " + i);
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                return;
            }
        }
        System.out.println(taskName + " 任务完成");
    }
}

// 3. 使用 Lambda 表达式
public class ThreadExample {
    public static void main(String[] args) {
        // 方式1:继承Thread类
        MyThread thread1 = new MyThread("线程1");
        MyThread thread2 = new MyThread("线程2");
        
        thread1.start();
        thread2.start();
        
        // 方式2:实现Runnable接口
        Thread thread3 = new Thread(new MyRunnable("任务1"));
        Thread thread4 = new Thread(new MyRunnable("任务2"));
        
        thread3.start();
        thread4.start();
        
        // 方式3:Lambda表达式
        Thread thread5 = new Thread(() -> {
            for (int i = 1; i <= 3; i++) {
                System.out.println("Lambda线程执行第 " + i + " 次");
                try {
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    return;
                }
            }
        });
        
        thread5.start();
        
        // 等待所有线程执行完毕
        try {
            thread1.join();
            thread2.join();
            thread3.join();
            thread4.join();
            thread5.join();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        
        System.out.println("所有线程执行完毕");
    }
}

5.2 线程同步

java 复制代码
// 线程安全的计数器
class SafeCounter {
    private int count = 0;
    
    // 方法同步 - synchronized 关键字
    public synchronized void increment() {
        count++;
    }
    
    public synchronized int getCount() {
        return count;
    }
    
    // 代码块同步
    public void decrement() {
        synchronized (this) {
            count--;
        }
    }
}

// 生产者消费者示例
class ProducerConsumerExample {
    private static final int BUFFER_SIZE = 10;
    private final int[] buffer = new int[BUFFER_SIZE];
    private int count = 0;
    private int in = 0;  // 生产位置
    private int out = 0; // 消费位置
    
    // 生产者
    class Producer implements Runnable {
        @Override
        public void run() {
            for (int i = 1; i <= 20; i++) {
                try {
                    produce(i);
                    Thread.sleep(100); // 模拟生产时间
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    return;
                }
            }
        }
        
        private void produce(int item) throws InterruptedException {
            synchronized (this) {
                // 等待缓冲区有空间
                while (count == BUFFER_SIZE) {
                    wait();
                }
                
                buffer[in] = item;
                in = (in + 1) % BUFFER_SIZE;
                count++;
                
                System.out.println("生产: " + item + ", 缓冲区大小: " + count);
                notifyAll(); // 通知等待的消费者
            }
        }
    }
    
    // 消费者
    class Consumer implements Runnable {
        @Override
        public void run() {
            for (int i = 0; i < 20; i++) {
                try {
                    int item = consume();
                    System.out.println("消费: " + item);
                    Thread.sleep(150); // 模拟消费时间
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    return;
                }
            }
        }
        
        private int consume() throws InterruptedException {
            synchronized (this) {
                // 等待缓冲区有数据
                while (count == 0) {
                    wait();
                }
                
                int item = buffer[out];
                out = (out + 1) % BUFFER_SIZE;
                count--;
                
                notifyAll(); // 通知等待的生产者
                return item;
            }
        }
    }
    
    public static void main(String[] args) {
        ProducerConsumerExample example = new ProducerConsumerExample();
        
        Thread producerThread = new Thread(example.new Producer());
        Thread consumerThread = new Thread(example.new Consumer());
        
        producerThread.start();
        consumerThread.start();
        
        try {
            producerThread.join();
            consumerThread.join();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        
        System.out.println("生产消费完成");
    }
}

5.3 线程池

java 复制代码
import java.util.concurrent.*;

public class ThreadPoolExample {
    public static void main(String[] args) {
        // 1. 创建固定大小的线程池
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
        
        // 提交任务
        for (int i = 1; i <= 5; i++) {
            final int taskId = i;
            fixedThreadPool.submit(() -> {
                System.out.println("任务 " + taskId + " 由线程 " + 
                                 Thread.currentThread().getName() + " 执行");
                try {
                    Thread.sleep(2000); // 模拟任务执行
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
                System.out.println("任务 " + taskId + " 执行完毕");
            });
        }
        
        // 2. 创建缓存线程池
        ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
        
        // 提交带返回值的任务
        Future<String> future = cachedThreadPool.submit(() -> {
            Thread.sleep(1000);
            return "异步任务结果";
        });
        
        try {
            // 获取异步结果
            String result = future.get(3, TimeUnit.SECONDS);
            System.out.println("异步结果: " + result);
        } catch (Exception e) {
            System.out.println("获取结果异常: " + e.getMessage());
        }
        
        // 3. 创建单线程执行器
        ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
        singleThreadExecutor.submit(() -> {
            System.out.println("单线程任务执行");
        });
        
        // 4. 自定义线程池
        ThreadPoolExecutor customThreadPool = new ThreadPoolExecutor(
            2,                          // 核心线程数
            4,                          // 最大线程数
            60L,                        // 空闲线程存活时间
            TimeUnit.SECONDS,           // 时间单位
            new LinkedBlockingQueue<>(100), // 工作队列
            new ThreadFactory() {       // 线程工厂
                private int counter = 0;
                @Override
                public Thread newThread(Runnable r) {
                    return new Thread(r, "CustomThread-" + counter++);
                }
            },
            new ThreadPoolExecutor.CallerRunsPolicy() // 拒绝策略
        );
        
        // 提交任务到自定义线程池
        for (int i = 1; i <= 3; i++) {
            final int taskId = i;
            customThreadPool.submit(() -> {
                System.out.println("自定义线程池任务 " + taskId + 
                                 " 由 " + Thread.currentThread().getName() + " 执行");
            });
        }
        
        // 关闭线程池
        fixedThreadPool.shutdown();
        cachedThreadPool.shutdown();
        singleThreadExecutor.shutdown();
        customThreadPool.shutdown();
        
        try {
            // 等待所有任务完成
            if (!fixedThreadPool.awaitTermination(10, TimeUnit.SECONDS)) {
                fixedThreadPool.shutdownNow();
            }
        } catch (InterruptedException e) {
            fixedThreadPool.shutdownNow();
            Thread.currentThread().interrupt();
        }
        
        System.out.println("所有线程池已关闭");
    }
}

6. IO/NIO

6.1 传统 IO

java 复制代码
import java.io.*;
import java.util.Scanner;

public class IOExample {
    public static void main(String[] args) {
        // 1. 文件读写 - 字节流
        fileByteIO();
        
        // 2. 文件读写 - 字符流
        fileCharacterIO();
        
        // 3. 缓冲流
        bufferedIO();
        
        // 4. 对象序列化
        objectSerialization();
    }
    
    // 字节流操作
    public static void fileByteIO() {
        String fileName = "test.txt";
        
        // 写入文件
        try (FileOutputStream fos = new FileOutputStream(fileName)) {
            String content = "Hello, Java IO!";
            fos.write(content.getBytes());
            System.out.println("字节流写入完成");
        } catch (IOException e) {
            System.err.println("写入文件异常: " + e.getMessage());
        }
        
        // 读取文件
        try (FileInputStream fis = new FileInputStream(fileName)) {
            byte[] buffer = new byte[1024];
            int bytesRead = fis.read(buffer);
            String content = new String(buffer, 0, bytesRead);
            System.out.println("字节流读取内容: " + content);
        } catch (IOException e) {
            System.err.println("读取文件异常: " + e.getMessage());
        }
    }
    
    // 字符流操作
    public static void fileCharacterIO() {
        String fileName = "test_char.txt";
        
        // 写入文件
        try (FileWriter writer = new FileWriter(fileName)) {
            writer.write("你好,Java字符流!\n");
            writer.write("这是第二行内容。");
            System.out.println("字符流写入完成");
        } catch (IOException e) {
            System.err.println("字符流写入异常: " + e.getMessage());
        }
        
        // 读取文件
        try (FileReader reader = new FileReader(fileName);
             BufferedReader bufferedReader = new BufferedReader(reader)) {
            
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                System.out.println("读取行: " + line);
            }
        } catch (IOException e) {
            System.err.println("字符流读取异常: " + e.getMessage());
        }
    }
    
    // 缓冲流提高性能
    public static void bufferedIO() {
        String fileName = "buffered_test.txt";
        
        // 使用缓冲输出流
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(fileName))) {
            for (int i = 1; i <= 1000; i++) {
                writer.write("这是第 " + i + " 行数据\n");
            }
            writer.flush(); // 强制刷新缓冲区
            System.out.println("缓冲写入完成");
        } catch (IOException e) {
            System.err.println("缓冲写入异常: " + e.getMessage());
        }
        
        // 使用缓冲输入流
        try (BufferedReader reader = new BufferedReader(new FileReader(fileName))) {
            String line;
            int lineCount = 0;
            while ((line = reader.readLine()) != null && lineCount < 5) {
                System.out.println("读取: " + line);
                lineCount++;
            }
        } catch (IOException e) {
            System.err.println("缓冲读取异常: " + e.getMessage());
        }
    }
    
    // 对象序列化
    public static void objectSerialization() {
        String fileName = "person.ser";
        Person person = new Person("张三", 25, "男");
        
        // 序列化对象
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(fileName))) {
            oos.writeObject(person);
            System.out.println("对象序列化完成");
        } catch (IOException e) {
            System.err.println("序列化异常: " + e.getMessage());
        }
        
        // 反序列化对象
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(fileName))) {
            Person deserializedPerson = (Person) ois.readObject();
            System.out.println("反序列化对象: " + deserializedPerson);
        } catch (IOException | ClassNotFoundException e) {
            System.err.println("反序列化异常: " + e.getMessage());
        }
    }
}

// 可序列化的Person类
class Person implements Serializable {
    private static final long serialVersionUID = 1L;
    
    private String name;
    private int age;
    private String gender;
    
    public Person(String name, int age, String gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }
    
    @Override
    public String toString() {
        return "Person{name='" + name + "', age=" + age + ", gender='" + gender + "'}";
    }
}

6.2 NIO (New IO)

java 复制代码
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.*;
import java.nio.charset.StandardCharsets;

public class NIOExample {
    public static void main(String[] args) {
        // 1. Path 和 Files
        pathAndFilesExample();
        
        // 2. 文件通道操作
        fileChannelExample();
        
        // 3. 目录操作
        directoryExample();
    }
    
    // Path 和 Files 示例
    public static void pathAndFilesExample() {
        try {
            // 创建 Path 对象
            Path path = Paths.get("nio_test.txt");
            
            // 写入文件
            String content = "Hello, NIO!\n这是第二行内容。";
            Files.write(path, content.getBytes(StandardCharsets.UTF_8));
            System.out.println("NIO写入完成");
            
            // 读取文件
            byte[] bytes = Files.readAllBytes(path);
            String readContent = new String(bytes, StandardCharsets.UTF_8);
            System.out.println("NIO读取内容: " + readContent);
            
            // 按行读取
            System.out.println("按行读取:");
            Files.lines(path).forEach(System.out::println);
            
            // 检查文件属性
            if (Files.exists(path)) {
                System.out.println("文件大小: " + Files.size(path) + " 字节");
                System.out.println("是否为目录: " + Files.isDirectory(path));
            }
            
        } catch (IOException e) {
            System.err.println("NIO操作异常: " + e.getMessage());
        }
    }
    
    // 文件通道示例
    public static void fileChannelExample() {
        String fileName = "channel_test.txt";
        
        try {
            // 写入数据到文件
            Path path = Paths.get(fileName);
            try (FileChannel channel = FileChannel.open(path, 
                    StandardOpenOption.CREATE, 
                    StandardOpenOption.WRITE, 
                    StandardOpenOption.TRUNCATE_EXISTING)) {
                
                String data = "这是通过FileChannel写入的数据";
                ByteBuffer buffer = ByteBuffer.wrap(data.getBytes(StandardCharsets.UTF_8));
                channel.write(buffer);
                System.out.println("通过Channel写入完成");
            }
            
            // 从文件读取数据
            try (FileChannel channel = FileChannel.open(path, StandardOpenOption.READ)) {
                ByteBuffer buffer = ByteBuffer.allocate(1024);
                int bytesRead = channel.read(buffer);
                
                if (bytesRead > 0) {
                    buffer.flip(); // 切换到读模式
                    byte[] bytes = new byte[bytesRead];
                    buffer.get(bytes);
                    String content = new String(bytes, StandardCharsets.UTF_8);
                    System.out.println("通过Channel读取: " + content);
                }
            }
            
        } catch (IOException e) {
            System.err.println("Channel操作异常: " + e.getMessage());
        }
    }
    
    // 目录操作示例
    public static void directoryExample() {
        try {
            // 创建目录
            Path dirPath = Paths.get("test_directory");
            if (!Files.exists(dirPath)) {
                Files.createDirectory(dirPath);
                System.out.println("目录创建完成: " + dirPath);
            }
            
            // 在目录中创建文件
            Path filePath = dirPath.resolve("test_file.txt");
            Files.write(filePath, "测试文件内容".getBytes(StandardCharsets.UTF_8));
            
            // 遍历目录
            System.out.println("目录内容:");
            Files.list(dirPath).forEach(System.out::println);
            
            // 递归遍历目录
            System.out.println("递归目录内容:");
            Files.walk(dirPath, 2) // 最大深度为2
                 .forEach(System.out::println);
            
            // 删除文件和目录
            Files.deleteIfExists(filePath);
            System.out.println("删除文件: " + filePath);
            
        } catch (IOException e) {
            System.err.println("目录操作异常: " + e.getMessage());
        }
    }
}

7. 数据库操作

7.1 JDBC 基础

java 复制代码
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

// 用户实体类
class User {
    private int id;
    private String name;
    private String email;
    private int age;
    
    // 构造方法
    public User() {}
    
    public User(String name, String email, int age) {
        this.name = name;
        this.email = email;
        this.age = age;
    }
    
    public User(int id, String name, String email, int age) {
        this.id = id;
        this.name = name;
        this.email = email;
        this.age = age;
    }
    
    // Getter和Setter方法
    public int getId() { return id; }
    public void setId(int id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public String getEmail() { return email; }
    public void setEmail(String email) { this.email = email; }
    public int getAge() { return age; }
    public void setAge(int age) { this.age = age; }
    
    @Override
    public String toString() {
        return "User{id=" + id + ", name='" + name + "', email='" + email + "', age=" + age + "}";
    }
}

// 数据库连接工具类
class DatabaseUtil {
    private static final String URL = "jdbc:mysql://localhost:3306/testdb?useSSL=false&serverTimezone=UTC";
    private static final String USERNAME = "root";
    private static final String PASSWORD = "password";
    
    static {
        try {
            // 加载MySQL驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            throw new RuntimeException("加载数据库驱动失败", e);
        }
    }
    
    public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection(URL, USERNAME, PASSWORD);
    }
    
    // 关闭资源的工具方法
    public static void closeQuietly(AutoCloseable... resources) {
        for (AutoCloseable resource : resources) {
            if (resource != null) {
                try {
                    resource.close();
                } catch (Exception e) {
                    // 静默关闭,忽略异常
                }
            }
        }
    }
}

// 用户DAO类
class UserDAO {
    
    // 创建用户表
    public void createTable() {
        String sql = """
            CREATE TABLE IF NOT EXISTS users (
                id INT AUTO_INCREMENT PRIMARY KEY,
                name VARCHAR(100) NOT NULL,
                email VARCHAR(100) UNIQUE NOT NULL,
                age INT DEFAULT 0,
                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
            )
            """;
        
        try (Connection conn = DatabaseUtil.getConnection();
             Statement stmt = conn.createStatement()) {
            
            stmt.execute(sql);
            System.out.println("用户表创建成功");
            
        } catch (SQLException e) {
            System.err.println("创建表失败: " + e.getMessage());
        }
    }
    
    // 插入用户
    public boolean insertUser(User user) {
        String sql = "INSERT INTO users (name, email, age) VALUES (?, ?, ?)";
        
        try (Connection conn = DatabaseUtil.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
            
            pstmt.setString(1, user.getName());
            pstmt.setString(2, user.getEmail());
            pstmt.setInt(3, user.getAge());
            
            int rowsAffected = pstmt.executeUpdate();
            System.out.println("插入用户成功,影响行数: " + rowsAffected);
            return rowsAffected > 0;
            
        } catch (SQLException e) {
            System.err.println("插入用户失败: " + e.getMessage());
            return false;
        }
    }
    
    // 根据ID查询用户
    public User getUserById(int id) {
        String sql = "SELECT * FROM users WHERE id = ?";
        
        try (Connection conn = DatabaseUtil.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
            
            pstmt.setInt(1, id);
            ResultSet rs = pstmt.executeQuery();
            
            if (rs.next()) {
                return new User(
                    rs.getInt("id"),
                    rs.getString("name"),
                    rs.getString("email"),
                    rs.getInt("age")
                );
            }
            
        } catch (SQLException e) {
            System.err.println("查询用户失败: " + e.getMessage());
        }
        
        return null;
    }
    
    // 查询所有用户
    public List<User> getAllUsers() {
        List<User> users = new ArrayList<>();
        String sql = "SELECT * FROM users ORDER BY id";
        
        try (Connection conn = DatabaseUtil.getConnection();
             Statement stmt = conn.createStatement();
             ResultSet rs = stmt.executeQuery(sql)) {
            
            while (rs.next()) {
                User user = new User(
                    rs.getInt("id"),
                    rs.getString("name"),
                    rs.getString("email"),
                    rs.getInt("age")
                );
                users.add(user);
            }
            
        } catch (SQLException e) {
            System.err.println("查询所有用户失败: " + e.getMessage());
        }
        
        return users;
    }
    
    // 更新用户
    public boolean updateUser(User user) {
        String sql = "UPDATE users SET name = ?, email = ?, age = ? WHERE id = ?";
        
        try (Connection conn = DatabaseUtil.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
            
            pstmt.setString(1, user.getName());
            pstmt.setString(2, user.getEmail());
            pstmt.setInt(3, user.getAge());
            pstmt.setInt(4, user.getId());
            
            int rowsAffected = pstmt.executeUpdate();
            System.out.println("更新用户成功,影响行数: " + rowsAffected);
            return rowsAffected > 0;
            
        } catch (SQLException e) {
            System.err.println("更新用户失败: " + e.getMessage());
            return false;
        }
    }
    
    // 删除用户
    public boolean deleteUser(int id) {
        String sql = "DELETE FROM users WHERE id = ?";
        
        try (Connection conn = DatabaseUtil.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
            
            pstmt.setInt(1, id);
            int rowsAffected = pstmt.executeUpdate();
            System.out.println("删除用户成功,影响行数: " + rowsAffected);
            return rowsAffected > 0;
            
        } catch (SQLException e) {
            System.err.println("删除用户失败: " + e.getMessage());
            return false;
        }
    }
    
    // 根据姓名模糊查询
    public List<User> searchUsersByName(String namePattern) {
        List<User> users = new ArrayList<>();
        String sql = "SELECT * FROM users WHERE name LIKE ? ORDER BY id";
        
        try (Connection conn = DatabaseUtil.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
            
            pstmt.setString(1, "%" + namePattern + "%");
            ResultSet rs = pstmt.executeQuery();
            
            while (rs.next()) {
                User user = new User(
                    rs.getInt("id"),
                    rs.getString("name"),
                    rs.getString("email"),
                    rs.getInt("age")
                );
                users.add(user);
            }
            
        } catch (SQLException e) {
            System.err.println("搜索用户失败: " + e.getMessage());
        }
        
        return users;
    }
}

// 测试类
public class JDBCTest {
    public static void main(String[] args) {
        UserDAO userDAO = new UserDAO();
        
        // 创建表
        userDAO.createTable();
        
        // 插入测试数据
        User user1 = new User("张三", "zhangsan@example.com", 25);
        User user2 = new User("李四", "lisi@example.com", 30);
        User user3 = new User("王五", "wangwu@example.com", 28);
        
        userDAO.insertUser(user1);
        userDAO.insertUser(user2);
        userDAO.insertUser(user3);
        
        // 查询所有用户
        System.out.println("\n=== 所有用户 ===");
        List<User> allUsers = userDAO.getAllUsers();
        allUsers.forEach(System.out::println);
        
        // 根据ID查询
        System.out.println("\n=== 查询ID为1的用户 ===");
        User user = userDAO.getUserById(1);
        System.out.println(user);
        
        // 更新用户
        if (user != null) {
            user.setAge(26);
            userDAO.updateUser(user);
            
            System.out.println("\n=== 更新后的用户 ===");
            User updatedUser = userDAO.getUserById(1);
            System.out.println(updatedUser);
        }
        
        // 模糊查询
        System.out.println("\n=== 搜索姓名包含'张'的用户 ===");
        List<User> searchResults = userDAO.searchUsersByName("张");
        searchResults.forEach(System.out::println);
        
        // 删除用户
        // userDAO.deleteUser(2);
        // System.out.println("\n=== 删除ID为2的用户后 ===");
        // userDAO.getAllUsers().forEach(System.out::println);
    }
}

7.2 数据库连接池

java 复制代码
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import java.sql.Connection;
import java.sql.SQLException;

// HikariCP 连接池配置
class ConnectionPoolConfig {
    private static HikariDataSource dataSource;
    
    static {
        HikariConfig config = new HikariConfig();
        config.setJdbcUrl("jdbc:mysql://localhost:3306/testdb?useSSL=false&serverTimezone=UTC");
        config.setUsername("root");
        config.setPassword("password");
        config.setDriverClassName("com.mysql.cj.jdbc.Driver");
        
        // 连接池配置
        config.setMaximumPoolSize(20);          // 最大连接数
        config.setMinimumIdle(5);               // 最小空闲连接数
        config.setConnectionTimeout(30000);     // 连接超时时间(毫秒)
        config.setIdleTimeout(600000);          // 空闲超时时间(毫秒)
        config.setMaxLifetime(1800000);         // 连接最大生存时间(毫秒)
        config.setLeakDetectionThreshold(60000); // 连接泄漏检测阈值
        
        dataSource = new HikariDataSource(config);
    }
    
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }
    
    public static void closeDataSource() {
        if (dataSource != null) {
            dataSource.close();
        }
    }
}

// 使用连接池的DAO示例
class PooledUserDAO extends UserDAO {
    
    @Override
    public boolean insertUser(User user) {
        String sql = "INSERT INTO users (name, email, age) VALUES (?, ?, ?)";
        
        try (Connection conn = ConnectionPoolConfig.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
            
            pstmt.setString(1, user.getName());
            pstmt.setString(2, user.getEmail());
            pstmt.setInt(3, user.getAge());
            
            int rowsAffected = pstmt.executeUpdate();
            System.out.println("使用连接池插入用户成功,影响行数: " + rowsAffected);
            return rowsAffected > 0;
            
        } catch (SQLException e) {
            System.err.println("使用连接池插入用户失败: " + e.getMessage());
            return false;
        }
    }
    
    // 其他方法类似,只是使用连接池获取连接
}

8. Spring 框架

8.1 Spring Core (IoC/DI)

java 复制代码
// 1. 配置类方式
import org.springframework.context.annotation.*;
import org.springframework.stereotype.*;

// 实体类
class User {
    private Long id;
    private String name;
    private String email;
    
    // 构造方法
    public User() {}
    
    public User(Long id, String name, String email) {
        this.id = id;
        this.name = name;
        this.email = email;
    }
    
    // Getter和Setter
    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public String getEmail() { return email; }
    public void setEmail(String email) { this.email = email; }
    
    @Override
    public String toString() {
        return "User{id=" + id + ", name='" + name + "', email='" + email + "'}";
    }
}

// 服务接口
interface UserService {
    User findById(Long id);
    void save(User user);
    List<User> findAll();
}

// 服务实现类
@Service
class UserServiceImpl implements UserService {
    
    @Autowired
    private UserRepository userRepository;
    
    @Override
    public User findById(Long id) {
        return userRepository.findById(id);
    }
    
    @Override
    public void save(User user) {
        userRepository.save(user);
    }
    
    @Override
    public List<User> findAll() {
        return userRepository.findAll();
    }
}

// 仓库接口
interface UserRepository {
    User findById(Long id);
    void save(User user);
    List<User> findAll();
}

// 仓库实现类
@Repository
class UserRepositoryImpl implements UserRepository {
    
    // 模拟数据库存储
    private static final Map<Long, User> userMap = new HashMap<>();
    private static Long idCounter = 1L;
    
    @Override
    public User findById(Long id) {
        return userMap.get(id);
    }
    
    @Override
    public void save(User user) {
        if (user.getId() == null) {
            user.setId(idCounter++);
        }
        userMap.put(user.getId(), user);
        System.out.println("保存用户: " + user);
    }
    
    @Override
    public List<User> findAll() {
        return new ArrayList<>(userMap.values());
    }
}

// 配置类
@Configuration
@ComponentScan(basePackages = "com.example")
class AppConfig {
    
    // 可以在这里定义Bean
    @Bean
    public User defaultUser() {
        return new User(0L, "默认用户", "default@example.com");
    }
}

// 控制器类
@Controller
class UserController {
    
    @Autowired
    private UserService userService;
    
    public void createUser(String name, String email) {
        User user = new User(null, name, email);
        userService.save(user);
        System.out.println("创建用户成功: " + user);
    }
    
    public User getUser(Long id) {
        return userService.findById(id);
    }
    
    public List<User> getAllUsers() {
        return userService.findAll();
    }
}

// 主程序类
public class SpringCoreExample {
    public static void main(String[] args) {
        // 创建Spring应用上下文
        AnnotationConfigApplicationContext context = 
            new AnnotationConfigApplicationContext(AppConfig.class);
        
        // 获取Bean
        UserController userController = context.getBean(UserController.class);
        
        // 测试功能
        userController.createUser("张三", "zhangsan@example.com");
        userController.createUser("李四", "lisi@example.com");
        
        System.out.println("\n=== 所有用户 ===");
        userController.getAllUsers().forEach(System.out::println);
        
        // 关闭上下文
        context.close();
    }
}

8.2 Spring Boot 基础

java 复制代码
// pom.xml 依赖示例
/*
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>
*/

// 主启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

// 实体类
import javax.persistence.*;

@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(nullable = false)
    private String name;
    
    @Column(unique = true, nullable = false)
    private String email;
    
    private Integer age;
    
    // 构造方法
    public User() {}
    
    public User(String name, String email, Integer age) {
        this.name = name;
        this.email = email;
        this.age = age;
    }
    
    // Getter和Setter
    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public String getEmail() { return email; }
    public void setEmail(String email) { this.email = email; }
    public Integer getAge() { return age; }
    public void setAge(Integer age) { this.age = age; }
    
    @Override
    public String toString() {
        return "User{id=" + id + ", name='" + name + "', email='" + email + "', age=" + age + "}";
    }
}

// Repository接口
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.List;

public interface UserRepository extends JpaRepository<User, Long> {
    
    // 根据邮箱查找用户
    User findByEmail(String email);
    
    // 根据姓名查找用户(模糊查询)
    List<User> findByNameContaining(String name);
    
    // 自定义查询
    @Query("SELECT u FROM User u WHERE u.age > :age")
    List<User> findUsersOlderThan(@Param("age") Integer age);
}

// Service层
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Optional;

@Service
@Transactional
public class UserService {
    
    @Autowired
    private UserRepository userRepository;
    
    public List<User> findAll() {
        return userRepository.findAll();
    }
    
    public Optional<User> findById(Long id) {
        return userRepository.findById(id);
    }
    
    public User save(User user) {
        return userRepository.save(user);
    }
    
    public void deleteById(Long id) {
        userRepository.deleteById(id);
    }
    
    public User findByEmail(String email) {
        return userRepository.findByEmail(email);
    }
    
    public List<User> findByNameContaining(String name) {
        return userRepository.findByNameContaining(name);
    }
    
    public List<User> findUsersOlderThan(Integer age) {
        return userRepository.findUsersOlderThan(age);
    }
}

// REST控制器
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Optional;

@RestController
@RequestMapping("/api/users")
public class UserController {
    
    @Autowired
    private UserService userService;
    
    // 获取所有用户
    @GetMapping
    public List<User> getAllUsers() {
        return userService.findAll();
    }
    
    // 根据ID获取用户
    @GetMapping("/{id}")
    public ResponseEntity<User> getUserById(@PathVariable Long id) {
        Optional<User> user = userService.findById(id);
        return user.map(ResponseEntity::ok)
                  .orElse(ResponseEntity.notFound().build());
    }
    
    // 创建用户
    @PostMapping
    public User createUser(@RequestBody User user) {
        return userService.save(user);
    }
    
    // 更新用户
    @PutMapping("/{id}")
    public ResponseEntity<User> updateUser(@PathVariable Long id, @RequestBody User userDetails) {
        Optional<User> optionalUser = userService.findById(id);
        if (optionalUser.isPresent()) {
            User user = optionalUser.get();
            user.setName(userDetails.getName());
            user.setEmail(userDetails.getEmail());
            user.setAge(userDetails.getAge());
            User updatedUser = userService.save(user);
            return ResponseEntity.ok(updatedUser);
        } else {
            return ResponseEntity.notFound().build();
        }
    }
    
    // 删除用户
    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
        userService.deleteById(id);
        return ResponseEntity.ok().build();
    }
    
    // 根据邮箱查找用户
    @GetMapping("/email/{email}")
    public ResponseEntity<User> getUserByEmail(@PathVariable String email) {
        User user = userService.findByEmail(email);
        return user != null ? ResponseEntity.ok(user) : ResponseEntity.notFound().build();
    }
    
    // 根据姓名模糊查询
    @GetMapping("/search")
    public List<User> searchUsers(@RequestParam String name) {
        return userService.findByNameContaining(name);
    }
    
    // 查找年龄大于指定值的用户
    @GetMapping("/older-than/{age}")
    public List<User> getUsersOlderThan(@PathVariable Integer age) {
        return userService.findUsersOlderThan(age);
    }
}

// 配置文件 application.yml
/*
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/testdb?useSSL=false&serverTimezone=UTC
    username: root
    password: password
    driver-class-name: com.mysql.cj.jdbc.Driver
  
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true
    properties:
      hibernate:
        dialect: org.hibernate.dialect.MySQL8Dialect

server:
  port: 8080
*/

9. Web 开发

9.1 Servlet 基础

java 复制代码
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

// 简单的用户实体类
class SimpleUser {
    private int id;
    private String name;
    private String email;
    
    public SimpleUser(int id, String name, String email) {
        this.id = id;
        this.name = name;
        this.email = email;
    }
    
    // Getter方法
    public int getId() { return id; }
    public String getName() { return name; }
    public String getEmail() { return email; }
    
    @Override
    public String toString() {
        return "SimpleUser{id=" + id + ", name='" + name + "', email='" + email + "'}";
    }
}

// 模拟数据访问
class UserService {
    private static List<SimpleUser> users = new ArrayList<>();
    private static int nextId = 1;
    
    static {
        users.add(new SimpleUser(nextId++, "张三", "zhangsan@example.com"));
        users.add(new SimpleUser(nextId++, "李四", "lisi@example.com"));
        users.add(new SimpleUser(nextId++, "王五", "wangwu@example.com"));
    }
    
    public List<SimpleUser> getAllUsers() {
        return new ArrayList<>(users);
    }
    
    public SimpleUser getUserById(int id) {
        return users.stream()
                   .filter(user -> user.getId() == id)
                   .findFirst()
                   .orElse(null);
    }
    
    public void addUser(SimpleUser user) {
        user = new SimpleUser(nextId++, user.getName(), user.getEmail());
        users.add(user);
    }
    
    public boolean deleteUser(int id) {
        return users.removeIf(user -> user.getId() == id);
    }
}

// 用户列表Servlet
@WebServlet("/users")
public class UserListServlet extends HttpServlet {
    private UserService userService = new UserService();
    
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        
        List<SimpleUser> users = userService.getAllUsers();
        
        out.println("<!DOCTYPE html>");
        out.println("<html>");
        out.println("<head>");
        out.println("<meta charset='UTF-8'>");
        out.println("<title>用户列表</title>");
        out.println("</head>");
        out.println("<body>");
        out.println("<h1>用户列表</h1>");
        out.println("<a href='add-user.html'>添加用户</a>");
        out.println("<table border='1'>");
        out.println("<tr><th>ID</th><th>姓名</th><th>邮箱</th><th>操作</th></tr>");
        
        for (SimpleUser user : users) {
            out.println("<tr>");
            out.println("<td>" + user.getId() + "</td>");
            out.println("<td>" + user.getName() + "</td>");
            out.println("<td>" + user.getEmail() + "</td>");
            out.println("<td><a href='delete-user?id=" + user.getId() + "'>删除</a></td>");
            out.println("</tr>");
        }
        
        out.println("</table>");
        out.println("</body>");
        out.println("</html>");
    }
}

// 添加用户Servlet
@WebServlet("/add-user")
public class AddUserServlet extends HttpServlet {
    private UserService userService = new UserService();
    
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        
        request.setCharacterEncoding("UTF-8");
        
        String name = request.getParameter("name");
        String email = request.getParameter("email");
        
        if (name != null && !name.trim().isEmpty() &&
            email != null && !email.trim().isEmpty()) {
            
            SimpleUser user = new SimpleUser(0, name, email);
            userService.addUser(user);
        }
        
        // 重定向到用户列表
        response.sendRedirect("users");
    }
}

// 删除用户Servlet
@WebServlet("/delete-user")
public class DeleteUserServlet extends HttpServlet {
    private UserService userService = new UserService();
    
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        
        String idParam = request.getParameter("id");
        if (idParam != null && !idParam.trim().isEmpty()) {
            try {
                int id = Integer.parseInt(idParam);
                userService.deleteUser(id);
            } catch (NumberFormatException e) {
                // 处理无效ID
            }
        }
        
        // 重定向到用户列表
        response.sendRedirect("users");
    }
}

// JSON API Servlet
@WebServlet("/api/users")
public class UserApiServlet extends HttpServlet {
    private UserService userService = new UserService();
    private ObjectMapper objectMapper = new ObjectMapper();
    
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        
        response.setContentType("application/json;charset=UTF-8");
        
        List<SimpleUser> users = userService.getAllUsers();
        String json = objectMapper.writeValueAsString(users);
        
        response.getWriter().write(json);
    }
}

// web.xml 配置示例
/*
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
         http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    
    <display-name>User Management Web App</display-name>
    
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>
    
</web-app>
*/

9.2 Spring MVC

java 复制代码
// 控制器
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import javax.validation.Valid;
import java.util.List;

@Controller
@RequestMapping("/users")
public class UserWebController {
    
    @Autowired
    private UserService userService;
    
    // 显示用户列表页面
    @GetMapping
    public String listUsers(Model model) {
        List<User> users = userService.findAll();
        model.addAttribute("users", users);
        return "user/list"; // 返回视图名称
    }
    
    // 显示添加用户表单
    @GetMapping("/new")
    public String showCreateForm(Model model) {
        model.addAttribute("user", new User());
        return "user/form";
    }
    
    // 处理添加用户请求
    @PostMapping
    public String createUser(@Valid @ModelAttribute User user, 
                           BindingResult result,
                           RedirectAttributes redirectAttributes) {
        
        if (result.hasErrors()) {
            return "user/form";
        }
        
        try {
            userService.save(user);
            redirectAttributes.addFlashAttribute("message", "用户创建成功!");
            return "redirect:/users";
        } catch (Exception e) {
            redirectAttributes.addFlashAttribute("error", "创建用户失败:" + e.getMessage());
            return "redirect:/users/new";
        }
    }
    
    // 显示编辑用户表单
    @GetMapping("/edit/{id}")
    public String showEditForm(@PathVariable Long id, Model model) {
        User user = userService.findById(id).orElse(null);
        if (user == null) {
            return "redirect:/users";
        }
        model.addAttribute("user", user);
        return "user/form";
    }
    
    // 处理更新用户请求
    @PostMapping("/update/{id}")
    public String updateUser(@PathVariable Long id,
                           @Valid @ModelAttribute User userDetails,
                           BindingResult result,
                           RedirectAttributes redirectAttributes) {
        
        if (result.hasErrors()) {
            return "user/form";
        }
        
        User user = userService.findById(id).orElse(null);
        if (user == null) {
            redirectAttributes.addFlashAttribute("error", "用户不存在");
            return "redirect:/users";
        }
        
        user.setName(userDetails.getName());
        user.setEmail(userDetails.getEmail());
        user.setAge(userDetails.getAge());
        
        userService.save(user);
        redirectAttributes.addFlashAttribute("message", "用户更新成功!");
        return "redirect:/users";
    }
    
    // 删除用户
    @PostMapping("/delete/{id}")
    public String deleteUser(@PathVariable Long id, RedirectAttributes redirectAttributes) {
        userService.deleteById(id);
        redirectAttributes.addFlashAttribute("message", "用户删除成功!");
        return "redirect:/users";
    }
}

// REST控制器
@RestController
@RequestMapping("/api/users")
public class UserRestController {
    
    @Autowired
    private UserService userService;
    
    // 获取所有用户
    @GetMapping
    public ResponseEntity<List<User>> getAllUsers() {
        List<User> users = userService.findAll();
        return ResponseEntity.ok(users);
    }
    
    // 根据ID获取用户
    @GetMapping("/{id}")
    public ResponseEntity<User> getUserById(@PathVariable Long id) {
        return userService.findById(id)
                .map(ResponseEntity::ok)
                .orElse(ResponseEntity.notFound().build());
    }
    
    // 创建用户
    @PostMapping
    public ResponseEntity<User> createUser(@Valid @RequestBody User user) {
        User savedUser = userService.save(user);
        return ResponseEntity.status(HttpStatus.CREATED).body(savedUser);
    }
    
    // 更新用户
    @PutMapping("/{id}")
    public ResponseEntity<User> updateUser(@PathVariable Long id, 
                                         @Valid @RequestBody User userDetails) {
        return userService.findById(id)
                .map(user -> {
                    user.setName(userDetails.getName());
                    user.setEmail(userDetails.getEmail());
                    user.setAge(userDetails.getAge());
                    User updatedUser = userService.save(user);
                    return ResponseEntity.ok(updatedUser);
                })
                .orElse(ResponseEntity.notFound().build());
    }
    
    // 删除用户
    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
        return userService.findById(id)
                .map(user -> {
                    userService.deleteById(id);
                    return ResponseEntity.ok().<Void>build();
                })
                .orElse(ResponseEntity.notFound().build());
    }
}

// 全局异常处理
@ControllerAdvice
public class GlobalExceptionHandler {
    
    @ExceptionHandler(UserNotFoundException.class)
    public ResponseEntity<String> handleUserNotFound(UserNotFoundException e) {
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(e.getMessage());
    }
    
    @ExceptionHandler(Exception.class)
    public ResponseEntity<String> handleGeneralException(Exception e) {
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                           .body("服务器内部错误:" + e.getMessage());
    }
}

// 自定义异常
public class UserNotFoundException extends RuntimeException {
    public UserNotFoundException(String message) {
        super(message);
    }
}

10. 项目实践

10.1 完整的用户管理系统

java 复制代码
// 项目结构说明
/*
src/
├── main/
│   ├── java/
│   │   └── com/example/usermanagement/
│   │       ├── UserManagementApplication.java  // 启动类
│   │       ├── controller/                     // 控制器层
│   │       │   ├── UserController.java
│   │       │   └── UserWebController.java
│   │       ├── service/                        // 服务层
│   │       │   ├── UserService.java
│   │       │   └── impl/UserServiceImpl.java
│   │       ├── repository/                     // 数据访问层
│   │       │   └── UserRepository.java
│   │       ├── entity/                         // 实体类
│   │       │   └── User.java
│   │       ├── dto/                            // 数据传输对象
│   │       │   ├── UserDTO.java
│   │       │   └── UserCreateRequest.java
│   │       └── exception/                      // 异常处理
│   │           ├── GlobalExceptionHandler.java
│   │           └── UserNotFoundException.java
│   ├── resources/
│   │   ├── application.yml                    // 配置文件
│   │   ├── static/                            // 静态资源
│   │   └── templates/                         // 模板文件
│   └── webapp/                                // Web资源
└── test/
    └── java/
        └── com/example/usermanagement/
*/

// 启动类
@SpringBootApplication
public class UserManagementApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserManagementApplication.class, args);
    }
}

// DTO - 用户创建请求
public class UserCreateRequest {
    @NotBlank(message = "姓名不能为空")
    @Size(min = 2, max = 50, message = "姓名长度必须在2-50个字符之间")
    private String name;
    
    @NotBlank(message = "邮箱不能为空")
    @Email(message = "邮箱格式不正确")
    private String email;
    
    @Min(value = 0, message = "年龄不能小于0")
    @Max(value = 150, message = "年龄不能大于150")
    private Integer age;
    
    // Getter和Setter
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public String getEmail() { return email; }
    public void setEmail(String email) { this.email = email; }
    public Integer getAge() { return age; }
    public void setAge(Integer age) { this.age = age; }
}

// DTO - 用户响应
public class UserResponse {
    private Long id;
    private String name;
    private String email;
    private Integer age;
    private LocalDateTime createdAt;
    
    // 构造方法
    public UserResponse(User user) {
        this.id = user.getId();
        this.name = user.getName();
        this.email = user.getEmail();
        this.age = user.getAge();
        this.createdAt = user.getCreatedAt();
    }
    
    // Getter方法
    public Long getId() { return id; }
    public String getName() { return name; }
    public String getEmail() { return email; }
    public Integer getAge() { return age; }
    public LocalDateTime getCreatedAt() { return createdAt; }
}

// 服务接口
public interface UserService {
    List<UserResponse> findAll();
    Optional<UserResponse> findById(Long id);
    UserResponse save(UserCreateRequest request);
    UserResponse update(Long id, UserCreateRequest request);
    void deleteById(Long id);
    Optional<User> findByEmail(String email);
}

// 服务实现
@Service
@Transactional
public class UserServiceImpl implements UserService {
    
    @Autowired
    private UserRepository userRepository;
    
    @Override
    @Transactional(readOnly = true)
    public List<UserResponse> findAll() {
        return userRepository.findAll()
                           .stream()
                           .map(UserResponse::new)
                           .collect(Collectors.toList());
    }
    
    @Override
    @Transactional(readOnly = true)
    public Optional<UserResponse> findById(Long id) {
        return userRepository.findById(id)
                           .map(UserResponse::new);
    }
    
    @Override
    public UserResponse save(UserCreateRequest request) {
        // 检查邮箱是否已存在
        if (userRepository.existsByEmail(request.getEmail())) {
            throw new IllegalArgumentException("邮箱已存在:" + request.getEmail());
        }
        
        User user = new User();
        user.setName(request.getName());
        user.setEmail(request.getEmail());
        user.setAge(request.getAge());
        user.setCreatedAt(LocalDateTime.now());
        
        User savedUser = userRepository.save(user);
        return new UserResponse(savedUser);
    }
    
    @Override
    public UserResponse update(Long id, UserCreateRequest request) {
        User user = userRepository.findById(id)
                .orElseThrow(() -> new UserNotFoundException("用户不存在,ID:" + id));
        
        // 检查邮箱是否被其他用户使用
        User existingUser = userRepository.findByEmail(request.getEmail());
        if (existingUser != null && !existingUser.getId().equals(id)) {
            throw new IllegalArgumentException("邮箱已被其他用户使用:" + request.getEmail());
        }
        
        user.setName(request.getName());
        user.setEmail(request.getEmail());
        user.setAge(request.getAge());
        
        User updatedUser = userRepository.save(user);
        return new UserResponse(updatedUser);
    }
    
    @Override
    public void deleteById(Long id) {
        if (!userRepository.existsById(id)) {
            throw new UserNotFoundException("用户不存在,ID:" + id);
        }
        userRepository.deleteById(id);
    }
    
    @Override
    @Transactional(readOnly = true)
    public Optional<User> findByEmail(String email) {
        return Optional.ofNullable(userRepository.findByEmail(email));
    }
}

// REST控制器
@RestController
@RequestMapping("/api/v1/users")
@Validated
public class UserRestController {
    
    @Autowired
    private UserService userService;
    
    @GetMapping
    public ResponseEntity<List<UserResponse>> getAllUsers() {
        List<UserResponse> users = userService.findAll();
        return ResponseEntity.ok(users);
    }
    
    @GetMapping("/{id}")
    public ResponseEntity<UserResponse> getUserById(@PathVariable Long id) {
        return userService.findById(id)
                .map(ResponseEntity::ok)
                .orElse(ResponseEntity.notFound().build());
    }
    
    @PostMapping
    public ResponseEntity<UserResponse> createUser(@Valid @RequestBody UserCreateRequest request) {
        try {
            UserResponse user = userService.save(request);
            return ResponseEntity.status(HttpStatus.CREATED).body(user);
        } catch (IllegalArgumentException e) {
            return ResponseEntity.badRequest().build();
        }
    }
    
    @PutMapping("/{id}")
    public ResponseEntity<UserResponse> updateUser(@PathVariable Long id,
                                                 @Valid @RequestBody UserCreateRequest request) {
        try {
            UserResponse user = userService.update(id, request);
            return ResponseEntity.ok(user);
        } catch (UserNotFoundException e) {
            return ResponseEntity.notFound().build();
        } catch (IllegalArgumentException e) {
            return ResponseEntity.badRequest().build();
        }
    }
    
    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
        try {
            userService.deleteById(id);
            return ResponseEntity.noContent().build();
        } catch (UserNotFoundException e) {
            return ResponseEntity.notFound().build();
        }
    }
}

// Web控制器
@Controller
@RequestMapping("/web/users")
public class UserWebController {
    
    @Autowired
    private UserService userService;
    
    @GetMapping
    public String listUsers(Model model) {
        List<UserResponse> users = userService.findAll();
        model.addAttribute("users", users);
        return "users/list";
    }
    
    @GetMapping("/new")
    public String showCreateForm(Model model) {
        model.addAttribute("userRequest", new UserCreateRequest());
        return "users/form";
    }
    
    @PostMapping
    public String createUser(@Valid @ModelAttribute("userRequest") UserCreateRequest request,
                           BindingResult result,
                           RedirectAttributes redirectAttributes) {
        
        if (result.hasErrors()) {
            return "users/form";
        }
        
        try {
            userService.save(request);
            redirectAttributes.addFlashAttribute("message", "用户创建成功!");
            return "redirect:/web/users";
        } catch (IllegalArgumentException e) {
            result.rejectValue("email", "error.user", e.getMessage());
            return "users/form";
        }
    }
    
    @GetMapping("/edit/{id}")
    public String showEditForm(@PathVariable Long id, Model model) {
        return userService.findById(id)
                .map(user -> {
                    UserCreateRequest request = new UserCreateRequest();
                    request.setName(user.getName());
                    request.setEmail(user.getEmail());
                    request.setAge(user.getAge());
                    model.addAttribute("userRequest", request);
                    model.addAttribute("userId", id);
                    return "users/form";
                })
                .orElse("redirect:/web/users");
    }
    
    @PostMapping("/update/{id}")
    public String updateUser(@PathVariable Long id,
                           @Valid @ModelAttribute("userRequest") UserCreateRequest request,
                           BindingResult result,
                           RedirectAttributes redirectAttributes) {
        
        if (result.hasErrors()) {
            return "users/form";
        }
        
        try {
            userService.update(id, request);
            redirectAttributes.addFlashAttribute("message", "用户更新成功!");
            return "redirect:/web/users";
        } catch (UserNotFoundException e) {
            redirectAttributes.addFlashAttribute("error", "用户不存在");
            return "redirect:/web/users";
        } catch (IllegalArgumentException e) {
            result.rejectValue("email", "error.user", e.getMessage());
            return "users/form";
        }
    }
    
    @PostMapping("/delete/{id}")
    public String deleteUser(@PathVariable Long id, RedirectAttributes redirectAttributes) {
        try {
            userService.deleteById(id);
            redirectAttributes.addFlashAttribute("message", "用户删除成功!");
        } catch (UserNotFoundException e) {
            redirectAttributes.addFlashAttribute("error", "用户不存在");
        }
        return "redirect:/web/users";
    }
}

// Thymeleaf 模板示例 (resources/templates/users/list.html)
/*
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>用户管理</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
    <div class="container mt-4">
        <h1>用户列表</h1>
        
        <div th:if="${message}" class="alert alert-success" th:text="${message}"></div>
        <div th:if="${error}" class="alert alert-danger" th:text="${error}"></div>
        
        <div class="mb-3">
            <a href="/web/users/new" class="btn btn-primary">添加用户</a>
        </div>
        
        <table class="table table-striped">
            <thead>
                <tr>
                    <th>ID</th>
                    <th>姓名</th>
                    <th>邮箱</th>
                    <th>年龄</th>
                    <th>创建时间</th>
                    <th>操作</th>
                </tr>
            </thead>
            <tbody>
                <tr th:each="user : ${users}">
                    <td th:text="${user.id}"></td>
                    <td th:text="${user.name}"></td>
                    <td th:text="${user.email}"></td>
                    <td th:text="${user.age}"></td>
                    <td th:text="${#temporals.format(user.createdAt, 'yyyy-MM-dd HH:mm:ss')}"></td>
                    <td>
                        <a th:href="@{/web/users/edit/{id}(id=${user.id})}" class="btn btn-sm btn-warning">编辑</a>
                        <form th:action="@{/web/users/delete/{id}(id=${user.id})}" method="post" style="display:inline;">
                            <button type="submit" class="btn btn-sm btn-danger" 
                                    onclick="return confirm('确定要删除这个用户吗?')">删除</button>
                        </form>
                    </td>
                </tr>
            </tbody>
        </table>
    </div>
</body>
</html>
*/

10.2 测试

java 复制代码
// 单元测试
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;

@SpringBootTest
class UserServiceTest {
    
    @Test
    void testCreateUser() {
        // 准备测试数据
        UserCreateRequest request = new UserCreateRequest();
        request.setName("测试用户");
        request.setEmail("test@example.com");
        request.setAge(25);
        
        // 执行测试
        UserResponse response = userService.save(request);
        
        // 验证结果
        assertNotNull(response.getId());
        assertEquals("测试用户", response.getName());
        assertEquals("test@example.com", response.getEmail());
        assertEquals(25, response.getAge());
    }
    
    @Test
    void testFindUserById() {
        // 准备测试数据
        UserCreateRequest request = new UserCreateRequest();
        request.setName("测试用户");
        request.setEmail("test@example.com");
        request.setAge(25);
        
        UserResponse createdUser = userService.save(request);
        
        // 执行测试
        Optional<UserResponse> foundUser = userService.findById(createdUser.getId());
        
        // 验证结果
        assertTrue(foundUser.isPresent());
        assertEquals(createdUser.getId(), foundUser.get().getId());
    }
}

// 集成测试
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureWebMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

@SpringBootTest
@AutoConfigureWebMvc
class UserRestControllerTest {
    
    @Autowired
    private MockMvc mockMvc;
    
    @Test
    void testGetAllUsers() throws Exception {
        mockMvc.perform(get("/api/v1/users")
                .contentType(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$").isArray());
    }
    
    @Test
    void testCreateUser() throws Exception {
        String userJson = """
            {
                "name": "测试用户",
                "email": "test@example.com",
                "age": 25
            }
            """;
        
        mockMvc.perform(post("/api/v1/users")
                .contentType(MediaType.APPLICATION_JSON)
                .content(userJson))
                .andExpect(status().isCreated())
                .andExpect(jsonPath("$.name").value("测试用户"))
                .andExpect(jsonPath("$.email").value("test@example.com"));
    }
}

11. 总结

这份复习指南涵盖了 Java 后端开发的核心知识点:

11.1 基础部分(详细)

  • Java 语法基础
  • 面向对象编程
  • 集合框架
  • 异常处理

11.2 进阶部分(中等详细)

  • 多线程编程
  • IO/NIO 操作
  • 数据库操作(JDBC)
  • Spring 框架基础

11.3 高级部分(概要)

  • Web 开发(Servlet/Spring MVC)
  • 项目实践和测试

11.4 学习建议

  1. 循序渐进:从基础语法开始,逐步深入
  2. 动手实践:每个知识点都要写代码验证
  3. 项目驱动:通过完整项目整合所学知识
  4. 持续学习:关注新技术发展,如 Spring Boot、微服务等
相关推荐
Elieal2 小时前
SpringMVC 进阶:核心组件详解与参数绑定全攻略
spring·maven
南方者3 小时前
【JAVA】【BUG】经常出现的典型 bug 及解决办法
java·oracle·bug
初圣魔门首席弟子4 小时前
c++嵌套类和局部类详细介绍
java·开发语言·c++
nice_lcj5204 小时前
Java 集合框架之 List 全面解析(从概念到实践)
java·windows·list
高山上有一只小老虎5 小时前
输出单向链表中倒数第k个结点
java·数据结构·链表
失散135 小时前
分布式专题——22 Kafka集群工作机制详解
java·分布式·云原生·架构·kafka
咖啡Beans6 小时前
SseEmitter + WebClient + Flux实现SSE事件流推送
java·spring boot·flux
你三大爷6 小时前
Safepoint的秘密探寻
java·后端
努力也学不会java6 小时前
【Java并发】揭秘Lock体系 -- condition等待通知机制
java·开发语言·人工智能·机器学习·juc·condition