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