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

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

一般而言,使用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

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

目录
相关文章
|
4月前
|
存储 JSON 关系型数据库
【干货满满】解密 API 数据解析:从 JSON 到数据库存储的完整流程
本文详解电商API开发中JSON数据解析与数据库存储的全流程,涵盖数据提取、清洗、转换及优化策略,结合Python实战代码与主流数据库方案,助开发者构建高效、可靠的数据处理管道。
|
2月前
|
数据采集 关系型数据库 MySQL
python爬取数据存入数据库
Python爬虫结合Scrapy与SQLAlchemy,实现高效数据采集并存入MySQL/PostgreSQL/SQLite。通过ORM映射、连接池优化与批量提交,支持百万级数据高速写入,具备良好的可扩展性与稳定性。
|
3月前
|
存储 数据管理 数据库
数据字典是什么?和数据库、数据仓库有什么关系?
在数据处理中,你是否常困惑于字段含义、指标计算或数据来源?数据字典正是解答这些问题的关键工具,它清晰定义数据的名称、类型、来源、计算方式等,服务于开发者、分析师和数据管理者。本文详解数据字典的定义、组成及其与数据库、数据仓库的关系,助你夯实数据基础。
数据字典是什么?和数据库、数据仓库有什么关系?
|
7月前
|
存储 缓存 数据库
数据库数据删除策略:硬删除vs软删除的最佳实践指南
在项目开发中,“删除”操作常见但方式多样,主要分为硬删除与软删除。硬删除直接从数据库移除数据,操作简单、高效,但不可恢复;适用于临时或敏感数据。软删除通过标记字段保留数据,支持恢复和审计,但增加查询复杂度与数据量;适合需追踪历史或可恢复的场景。两者各有优劣,实际开发中常结合使用以满足不同需求。
547 4
|
3月前
|
存储 关系型数据库 数据库
【赵渝强老师】PostgreSQL数据库的WAL日志与数据写入的过程
PostgreSQL中的WAL(预写日志)是保证数据完整性的关键技术。在数据修改前,系统会先将日志写入WAL,确保宕机时可通过日志恢复数据。它减少了磁盘I/O,提升了性能,并支持手动切换日志文件。WAL文件默认存储在pg_wal目录下,采用16进制命名规则。此外,PostgreSQL提供pg_waldump工具解析日志内容。
248 0
|
5月前
|
存储 SQL Java
数据存储使用文件还是数据库,哪个更合适?
数据库和文件系统各有优劣:数据库读写性能较低、结构 rigid,但具备计算能力和数据一致性保障;文件系统灵活易管理、读写高效,但缺乏计算能力且无法保证一致性。针对仅需高效存储与灵活管理的场景,文件系统更优,但其计算短板可通过开源工具 SPL(Structured Process Language)弥补。SPL 提供独立计算语法及高性能文件格式(如集文件、组表),支持复杂计算与多源混合查询,甚至可替代数据仓库。此外,SPL 易集成、支持热切换,大幅提升开发运维效率,是后数据库时代文件存储的理想补充方案。
|
10月前
|
数据采集 数据库 Python
有哪些方法可以验证用户输入数据的格式是否符合数据库的要求?
有哪些方法可以验证用户输入数据的格式是否符合数据库的要求?
442 75
|
8月前
|
数据库 Python
【YashanDB知识库】python驱动查询gbk字符集崖山数据库CLOB字段,数据被驱动截断
【YashanDB知识库】python驱动查询gbk字符集崖山数据库CLOB字段,数据被驱动截断

热门文章

最新文章