一、JDBC基础概念
JDBC 是Java 中的一组API,用于执行SQL 操作(例如CRUD 操作:增、删、改、关系),同时可以和各种类型的数据库类型进行连接(MySQL、Oracle、SQL Server 等)。 JDBC是Java标准库的一部分,提供了与数据库进行交互的抽象接口。
JDBC主要包含以下几个核心组件:
- Driver(驱动程序):这是用于连接Java应用程序和数据库的接口。多数数据库(如MySQL、Oracle、PostgreSQL等)都有自己特定的JDBC驱动程序。
- Connection(连接):Connection对象代表一个Java程序与数据库的连接。
- Statement(语句):用于执行SQL查询。
- ResultSet(结果集):存储从数据库查询的结果。
- SQLException(异常):处理数据库操作中可能出现的异常。
二、使用MySQL JDBC的步骤
要通过JDBC连接MySQL,主要步骤如下:
-
添加MySQL JDBC驱动:
-
-
创建Maven模块
首先需要下载MySQL JDBC驱动(mysql-connector-java.jar
),然后将其添加到Java项目中。 - 如果使用Maven管理依赖,可以在
pom.xml
中添加依赖: -
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.26</version>
</dependency> -
当我们有这两个包名出现后,就说明我们的MySQL JDBC驱动已经下好了
-
2. JDBC连接MySQL的基本步骤
1.加载MySQL JDBC驱动程序
JDBC驱动程序通常是一个外部JAR包。在项目中,可以通过下载MySQL的Connector/J包并添加到项目的类路径中。加载驱动程序的代码通常如下:
Class.forName("com.mysql.cj.jdbc.Driver");
2.创建数据库连接
使用DriverManager.getConnection()
方法获取数据库连接。该方法需要数据库的URL、用户名和密码。URL通常为jdbc:mysql://
,后面连接数据库服务器的地址和数据库名。
String url = "jdbc:mysql://localhost:3306/mydatabase"; // 数据库URL
String user = "root"; // 数据库用户名
String password = "password"; // 数据库密码
Connection conn = DriverManager.getConnection(url, user, password);
或
String url = "jdbc:mysql://localhost:3306/dbname?useSSL=false&serverTimezone=UTC";
Connection conn = DriverManager.getConnection(url, "username", "password");
红色:为要操作数据库的名字
蓝色:自己操作的话,为root
绿色:自己开启数据库的密码
3. 创建Statement对象
在建立连接后,创建Statement
对象来执行SQL语句。
Statement stmt = conn.createStatement();
4. 执行SQL查询
使用Statement
对象的executeQuery()
方法执行查询语句,并使用executeUpdate()
执行更新语句。
5. 处理结果
返回查询的结果会存储在ResultSet
对象中,通过遍历ResultSet
获取数据。
结果展示:
小编这里不知道MessageFormat.format的用法所以在网上找了点资料,如果会的可以不用看:
MessageFormat.format字段介绍:
MessageFormat.format的主要用途
-
动态生成带变量的字符串:带有占位(即
{0}
,{1}
,{2}
, ...)的字符串模板和参数进行匹配,并输出格式化后的字符串。 -
国际化和本地化:在多语言环境中,
MessageFormat
能够自动处理本地化格式(如日期、数字、货币),适应不同语言和区域的标准。 -
安全插值:使用
MessageFormat
时,避免了简单的字符串粘贴可能带来的代码差异性差、安全性低的问题(如SQL注入),提供了更安全和清晰的插值方式。
基本用法
MessageFormat.format
方法接受两个参数:
- 第一个参数:格式化字符串(模板),指定了如何插入数据,并通过
{0}
,{1}
,{2}
, 等形式代表占位符。 - 第二个参数:一组数据,以队列形式提供,每个数据会对应模板中的占位符。
示例:
import java.text.MessageFormat;
public class MessageFormatExample {
public static void main(String[] args) {
String template = "Hello, {0}. Today is {1}. You have {2} new messages.";
// 插入的数据
String name = "Alice";
String date = "2024-11-13";
int messages = 5;
// 使用 MessageFormat.format 生成动态字符串
String message = MessageFormat.format(template, name, date, messages);
System.out.println(message);
// 输出: Hello, Alice. Today is 2024-11-13. You have 5 new messages.
}
}
上面的要点:
{0}
,{1}
,{2}
是模板中的占位符,依次会被name
、date
、messages
替换。MessageFormat.format
自动将messages
的整数值替换为字符串并插入到模板中。
日期、数字等格式化
MessageFormat
还支持特殊格式,如日期和数字。可以在占位符中指定格式化方式,例如date
和number
:
import java.text.MessageFormat;
import java.util.Date;
String template = "At {0,time,short} on {0,date,long}, we received {1,number,integer} messages.";
Date now = new Date();
int messageCount = 5;
String result = MessageFormat.format(template, now, messageCount);
System.out.println(result);
// 输出类似:At 3:30 PM on January 1, 2022, we received 5 messages.
这里{0,time,short}
指定时间格式为短格式,{0,date,long}
指定日期格式为长格式,而{1,number,integer}
将整数消息抽样为无小数位的整数。
示例3:结合国际化(资源文件)
在国际化中,可以将多语言模板存储在资源文件中,再使用MessageFormat.format
进行格式化。例如:
想象在资源文件messages_en.properties
中包含以下内容:
welcome.message = Hello {0}, you have {1} new messages!
使用时可以这样处理:
import java.util.ResourceBundle;
ResourceBundle messages = ResourceBundle.getBundle("messages", Locale.ENGLISH);
String template = messages.getString("welcome.message");
String result = MessageFormat.format(template, "Alice", 5);
System.out.println(result);
// 输出:Hello Alice, you have 5 new messages!
注意事项
转义大惯例:如果模板中需要使用花逗号{
或}
,需要进行转义,即写成'{'
或'}'
,例如:
String template = "This is a brace: '{{' and '}}'";
String result = MessageFormat.format(template);
// 输出:This is a brace: { and }
-
参数顺序:
MessageFormat.format
会严格按顺序匹配{0}
,{1}
,{2}
, 等占位符。 -
参数数量:如果参数数量与占位符不符,会发送异常或产生不完整输出。
6. 关闭资源
在完成所有数据库操作后,必须关闭连接、语句和结果集,才能释放资源。
3. 使用PreparedStatement
PreparedStatement
是的Statement
子接口,用于执行预编译的SQL语句,可以防止SQL注入,提高查询效率。使用示例如下:
String query = "SELECT * FROM users WHERE id = ?";
PreparedStatement pstmt = conn.prepareStatement(query);
pstmt.setInt(1, 1); // 设置查询条件
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
int id = rs.getInt("id");
String name = rs.getString("name");
System.out.println("ID: " + id + ", Name: " + name);
}
rs.close();
pstmt.close();
4. JDBC常用操作
插入数据
String insert = "INSERT INTO users (name, email) VALUES (?, ?)";
PreparedStatement pstmt = conn.prepareStatement(insert);
pstmt.setString(1, "Alice");
pstmt.setString(2, "[email protected]");
int rows = pstmt.executeUpdate();
System.out.println("Inserted rows: " + rows);
pstmt.close();
更新数据:
String update = "UPDATE users SET email=? WHERE name=?";
PreparedStatement pstmt = conn.prepareStatement(update);
pstmt.setString(1, "[email protected]");
pstmt.setString(2, "Alice");
int rows = pstmt.executeUpdate();
System.out.println("Updated rows: " + rows);
pstmt.close();
删除数据
String delete = "DELETE FROM users WHERE name=?";
PreparedStatement pstmt = conn.prepareStatement(delete);
pstmt.setString(1, "Alice");
int rows = pstmt.executeUpdate();
System.out.println("Deleted rows: " + rows);
pstmt.close();
5. 异常处理
在JDBC编程中,推荐使用try-catch-finally来处理数据库连接。可以使用SQLException
捕获和处理数据库操作中的异常。
try {
// 创建数据库连接和执行操作
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 关闭连接
}
6. JDBC事务管理
默认情况下,每个SQL操作都是自动提交的。为了保证多步操作的原子性,可以使用事务管理。可以通过设置自动提交为false
,然后在操作结束时手动提交或回滚。
conn.setAutoCommit(false);
try {
// 执行多个更新操作
conn.commit(); // 手动提交
} catch (SQLException e) {
conn.rollback(); // 出现异常时回滚
e.printStackTrace();
} finally {
conn.setAutoCommit(true); // 恢复自动提交
}
7. JDBC性能优化
- 使用连接池:使用数据库连接池(如HikariCP、C3P0等)来管理连接,减少创建和库存连接的开支。
- 批量操作:对于批量插入和更新,可以使用批量操作来提高效率。
- 预编译语句存储:
PreparedStatement
可以重复使用相同的SQL语句,减少编译开销。 - 索引优化:合理使用数据库索引,确保查询速度更快。