Java MySQL 连接
JDBC 驱动、连接数据库、执行查询与 PreparedStatement 防注入。
添加驱动依赖
Java reaches databases through JDBC and a vendor driver jar. For MySQL use mysql-connector-j; one Maven dependency is enough — since JDBC 4.0 no manual Class.forName is needed.
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.3.0</version>
</dependency>
JDBC URL 示例:
jdbc:mysql://localhost:3306/testdb?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8连接数据库
DriverManager.getConnection(url, user, password) opens a connection and conn.isValid(2) checks it. In production use a pool such as HikariCP instead of connecting per request.
import java.sql.Connection;
import java.sql.DriverManager;
public class ConnectDemo {
public static void main(String[] args) throws Exception {
String url = "jdbc:mysql://localhost:3306/testdb?useSSL=false&serverTimezone=Asia/Shanghai";
String user = "root";
String pwd = "your_password";
try (Connection conn = DriverManager.getConnection(url, user, pwd)) {
System.out.println(conn.isValid(2));
System.out.println(conn.getMetaData().getDriverName());
}
}
}true
MySQL Connector/Jtestdb created. If it cannot connect you get CommunicationsException — check the service and whether port 3306 is open.执行查询
Statement runs static SQL; executeQuery returns a ResultSet you walk with next() and read via getXxx(column). Always close the result set and statement.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class QueryDemo {
public static void main(String[] args) throws Exception {
String url = "jdbc:mysql://localhost:3306/testdb?useSSL=false&serverTimezone=Asia/Shanghai";
try (Connection conn = DriverManager.getConnection(url, "root", "your_password");
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("SELECT id, name FROM sites")) {
while (rs.next()) {
System.out.println(rs.getInt("id") + " " + rs.getString("name"));
}
}
}
}1 runoob
2 pythonPreparedStatement
Parameterised SQL must use PreparedStatement with ? placeholders bound via setXxx. It prevents SQL injection, is faster thanks to precompilation, and handles quotes and dates correctly.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
public class PreparedDemo {
public static void main(String[] args) throws Exception {
String url = "jdbc:mysql://localhost:3306/testdb?useSSL=false&serverTimezone=Asia/Shanghai";
String sql = "INSERT INTO sites (name, url) VALUES (?, ?)";
try (Connection conn = DriverManager.getConnection(url, "root", "your_password");
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setString(1, "runoob");
ps.setString(2, "https://www.runoob.com");
int rows = ps.executeUpdate();
System.out.println(rows);
}
}
}1"... WHERE name='" + name + "'") is the classic injection hole. Parameterised queries are mandatory, not an optimisation.添加驱动依赖
Java 通过 JDBC 访问数据库,需要对应厂商的驱动 jar。MySQL 用 mysql-connector-j,Maven 加一行依赖即可,JDBC 4.0 起不用手动 Class.forName。
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.3.0</version>
</dependency>
JDBC URL 示例:
jdbc:mysql://localhost:3306/testdb?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8连接数据库
DriverManager.getConnection(url, user, password) 建立连接,conn.isValid(2) 可验证连接可用。生产环境应使用连接池(HikariCP),不要每次请求都新建连接。
import java.sql.Connection;
import java.sql.DriverManager;
public class ConnectDemo {
public static void main(String[] args) throws Exception {
String url = "jdbc:mysql://localhost:3306/testdb?useSSL=false&serverTimezone=Asia/Shanghai";
String user = "root";
String pwd = "your_password";
try (Connection conn = DriverManager.getConnection(url, user, pwd)) {
System.out.println(conn.isValid(2));
System.out.println(conn.getMetaData().getDriverName());
}
}
}true
MySQL Connector/Jtestdb。连不上会抛 CommunicationsException,先检查服务是否启动、端口 3306 是否放行。执行查询
Statement 执行静态 SQL,executeQuery 返回 ResultSet,用 next() 逐行移动、getXxx(列名) 取值。查询完必须关闭结果集与语句。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class QueryDemo {
public static void main(String[] args) throws Exception {
String url = "jdbc:mysql://localhost:3306/testdb?useSSL=false&serverTimezone=Asia/Shanghai";
try (Connection conn = DriverManager.getConnection(url, "root", "your_password");
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("SELECT id, name FROM sites")) {
while (rs.next()) {
System.out.println(rs.getInt("id") + " " + rs.getString("name"));
}
}
}
}1 runoob
2 pythonPreparedStatement
带参数的 SQL 必须用 PreparedStatement 加 ? 占位符,setXxx 绑定值。它既能防 SQL 注入,又因为预编译而更快,还能正确处理引号和日期。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
public class PreparedDemo {
public static void main(String[] args) throws Exception {
String url = "jdbc:mysql://localhost:3306/testdb?useSSL=false&serverTimezone=Asia/Shanghai";
String sql = "INSERT INTO sites (name, url) VALUES (?, ?)";
try (Connection conn = DriverManager.getConnection(url, "root", "your_password");
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setString(1, "runoob");
ps.setString(2, "https://www.runoob.com");
int rows = ps.executeUpdate();
System.out.println(rows);
}
}
}1"... WHERE name='" + name + "'")是最典型的注入漏洞来源。参数化查询不是「可选优化」,而是必须。