当我学了一门Java语言后,往往会产生一些疑问,比方说,方法中的一些变量、对象实列这样的数据,会被存放在JVM中的堆内存或栈内存中。一旦调用完方法后,这些数据就会被垃圾回收机制回收。这让我产生了一些叛逆心理,我不想将这些数据存进内存中,内存中的数据是转瞬即逝的。或有一些关键数据需要某种存贮方式,可以保存相当长的时间。这样,在我想要调用的时候我就能够调用出来。
之后,我接触到了数据库。数据库会把数据存放到磁盘中,这恰恰是我想要的。数据可以在磁盘中存储相当长的时间,而当我想要用数据的时候,数据库就会将磁盘中的一部分数据调用到内存中。
现在又有一个疑问了,我要如何通过Java语言来调用或连接数据库呢?由此JDBC应运诞生了。
什么是JDBC
JDBC全称Java Database Connectivity ,由Oracle公司准确说是sun公司开发的一套标准API。(sun公司早在2009年被Oracle公司收购)为了实现这套接口,数据库公司写出了数据驱动程序,从而能连接他们的数据库。
JDBC调用步骤
1、加载JDBC驱动程序
Class.forName(“com.mysql.cj.jdbc.Driver”); // 手动加载MySQL JDBC驱动
2、建立数据库连接
String url = “jdbc:mysql://localhost:3306/mydatabase”;
String user = “root”;
String password = “password”;
Connection conn = DriverManager.getConnection(url, user, password);
3、创建Statement
或PreparedStatement
Statement stmt = conn.createStatement();
或者:
String sql = “SELECT * FROM employees WHERE id = ?”;
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, 101); // 设置SQL查询中的参数
4、执行sql语句
ResultSet rs = stmt.executeQuery(“SELECT * FROM employees”);//返回一个结果集
或者:
int rowsAffected = pstmt.executeUpdate(); // 返回受影响的行数
5、处理查询结果
while (rs.next()) {
int id = rs.getInt(“id”);
String name = rs.getString(“name”);
// 处理数据
}
6、捕获sql异常
try {
// 数据库操作
} catch (SQLException e) {
e.printStackTrace();
}
7、关闭数据库相关连接和相关资源
try {
if (rs != null) rs.close();
if (stmt != null) stmt.close();
if (conn != null) conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
8、事务管理(可选)
conn.setAutoCommit(false); // 关闭自动提交
try {
stmt.executeUpdate(“UPDATE employees SET salary = salary + 100 WHERE id = 101”);
stmt.executeUpdate(“UPDATE employees SET salary = salary + 200 WHERE id = 102”);
conn.commit(); // 提交事务
} catch (SQLException e) {
conn.rollback(); // 回滚事务
}
JDBC API 详解
DriverManager
1、注册驱动
Class.forName("com.mysql.jdbc.Driver");//DriverManager 会自动加载并注册数据库驱动,通常在加载类时会执行,例如通过 Class.forName("com.mysql.cj.jdbc.Driver") 进行手动注册。
注意:从 JDBC 4.0 开始,DriverManager 会自动加载已注册的驱动,因此不再需要显式调用 Class.forName() 来加载驱动。
2、获取数据库连接
Static Connection =DriverManager.getConnection(String url,String user,String password) //获取数据库连接
参数:
url=”jdbc:mysql://ip地址(域名):端口号/数据库名称?参数键值对1&参数键值对2…
user=”用户名”
password=”密码“
示例:

Connection
1、获取sql执行对象
普通sql执行对象:Statement createStatement()
预编译sql执行对象:PreparedStatement prepareStatement(sql)
执行存储过程的对象:CallableStatement prepareCall(sql)
2、管理事务
开启事务:setAutoCommit(boolean autoCommit) //true 为自动提交事务:false为手动提交事务,即开启事务
提交事务:commit()
回滚事务:rollback()
示例:

Statement
执行sql语句
int executeUpdate(sql) //执行DML、DDL语句,返回DML语句影响的行数,DDL执行成功后可能会返回0


ResultSet executeQuery(sql) //执行DQL语句,返回ResultSet结果集对象
ResultSet
封装DQL语句查询结果
ResultSet statement.executeQuery(sql) //返回结果集
调用查询结果的方法:
boolean next() //从当前位置向前移动一位,并判断当前行是否有效;返回值为true,有效,反之亦然。
XXX getXXX() //获取相应数据
数据类型如:int getint(参数),String getString(参数)…
参数:int 列的编号,从1开始
String 列的名称

PreparedStatement
预编译sql语句,防止sql注入
SQL 注入是一种常见的网络安全漏洞,攻击者通过在应用程序的输入字段中插入恶意 SQL 代码,从而篡改或执行未经授权的数据库操作。
比如:
SELECT * FROM users WHERE id = '' OR '1'='1'; //这个注入使条件永远为真,导致查询返回所有用户记录。
1、获取PreparedStatement对象
String sql =”select * from user where username=? and password =?”; //使用?占位符来替换sql语句中的参数值
PreparedStatement pstmt=conn.prepareStatement(sql) //通过Connection对象获取,并传入sql语句
2、设置参数值
PreparedStatement 对象 :setXXX(参数1,参数2)//给?复制
XXX:数据类型:如setString(参数1,参数2)
参数:参数1:?的位置编号,从1开始
参数2:?的值
执行sql语句
executeUpdate();
executeQuery();//不需要传递参数了

现在我们已经掌握了如何正确跟数据库建立连接了。现在我有个疑问,已知一个人想要通过java访问数据库时,我们就需要跟数据库建立一个连接。用完之后,再关闭数据库连接。若是同时有大量的人群想要通过java访问数据库时,我们就需要跟这些人群数目一一对应建立连接,然后等他们使用完之后,再一个一个关闭数据库连接。随着连接数目的不断增加,若是达到数据库最大连接限度,这会不会造成数据库负载过高或直接导致系统崩溃呢?
由此数据库连接池应运而生了。
数据库连接池
数据库连接池(Database Connection Pool)是一个用于管理数据库连接的技术,它通过预先建立和管理一定数量的数据库连接,供应用程序复用。连接池的核心思想是避免每次数据库操作时都建立新的连接,而是从池中获取已经存在的连接,使用完后再将连接归还池中。这样可以显著提高数据库操作的性能,减少创建和销毁连接的开销。
主要概念
- 连接池:是一个包含一定数量数据库连接的容器。池中的连接可以被多个应用程序共享,避免了频繁的连接创建和销毁操作。
- 连接复用:应用程序每次请求连接时,不是重新创建新的连接,而是从池中获取一个空闲连接。操作完成后,连接会被归还池中。
- 连接回收:每个连接在使用完后要被归还给连接池,连接池会管理连接的生命周期,确保连接不会泄漏。
- 最大连接数:连接池设置的最大连接数量,用来限制并发请求中最多可用的数据库连接数。
- 最小连接数:连接池设置的最小连接数量,保证连接池中有一定数量的连接,避免每次请求都需要创建连接。
在这里,我采用阿里巴巴开源的数据库连接池Druid
Druid使用步骤
1、导入Druid的jar包
手动下载druid的jar包,导入到lib目录下
2、定义配置文件

3、加载配置文件
Properties pro=new Properties();
pro.load(new FileInputStream(“src/com/itxiaochen/jdbc/druid.properties”));
4、获取连接池对象
DataSource dataSource = DruidDataSourceFactory.createDataSource(pro);
5、获取连接
Connection connection = dataSource.getConnection();
留言