Skip to content

数据库基础

在Java Web开发中,数据库是存储和管理数据的核心组件。本章节将介绍MySQL数据库的基础知识,以及如何通过JDBC在Java中操作数据库。

数据库基础概念

什么是数据库?

数据库是按照数据结构来组织、存储和管理数据的仓库。在Web应用中,数据库用于持久化存储用户信息、业务数据等。

关系型数据库

关系型数据库是基于关系模型的数据库,使用行和列来存储数据。MySQL是最流行的开源关系型数据库之一。

基本概念

  • 表(Table):数据的集合,由行和列组成
  • 行(Row):表中的一条记录
  • 列(Column):表中的一个字段
  • 主键(Primary Key):唯一标识表中每一行的列
  • 外键(Foreign Key):用于建立表之间关系的列

SQL语言基础

SQL(Structured Query Language)是用于管理关系型数据库的标准语言。

SQL分类

  1. DDL(数据定义语言):用于定义数据库结构

    • CREATE:创建数据库或表
    • ALTER:修改数据库或表结构
    • DROP:删除数据库或表
  2. DML(数据操作语言):用于操作数据

    • INSERT:插入数据
    • UPDATE:更新数据
    • DELETE:删除数据
  3. DQL(数据查询语言):用于查询数据

    • SELECT:查询数据
  4. DCL(数据控制语言):用于控制数据库访问权限

    • GRANT:授予权限
    • REVOKE:撤销权限

MySQL安装与配置

安装MySQL

在不同操作系统上安装MySQL:

  1. Windows

    • 下载MySQL Installer
    • 运行安装程序,选择合适的安装类型
    • 配置root用户密码
  2. Linux(Ubuntu/Debian)

    bash
    sudo apt update
    sudo apt install mysql-server
    sudo mysql_secure_installation
  3. macOS

    bash
    brew install mysql
    brew services start mysql

启动和连接MySQL

启动MySQL服务:

bash
# Windows
net start mysql

# Linux/macOS
sudo systemctl start mysql
# 或
brew services start mysql

连接MySQL:

bash
mysql -u root -p

MySQL基本操作

数据库操作

sql
-- 创建数据库
CREATE DATABASE myapp CHARACTER SET utf8mb4;

-- 查看所有数据库
SHOW DATABASES;

-- 使用数据库
USE myapp;

-- 删除数据库
DROP DATABASE myapp;

表操作

sql
-- 创建表
CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    username VARCHAR(50) NOT NULL UNIQUE,
    email VARCHAR(100) NOT NULL,
    password VARCHAR(255) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- 查看表结构
DESCRIBE users;
-- 或
SHOW CREATE TABLE users;

-- 修改表结构
ALTER TABLE users ADD COLUMN age INT;

-- 删除表
DROP TABLE users;

数据操作

sql
-- 插入数据
INSERT INTO users (username, email, password) 
VALUES ('zhangsan', 'zhangsan@example.com', 'password123');

-- 查询数据
SELECT * FROM users;
SELECT username, email FROM users WHERE id = 1;

-- 更新数据
UPDATE users SET email = 'newemail@example.com' WHERE id = 1;

-- 删除数据
DELETE FROM users WHERE id = 1;

JDBC编程

JDBC(Java Database Connectivity)是Java提供的用于连接和操作数据库的API。

JDBC基础

JDBC驱动

要使用JDBC连接MySQL,需要添加MySQL JDBC驱动依赖:

Maven依赖:

xml
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.33</version>
</dependency>

Gradle依赖:

gradle
implementation 'mysql:mysql-connector-java:8.0.33'

JDBC编程步骤

  1. 加载驱动(在较新版本中可省略)
  2. 建立连接
  3. 创建Statement
  4. 执行SQL语句
  5. 处理结果
  6. 关闭连接

JDBC示例代码

java
import java.sql.*;

public class JdbcExample {
    private static final String URL = "jdbc:mysql://localhost:3306/myapp?useSSL=false&serverTimezone=UTC";
    private static final String USERNAME = "root";
    private static final String PASSWORD = "your_password";
    
