网站后端连接数据库知识点大全(一)

简介: 教程来源:https://dnuhf.cn/article/162.html 本文系统梳理Web后端数据库连接核心知识:涵盖JDBC原理、主流驱动配置、PreparedStatement防注入、批处理;深入解析HikariCP、Druid、Tomcat JDBC三大连接池;详解Spring中数据源配置、JdbcTemplate及多数据源实践,助开发者构建高效、安全、稳定的数据库访问体系。

在 Web 开发中,后端与数据库的连接是核心环节之一。无论是简单的博客系统还是复杂的企业级应用,都离不开高效、安全、稳定的数据库连接。本文将系统全面地梳理网站后端连接数据库的核心知识点,从连接原理到最佳实践,涵盖 JDBC、连接池、ORM 框架、事务管理、性能优化等各个方面,帮助开发者建立完整的知识体系。
7a473eda-a084-4614-8113-45f48ec7980b.png

一、数据库连接基础

1.1 数据库连接原理

应用服务器 → 数据库驱动 → 网络连接 → 数据库服务器
     ↓            ↓           ↓           ↓
  连接请求 → 建立连接 → 传输数据 → 执行SQL → 返回结果

连接过程:
加载数据库驱动
建立网络连接(TCP/IP)
进行身份认证
创建会话
执行 SQL 语句
返回结果
关闭连接(释放资源)

1.2 数据库驱动
常用 JDBC 驱动:

xml
<!-- Maven 依赖 -->
<!-- MySQL -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.33</version>
</dependency>

<!-- PostgreSQL -->
<dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <version>42.6.0</version>
</dependency>

<!-- Oracle -->
<dependency>
    <groupId>com.oracle.database.jdbc</groupId>
    <artifactId>ojdbc8</artifactId>
    <version>21.9.0.0</version>
</dependency>

<!-- SQL Server -->
<dependency>
    <groupId>com.microsoft.sqlserver</groupId>
    <artifactId>mssql-jdbc</artifactId>
    <version>12.4.0.jre11</artifactId>
</dependency>

<!-- H2(内存数据库) -->
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>2.2.220</version>
</dependency>

1.3 JDBC 基础连接

java
import java.sql.*;

public class JDBCDemo {

    // 数据库连接参数
    private static final String URL = "jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=UTC";
    private static final String USERNAME = "root";
    private static final String PASSWORD = "123456";

