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、微服务等
相关推荐
晒太羊的猫5 小时前
hot100子串
java·算法·leetcode
开开心心就好6 小时前
本地文件搜索工具,双击Ctrl就能呼出搜索
java·服务器·前端·支持向量机·ffmpeg·音视频·模拟退火算法
独隅6 小时前
Claude 高效使用指南深度评测
java·开发语言·claude·claude code
ByteCoder.6 小时前
班前十分钟的清单,按体检引导单来写
java·服务器·前端·助播虾
海的透彻6 小时前
如何让docker容器启动时用自定义的用户
java·docker·dubbo
疯狂学习GIS6 小时前
将谷歌地球引擎账号升级为Contributor与Partner层级的方法
java·数据库·人工智能
GG.WinGel6 小时前
质数数目(蓝桥杯练习题)
java·数据结构·算法·青少年编程·蓝桥杯
泡泡糖的中文规格书6 小时前
HDLbits 2.2 学习笔记 · 多路复用器
java·开发语言
John_Hui6 小时前
第 3 篇:配置 JDK 17 环境
java·开发语言·ubuntu
秋天的怀念_David6 小时前
算法一千零一夜 · 第十七夜 长街点灯
java·程序人生·算法