使用数据连接池进行数据库操作

简介: 使用数据连接池进行数据库操作

一般而言,使用Java访问MySQL的方法如下。

public Connection connect() throws SQLException{
   
try{
   
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection conn=DriverManager.getConnection(url,user,password);
        stmt=conn.createPreparedStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
return conn;
    }catch(ClassNotFoundException e){
   
        System.out.println("JDBC Driver not found:"+e.getMessage());
    }catch(SQLException e){
   
        System.out.println("Database connection failed:"+e.getMessage());
    }
return null;
}

public void disconnect(Connection conn){
   
try{
   
if(conn!=null){
   
            conn.close();
        }
    }catch(Exception e){
   
        System.out.println(e.getMessage());
    }
}

public void closeStmt(PreparedStatement stmt){
   
try{
   
if(stmt!=null){
   
            stmt.close();
        }
    }catch(Exception e){
   
        System.out.println(e.getMessage());
    }
}

public void closeRS(ResultSet rs){
   
try{
   
if(rs!=null){
   
            rs.close();
        }
    }catch(Exception e){
   
        System.out.println(e.getMessage());
    }
}


//用户登录时验证数据库中是否存在该用户及其密码是否正确
public String login(Connection conn,User user)throws SQLException{
   
    String username=user.getUsername();
    String password=user.getPassword();
    PreparedStatement stmt=null;
    ResultSet rs=null;
try{
   
        String queryString="SELECT * FROM user WHERE username=? AND password=?";
        stmt=conn.preparePreparedStatement(queryString);
        stmt.setString(1,username);
        stmt.setString(2,password);
        rs=stmt.executeQuery();        
if(!rs.next()){
   
return "0";
        }else{
   
return "1";
        }
    }catch(SQLException e){
   
        Sysyem.out.println(e.getMessage());
    }finally{
   
try{
   
            closeRS(ResultSet rs);
            closeStmt(PreparedStatement stmt);
        }catch(SQLException e){
   
            Sysyem.out.println(e.getMessage());
        }
    }
return "-1";
}

Connection connect()用于建立数据库连接

void disconnect(Connection conn)用于断开数据库连接

void closeStmt(PreparedStatement stmt)用于关闭PreparedStatement

void closeRS(ResultSet rs)用于关闭ResultSet

程序使用完毕必须关闭Connection、PreparedStatement和ResultSet,否者会造成内存溢出。并且关闭顺序必须是先关闭ResultSet,接下来是PreparedStatement,最后是Connection。Java建议使用数据库连接池来对数据库操作,它的好处可以在网上查到。这里我们使用HikariCP。使用数据库连接词,必须先配置pom.xml

<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>5.0.1</version><!--请根据需要选择最新版本-->
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.27</version><!--请根据需要选择适合的 JDBC 驱动-->
</dependency>
<!--SLF4J API-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.36</version>
</dependency>
<!--Logback实现-->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.11</version>
</dependency>

配置HikariCP

你可以在Java代码中或者在配置文件(如application.properties或application.yml)中进行配置。以下是两种方式的示例。

Java代码配置示例。

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

public class DataSourceConfig{
   
private HikariDataSource dataSource;
public DataSourceConfig(){
   
        HikariConfig config=new HikariConfig();
        config.setJdbcUrl("jdbc:mysql://localhost:3306/your_database");//替换为你的数据库URL
        config.setUsername("your_username");//数据库账号
        config.setPassword("your_password");//数据库密码
        config.setDriverClassName("com.mysql.cj.jdbc.Driver");//JDBC 驱动类名

//HikariCP 相关配置
        config.setMaximumPoolSize(10);//最大连接数
        config.setMinimumIdle(2);//最小空闲连接数
        config.setIdleTimeout(30000);//空闲连接最大存活时间
        config.setConnectionTimeout(30000);//连接超时时间
        dataSource=new HikariDataSource(config);
    }
public HikariDataSource getDataSource(){
   
return dataSource;
    }
}

使用HikariCP连接数据库

private HikariDataSource dataSource;
public UserService(HikariDataSource dataSource){
   
this.dataSource=dataSource;
    }
public boolean deleteUser(String username){
   
String sql="DELETE FROM user WHERE username=?";
try(Connection connection=dataSource.getConnection();
            PreparedStatement ps=connection.preparePreparedStatement(sql)){
   
            ps.setString(1,username);
            int affectedRows=ps.executeUpdate();
return affectedRows==1;
        }catch(SQLException e){
   
            logger.error(e.getMessage());
return false;
        }
    }

public String login(Connection conn,User user)throws SQLException{
   
String queryString="SELECT * FROM user WHERE username=? AND password=?";
try{
   
Connection connection=dataSource.getConnection();
try{
   
PreparedStatement ps=connection.preparePreparedStatement(queryString);
            stmt=conn.preparePreparedStatement(queryString);
            stmt.setString(1,username);
            stmt.setString(2,password);
            rs=stmt.executeQuery();
if(!rs.next()){
   
return "0";
            }else{
   
return "1";
            }
        }
    }catch(SQLException e){
   
Sysyem.out.println(e.getMessage());
    }finally{
   
try{
   
closeRS(ResultSet rs);
closeStmt(PreparedStatement stmt);
        }catch(SQLException e){
   
Sysyem.out.println(e.getMessage());
        }
    }
return "-1";
}

关闭HikariCP

在应用程序关闭时,确保关闭Hikari连接池以释放资源。

dataSource.close();

可以将关闭连接池封装方法

//关闭连接池
public void closePool(HikariDataSource dataSource){
   
if(dataSource!=null){
   
        dataSource.close();
    }
}

接下来我们看看如何在程序中使用数据库连接池