    // 1. 基础连接示例
    public void basicConnection() {
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;

        try {
            // 加载驱动(可选,JDBC 4.0+ 自动加载)
            Class.forName("com.mysql.cj.jdbc.Driver");

            // 建立连接
            conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
            System.out.println("数据库连接成功");

            // 创建 Statement
            stmt = conn.createStatement();

            // 执行查询
            rs = stmt.executeQuery("SELECT * FROM users");

            // 处理结果
            while (rs.next()) {
                int id = rs.getInt("id");
                String name = rs.getString("username");
                System.out.println("ID: " + id + ", Name: " + name);
            }

        } catch (ClassNotFoundException e) {
            System.err.println("驱动加载失败: " + e.getMessage());
        } catch (SQLException e) {
            System.err.println("数据库连接失败: " + e.getMessage());
        } finally {
            // 关闭资源(顺序:ResultSet → Statement → Connection)
            try {
                if (rs != null) rs.close();
                if (stmt != null) stmt.close();
                if (conn != null) conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    // 2. PreparedStatement(防止 SQL 注入)
    public void preparedStatementExample() {
        String sql = "SELECT * FROM users WHERE username = ? AND age > ?";

        try (Connection conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
             PreparedStatement pstmt = conn.prepareStatement(sql)) {

            // 设置参数
            pstmt.setString(1, "张三");
            pstmt.setInt(2, 18);

            // 执行查询
            try (ResultSet rs = pstmt.executeQuery()) {
                while (rs.next()) {
                    System.out.println(rs.getString("username"));
                }
            }

        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    // 3. 批处理操作
    public void batchExample() {
        String sql = "INSERT INTO users (username, age) VALUES (?, ?)";

        try (Connection conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
             PreparedStatement pstmt = conn.prepareStatement(sql)) {

            // 关闭自动提交
            conn.setAutoCommit(false);

            // 添加批处理
            for (int i = 0; i < 1000; i++) {
                pstmt.setString(1, "user" + i);
                pstmt.setInt(2, 20 + i % 50);
                pstmt.addBatch();
            }

            // 执行批处理
            int[] results = pstmt.executeBatch();

            // 提交事务
            conn.commit();

            System.out.println("批量插入完成: " + results.length);

        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

二、连接池技术

2.1 为什么需要连接池
不使用连接池的问题:
每次请求都需要创建和关闭连接,开销大
高并发时数据库连接数爆炸
资源浪费,性能低下
连接池的优势:
复用连接,减少创建/销毁开销
限制最大连接数,保护数据库
管理连接生命周期
提供连接健康检查

2.2 HikariCP(推荐)

xml
<!-- Maven 依赖 -->
<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;

public class HikariCPDemo {

    // 配置方式1:编程式配置
    public DataSource createDataSource() {
        HikariConfig config = new HikariConfig();

        // 基础配置
        config.setJdbcUrl("jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=UTC");
        config.setUsername("root");
        config.setPassword("123456");

        // 连接池大小配置
        config.setMaximumPoolSize(10);           // 最大连接数
        config.setMinimumIdle(5);                // 最小空闲连接
        config.setIdleTimeout(600000);            // 空闲超时(10分钟)
        config.setConnectionTimeout(30000);       // 连接超时(30秒)
        config.setMaxLifetime(1800000);           // 连接最大生命周期(30分钟)

        // 验证配置
        config.setConnectionTestQuery("SELECT 1");
        config.setValidationTimeout(5000);

        // 其他配置
        config.setPoolName("MyHikariPool");
        config.setRegisterMbeans(true);

        return new HikariDataSource(config);
    }

    // 配置方式2:配置文件方式
    // hikari.properties
    /*
    dataSourceClassName=com.mysql.cj.jdbc.MysqlDataSource
    dataSource.url=jdbc:mysql://localhost:3306/mydb
    dataSource.user=root
    dataSource.password=123456
    maximumPoolSize=10
    minimumIdle=5
    connectionTimeout=30000
    idleTimeout=600000
    maxLifetime=1800000
    */

    public DataSource createDataSourceFromFile() {
        HikariConfig config = new HikariConfig("/hikari.properties");
        return new HikariDataSource(config);
    }
}

2.3 Druid(阿里)

xml
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.2.20</version>
</dependency>
java
import com.alibaba.druid.pool.DruidDataSource;
import javax.sql.DataSource;
import java.util.Properties;

public class DruidDemo {

    public DataSource createDataSource() {
        DruidDataSource dataSource = new DruidDataSource();

        // 基础配置
        dataSource.setUrl("jdbc:mysql://localhost:3306/mydb?useSSL=false");
        dataSource.setUsername("root");
        dataSource.setPassword("123456");

        // 连接池配置
        dataSource.setInitialSize(5);           // 初始化连接数
        dataSource.setMinIdle(5);               // 最小空闲连接
        dataSource.setMaxActive(20);             // 最大活跃连接
        dataSource.setMaxWait(60000);            // 获取连接最大等待时间

        // 连接保持配置
        dataSource.setTimeBetweenEvictionRunsMillis(60000);  // 检查空闲连接的间隔
        dataSource.setMinEvictableIdleTimeMillis(300000);    // 连接最小空闲时间
        dataSource.setMaxEvictableIdleTimeMillis(600000);    // 连接最大空闲时间

        // 验证配置
        dataSource.setValidationQuery("SELECT 1");
        dataSource.setTestWhileIdle(true);
        dataSource.setTestOnBorrow(false);
        dataSource.setTestOnReturn(false);

        // 监控配置
        dataSource.setFilters("stat,wall,log4j");  // 开启监控和防火墙

        return dataSource;
    }

    // 配置文件方式
    public DataSource createFromProperties() {
        Properties props = new Properties();
        props.setProperty("url", "jdbc:mysql://localhost:3306/mydb");
        props.setProperty("username", "root");
        props.setProperty("password", "123456");
        props.setProperty("initialSize", "5");
        props.setProperty("maxActive", "20");
        props.setProperty("minIdle", "5");

        return DruidDataSourceFactory.createDataSource(props);
    }
}

2.4 Tomcat JDBC Pool

xml
<dependency>
    <groupId>org.apache.tomcat</groupId>
    <artifactId>tomcat-jdbc</artifactId>
    <version>10.1.15</version>
</dependency>
java
import org.apache.tomcat.jdbc.pool.DataSource;
import org.apache.tomcat.jdbc.pool.PoolProperties;

public class TomcatPoolDemo {

    public DataSource createDataSource() {
        PoolProperties p = new PoolProperties();

        p.setUrl("jdbc:mysql://localhost:3306/mydb");
        p.setUsername("root");
        p.setPassword("123456");
        p.setDriverClassName("com.mysql.cj.jdbc.Driver");

        p.setInitialSize(5);
        p.setMaxActive(20);
        p.setMinIdle(5);
        p.setMaxIdle(10);
        p.setMaxWait(30000);

        p.setValidationQuery("SELECT 1");
        p.setTestOnBorrow(true);
        p.setTestWhileIdle(true);

        p.setTimeBetweenEvictionRunsMillis(60000);
        p.setMinEvictableIdleTimeMillis(300000);

        return new DataSource(p);
    }
}

三、Spring 框架中的数据库连接

3.1 配置数据源
application.yml 配置:

spring:
  datasource:
    # 基础配置
    url: jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=UTC
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver

    # HikariCP 配置
    hikari:
      maximum-pool-size: 10
      minimum-idle: 5
      connection-timeout: 30000
      idle-timeout: 600000
      max-lifetime: 1800000
      connection-test-query: SELECT 1
      pool-name: MyHikariPool

    # Druid 配置
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      initial-size: 5
      max-active: 20
      min-idle: 5
      max-wait: 60000
      filters: stat,wall,slf4j
      stat-view-servlet:
        enabled: true
        url-pattern: /druid/*
        login-username: admin
        login-password: admin

Java 配置:

@Configuration
public class DataSourceConfig {

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource dataSource() {
        return DataSourceBuilder.create().build();
    }

    // 自定义 HikariCP 配置
    @Bean
    public DataSource customDataSource() {
        HikariConfig config = new HikariConfig();
        config.setJdbcUrl("jdbc:mysql://localhost:3306/mydb");
        config.setUsername("root");
        config.setPassword("123456");
        config.setMaximumPoolSize(20);
        config.setMinimumIdle(5);
        config.setConnectionTimeout(30000);
        config.setIdleTimeout(600000);
        config.setMaxLifetime(1800000);
        return new HikariDataSource(config);
    }

    // 多数据源配置
    @Bean
    @Primary
    @ConfigurationProperties(prefix = "spring.datasource.primary")
    public DataSource primaryDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.secondary")
    public DataSource secondaryDataSource() {
        return DataSourceBuilder.create().build();
    }
}

3.2 JdbcTemplate 使用

@Repository
public class UserDao {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private NamedParameterJdbcTemplate namedParameterJdbcTemplate;

    // 查询单条记录
    public User findById(Long id) {
        String sql = "SELECT id, username, age FROM users WHERE id = ?";
        return jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(User.class), id);
    }

    // 查询列表
    public List<User> findAll() {
        String sql = "SELECT id, username, age FROM users";
        return jdbcTemplate.query(sql, (rs, rowNum) -> {
            User user = new User();
            user.setId(rs.getLong("id"));
            user.setUsername(rs.getString("username"));
            user.setAge(rs.getInt("age"));
            return user;
        });
    }

    // 插入并返回主键
    public long insert(User user) {
        String sql = "INSERT INTO users (username, age) VALUES (?, ?)";
        KeyHolder keyHolder = new GeneratedKeyHolder();

        jdbcTemplate.update(connection -> {
            PreparedStatement ps = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
            ps.setString(1, user.getUsername());
            ps.setInt(2, user.getAge());
            return ps;
        }, keyHolder);

        return keyHolder.getKey().longValue();
    }

    // 批量插入
    public int[] batchInsert(List<User> users) {
        String sql = "INSERT INTO users (username, age) VALUES (?, ?)";
        return jdbcTemplate.batchUpdate(sql, users, 100, (ps, user) -> {
            ps.setString(1, user.getUsername());
            ps.setInt(2, user.getAge());
        });
    }

    // 命名参数查询
    public List<User> findByCondition(String username, Integer age) {
        String sql = "SELECT * FROM users WHERE username = :username AND age > :age";
        MapSqlParameterSource params = new MapSqlParameterSource();
        params.addValue("username", username);
        params.addValue("age", age);

        return namedParameterJdbcTemplate.query(sql, params, new BeanPropertyRowMapper<>(User.class));
    }
}

来源:
https://dnuhf.cn/category/food.html

相关文章
|
10月前
|
机器学习/深度学习 人工智能 自然语言处理
抖音封号是什么原因造成的?
抖音封号的技术逻辑与风控体系解析
|
前端开发 JavaScript Java
网易音乐网站系统|前后端分离springboot+vue实现在线音乐网站
网易音乐网站系统|前后端分离springboot+vue实现在线音乐网站
2097 0
|
2月前
|
存储 NoSQL 安全
从单体到亿级流量:登录功能全场景设计指南,踩过的坑全给你填平了
本文系统剖析登录功能设计,按项目复杂度分四级:极简单体(Tomcat Session+BCrypt)、集群(Redis分布式会话+双令牌)、微服务(OAuth2.0统一认证中心)、高并发(多级缓存+智能风控)。强调设计须匹配业务规模,杜绝过度或缺失设计,并严守密码存储、传输、会话等八大安全红线。
248 1
|
6月前
|
关系型数据库 MySQL 数据库
如何在 Mac 上安装 MySQL 8.0.20.dmg(从下载到使用全流程,附安装包)
手把手教你通过.dmg安装包在Mac上安装MySQL 8.0.20。含下载链接、详细安装步骤及服务启动方法,图文清晰,小白也能轻松完成数据库部署。(236字符)
1079 6
|
4月前
|
人工智能 弹性计算 关系型数据库
2026年阿里云服务器热门配置最新活动价格及优惠购买指南
本文聚焦2026年阿里云服务器热门配置的性价比方案与购买策略。2核2G轻量服务器38元起,适配个人博客及初级开发;2核4G云服务器199元/年,满足初创企业官网及电商基础需求;4核8G、8核16G配置分别以898.20元、5958.52元起,适配中小型企业复杂应用及高并发场景。文章还梳理了新用户优惠、优惠券领取、组合套餐购买、续费策略等省钱技巧,助力用户通过合理规划,以最优性价比获取所需云资源,降低上云成本。
564 3
|
4月前
|
存储 Web App开发 安全
2026年网站搭建教程(详细的建站步骤)
企业网站搭建全流程:从需求分析、架构规划到域名注册、主机配置,依托PageAdmin系统完成部署与内容建设,经多维度测试后正式上线。流程覆盖前期准备、基础搭建、系统安装、内容填充及发布运维,确保网站稳定、兼容、易维护,适用于企业、政务等机构,具备强复制性与标准化指导意义。(238字)
1448 3
|
测试技术 数据安全/隐私保护 Java
基于SpringBoot+Vue+uniapp的音乐管理系统的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的音乐管理系统的详细设计和实现(源码+lw+部署文档+讲解等)
347 2
|
关系型数据库 数据库
关系型数据库设计规范第三范式(3NF)
【5月更文挑战第14天】关系型数据库设计规范第三范式(3NF)
1296 3