    public static void main(String[] args) {
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        
        try {
            // 1. 建立连接
            conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
            
            // 2. 创建Statement
            stmt = conn.createStatement();
            
            // 3. 执行查询
            String sql = "SELECT id, username, email FROM users";
            rs = stmt.executeQuery(sql);
            
            // 4. 处理结果
            while (rs.next()) {
                int id = rs.getInt("id");
                String username = rs.getString("username");
                String email = rs.getString("email");
                System.out.println("ID: " + id + ", Username: " + username + ", Email: " + email);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            // 5. 关闭资源
            try {
                if (rs != null) rs.close();
                if (stmt != null) stmt.close();
                if (conn != null) conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

PreparedStatement

PreparedStatement是Statement的子接口,可以防止SQL注入攻击,并提高执行效率。

java
public class PreparedStatementExample {
    private static final String URL = "jdbc:mysql://localhost:3306/myapp?useSSL=false&serverTimezone=UTC";
    private static final String USERNAME = "root";
    private static final String PASSWORD = "your_password";
    
    public void insertUser(String username, String email, String password) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        
        try {
            conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
            
            String sql = "INSERT INTO users (username, email, password) VALUES (?, ?, ?)";
            pstmt = conn.prepareStatement(sql);
            
            // 设置参数
            pstmt.setString(1, username);
            pstmt.setString(2, email);
            pstmt.setString(3, password);
            
            // 执行插入
            int rows = pstmt.executeUpdate();
            System.out.println("插入了 " + rows + " 行数据");
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                if (pstmt != null) pstmt.close();
                if (conn != null) conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

数据库连接池

在实际应用中,频繁创建和关闭数据库连接会影响性能。使用连接池可以有效管理数据库连接。

使用HikariCP连接池

添加依赖:

xml
<dependency>
    <groupId>com.zaxxer</groupId>
    <artifactId>HikariCP</artifactId>
    <version>5.0.1</version>
</dependency>

配置连接池:

java
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

public class DatabaseConfig {
    private static HikariDataSource dataSource;
    
    static {
        HikariConfig config = new HikariConfig();
        config.setJdbcUrl("jdbc:mysql://localhost:3306/myapp?useSSL=false&serverTimezone=UTC");
        config.setUsername("root");
        config.setPassword("your_password");
        config.setMaximumPoolSize(20);
        config.setMinimumIdle(5);
        config.setConnectionTimeout(30000);
        config.setIdleTimeout(600000);
        config.setMaxLifetime(1800000);
        
        dataSource = new HikariDataSource(config);
    }
    
    public static DataSource getDataSource() {
        return dataSource;
    }
    
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }
}

使用连接池:

java
public class UserService {
    public User getUserById(int id) {
        String sql = "SELECT * FROM users WHERE id = ?";
        
        try (Connection conn = DatabaseConfig.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
            
            pstmt.setInt(1, id);
            ResultSet rs = pstmt.executeQuery();
            
            if (rs.next()) {
                User user = new User();
                user.setId(rs.getInt("id"));
                user.setUsername(rs.getString("username"));
                user.setEmail(rs.getString("email"));
                return user;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        
        return null;
    }
}

实践练习

创建一个简单的学生管理系统:

  1. 设计学生表结构
  2. 实现学生信息的增删改查功能
  3. 使用JDBC操作数据库
  4. 使用PreparedStatement防止SQL注入
  5. 实现数据库连接池

总结

数据库是Web应用的核心组件,掌握数据库基础知识和JDBC编程对于Java开发者至关重要。通过本章节的学习,你应该能够:

  1. 理解数据库基本概念
  2. 使用SQL进行基本的数据库操作
  3. 使用JDBC在Java中操作数据库
  4. 使用PreparedStatement提高安全性和性能
  5. 使用连接池优化数据库连接管理

在后续章节中,我们将学习更高级的框架(如MyBatis、Spring Data JPA)来简化数据库操作。