private void validatePass(User user,String info,String username)throws SQLException,IOException{
   
    UserRepository mysql=new UserRepository();
    HikariDataSource dataSource=mysql.dataSource;
try{
   
if(mysql.login(user).equals("0")){
   }else{
   }
    }catch(Exception e){
   ;
    }finally{
   
        mysql.closePool(dataSource);
    }
}

数据库的配置与操作放在UserRepository类中,通过

HikariDataSource dataSource=mysql.dataSource;

获取dataSource,接下来调用对数据库的操作,比如这里mysql.login(user),最后记得一定要在finally块中把dataSource关掉。

我们如果在程序中忘记关闭ResultSet、PreparedStatement、connection、HikariDataSource就会带来内存溢出。但是如果我们使用try-with-resources结构就可以在程序完毕,自动关闭这些对象。

// 登录
    public String login(User user) throws SQLException {
   
        String username = user.getUsername();
        String password = user.getPassword();
        String queryString = "SELECT COUNT(*) as sum FROM user WHERE username=? AND password=?";        
        try (Connection conn = dataSource.getConnection();
            PreparedStatement stmt = conn.preparePreparedStatement(queryString)) {
   
                stmt.setString(1, username);
                stmt.setString(2, password);
                try (ResultSet rs = stmt.executeQuery()) {
   
                    if (rs.next()) {
   
                        int result = rs.getInt("sum");
                        if (result == 0) {
   
                            logger.error("登录失败");
                            return "0";
                        } else {
   
                            logger.info("登录成功");
                            return "1";
                        }
                    }
                }
            } catch (SQLException e) {
   
                logger.error("login(User user) 发生数据库错误: " + e.getMessage());
            }
        return "-1";
    }

这里

try (Connection conn = dataSource.getConnection();
            PreparedStatement stmt = conn.preparePreparedStatement(queryString)) {
   
                stmt.setString(1, username);
                stmt.setString(2, password);
                try (ResultSet rs = stmt.executeQuery()) {
   

                }//这里自动关闭ResultSet rs
}//这里自动关闭PreparedStatement和Connection。

调用的时候

UserRepository mysql = new UserRepository();
try(HikariDataSource dataSource = mysql.dataSource) {
   } catch (Exception e) {
   }//这里自动关闭HikariDataSource dataSource

顾翔凡言:人工智能未来的发展瓶颈在于对知识的更新。唯一不变的是变化,知识发生了变化,人工智能软件能否及时跟进变化,可能阻碍人工智能的使用。

目录
相关文章
|
3天前
|
人工智能 运维 安全
|
1天前
|
人工智能 异构计算
敬请锁定《C位面对面》,洞察通用计算如何在AI时代持续赋能企业创新,助力业务发展!
敬请锁定《C位面对面》,洞察通用计算如何在AI时代持续赋能企业创新,助力业务发展!
|
8天前
|
人工智能 JavaScript 测试技术
Qwen3-Coder入门教程|10分钟搞定安装配置
Qwen3-Coder 挑战赛简介:无论你是编程小白还是办公达人,都能通过本教程快速上手 Qwen-Code CLI,利用 AI 轻松实现代码编写、文档处理等任务。内容涵盖 API 配置、CLI 安装及多种实用案例,助你提升效率,体验智能编码的乐趣。
767 109
|
3天前
|
机器学习/深度学习 传感器 算法
Edge Impulse:面向微型机器学习的MLOps平台——论文解读
Edge Impulse 是一个面向微型机器学习(TinyML)的云端MLOps平台,致力于解决嵌入式与边缘设备上机器学习开发的碎片化与异构性难题。它提供端到端工具链,涵盖数据采集、信号处理、模型训练、优化压缩及部署全流程,支持资源受限设备的高效AI实现。平台集成AutoML、量化压缩与跨硬件编译技术,显著提升开发效率与模型性能,广泛应用于物联网、可穿戴设备与边缘智能场景。
171 127
|
3天前
|
算法 Python
【轴承故障诊断】一种用于轴承故障诊断的稀疏贝叶斯学习(SBL),两种群稀疏学习算法来提取故障脉冲,第一种仅利用故障脉冲的群稀疏性,第二种则利用故障脉冲的额外周期性行为(Matlab代码实现)
【轴承故障诊断】一种用于轴承故障诊断的稀疏贝叶斯学习(SBL),两种群稀疏学习算法来提取故障脉冲,第一种仅利用故障脉冲的群稀疏性,第二种则利用故障脉冲的额外周期性行为(Matlab代码实现)
230 152
|
5天前
|
Java 数据库 数据安全/隐私保护
Spring 微服务和多租户:处理多个客户端
本文介绍了如何在 Spring Boot 微服务架构中实现多租户。多租户允许单个应用实例为多个客户提供独立服务,尤其适用于 SaaS 应用。文章探讨了多租户的类型、优势与挑战,并详细说明了如何通过 Spring Boot 的灵活配置实现租户隔离、动态租户管理及数据源路由,同时确保数据安全与系统可扩展性。结合微服务的优势,开发者可以构建高效、可维护的多租户系统。
212 127
|
4天前
|
机器学习/深度学习 存储 资源调度
CMSIS-NN:ARM Cortex-M处理器的高效神经网络内核——论文解读
CMSIS-NN是专为ARM Cortex-M系列微控制器优化的神经网络计算内核库,旨在支持资源受限的物联网边缘设备进行高效的深度学习推理。该库通过对卷积、池化、全连接层等关键操作进行定点量化、SIMD指令优化和内存布局调整,显著提升了模型在嵌入式设备上的运行效率。实验表明,CMSIS-NN在Cortex-M7处理器上的推理速度比基准实现提升了近5倍,大幅降低了功耗,为边缘AI应用提供了可行的技术路径。
224 128