JDBC
JDBC,全称Java Database Connectivity,它是一个用于Java编程语言的应用程序接口(API),定义了客户端如何访问数据库,是一个基于Java的数据访问技术,用于Java数据库连接。
JDBC的功能
它允许用户通过不同的实现来加载和注册正确的Java包,并使用JDBC驱动程序管理器作为创建JDBC连接的工厂。JDBC连接支持创建和执行语句。这些语句可以是更新语句,如SQL的CREATE, INSERT, UPDATE和DELETE,也可以是查询语句,如SELECT。此外,还可以通过JDBC连接调用存储过程。
JDBC使用以下类之一来表示语句:
- Statement – 每次都将语句发送到数据库服务器。
- PreparedStatement – 语句被缓存,然后在数据库服务器上预先确定执行路径,允许以高效的方式多次执行。
- CallableStatement – 用于执行存储过程。
JDBC编程步骤包括:
- 加载驱动程序:Class.forName(driverClass)
- 获得数据库连接:DriverManager.getConnection(url, user, password)
- 创建Statement/PreparedStatement对象:conn.createStatement() 或 conn.prepareStatement(sql)
- 执行SQL语句:stmt.executeQuery(sql) 或 stmt.executeUpdate(sql) 或 pstmt.execute()
- 处理结果集:ResultSet rs = stmt.executeQuery(sql) 或 int n = stmt.executeUpdate(sql)
- 关闭资源:rs.close(), stmt.close(), pstmt.close(), conn.close() //按照打开的顺序逆序关闭
预先准备
在使用JDBC之前我们需要下载MySQL并进行导包
Java MySQL Connector/J 包下载详见:MySQL Connector/J
1.将下载的jar包拖进lib文件夹中,右键->Add as library->OK
2.在MySQL中创建一个table
示例
import java.sql.*;
public class JDBCTest {
public static final String URL = "jdbc:mysql://127.0.0.1:3306/school";
public static final String USER = "root";
public static final String PASSWORD = "111111";
public static final String DRIVER = "com.mysql.jdbc.Driver";
public static Connection connection;
public static Statement statement;
public static ResultSet resultSet;
public static void main(String[] args) throws SQLException {
try{
//1.加载驱动程序
Class.forName(DRIVER);
System.out.println("数据库驱动加载成功!");
//2.获取数据库连接
connection = DriverManager.getConnection(URL,USER,PASSWORD);
//3.获取数据库操作对象
statement = connection.createStatement();
System.out.println("数据库连接成功!");
//4.SQL语句
ResultSet resultSet = statement.executeQuery("select * from student");
while(resultSet.next()) {
int id = resultSet.getInt(1);
String name = resultSet.getString(2);
String gender = resultSet.getString(3);
int age = resultSet.getInt(4);
System.out.println("id:" + id + ", name:" + name + ", gender:" + gender + ", age:" + age);
}
//5.完成所有操作,关闭所有连接,谁先用谁先关闭
} catch(Exception e) {
e.printStackTrace();
} finally {
statement.close();
connection.close();
}
}
}
输出结果:
数据库驱动加载成功!
数据库连接成功!
id:1, name:Tom, gender:male, age:12
id:2, name:Lowell, gender:male, age:20
id:3, name:Frank, gender:male, age:36
封装JDBCUtils类
因为每次查询都要重新写配置文件,因此我们将配置文件封装起来,在src下创建db.properties配置文件,写入配置项
同时也将JDBC代码封装
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
public class JDBCUtils {
private static String driver;
private static String url;
private static String user;
private static String password;
//通过静态代码块,来预先处执行读取配置文件的配置项,做预处理
static {
try{
JDBCUtils.class.getClassLoader();
//读取配置文件
InputStream inputStream = ClassLoader.getSystemResourceAsStream("db.properties");
//加载对象
Properties properties = new Properties();
properties.load(inputStream);
//读取配置项
driver = properties.getProperty("driver");
url = properties.getProperty("url");
user = properties.getProperty("user");
password = properties.getProperty("password");
} catch(Exception e) {
e.printStackTrace();
}
}
//测试是否加载成功
public static void Test() {
System.out.println("load success");
}
//创建单例,获取配置项
public static Connection getConnetion() throws SQLException {
return DriverManager.getConnection(url,user,password);
}
//释放,关闭结果,关闭仓库,关闭数据库连接
public static void close(Connection connection, Statement statement) throws SQLException {
if(statement != null) {
statement.close();
}
if(connection != null) {
connection.close();
}
}
public static void close(Connection connection, Statement statement, ResultSet resultSet) throws SQLException {
if(statement != null) {
statement.close();
}
if(connection != null) {
connection.close();
}
if(resultSet != null) {
resultSet.close();
}
}
}
创建测试类,测试是否能够成功加载
import com.goole.util.JDBCUtils;
public class JDBCUtilsDemo {
public static void main(String[] args) {
JDBCUtils.Test();
}
输出结果:
load success
executeUpdate()实现增删改
示例
package com.jdbc;
import com.goole.util.JDBCUtils;
import org.junit.Test;
import java.sql.*;
public class JDBCUtilsDemo {
public Connection connection;
public Statement statement;
@Test
public void insertTest() throws SQLException {
try{
connection = JDBCUtils.getConnetion();
statement = connection.createStatement();
//System.out.println("connection = " + connection);
String sql = "insert into student(id,name) values(15,'Tin')";
int res = statement.executeUpdate(sql);
if(res > 0) {
System.out.println("Insert successfully!");
}
}catch(Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.close(connection,statement);
}
}
@Test
public void updateTest() throws SQLException {
try{
connection = JDBCUtils.getConnetion();
statement = connection.createStatement();
System.out.println("connection = " + connection);
String sql = "update student set name = 'Jerry' where id = '11'";
int res = statement.executeUpdate(sql);
if(res > 0) {
System.out.println("Update successfully!");
}
}catch(Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.close(connection,statement);
}
}
@Test
public void deleteTest() throws SQLException {
try{
connection = JDBCUtils.getConnetion();
statement = connection.createStatement();
System.out.println("connection = " + connection);
String sql = "delete from student where id = '10'";
int res = statement.executeUpdate(sql);
if(res > 0) {
System.out.println("Delete successfully!");
}
}catch(Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.close(connection,statement);
}
}
@Test
public void selectTest() throws SQLException {
try{
connection = JDBCUtils.getConnetion();
statement = connection.createStatement();
System.out.println("connection = " + connection);
String sql = "select * from student";
ResultSet res = statement.executeQuery(sql);
while(res.next()) {
int id = res.getInt(1);
String name = res.getString(2);
String gender = res.getString(3);
int age = res.getInt(4);
System.out.println("id:" + id +", name:" + name + ", gender:" + gender + ", age:" + age);
}
}catch(Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.close(connection,statement);
}
}
}
增删改结果:
查询结果:
connection = com.mysql.jdbc.JDBC4Connection@6e509ffa
id:1, name:Tom, gender:male, age:12
id:2, name:Lowell, gender:male, age:20
id:3, name:Frank, gender:male, age:36
id:8, name:Jim, gender:female, age:25
id:11, name:Jerry, gender:null, age:0
id:15, name:Tin, gender:null, age:0
id:37, name:, gender:null, age:0
PreparedStatement和问号占位符
什么是PreparedStatement?
preparedstatement是一个接口,它表示一个预编译的SQL语句。它可以提高SQL语句的执行效率,增加代码的可读性,防止SQL注入攻击,以及方便地设置参数值。
SQL注入攻击是一种利用Web应用程序中存在的安全漏洞,通过在输入框中插入恶意的SQL代码,从而实现对数据库的非法操作。
要使用preparedstatement,你需要先通过Connection对象的prepareStatement方法创建一个preparedstatement对象,并传入一个包含占位符(?) 的SQL语句。然后,你可以通过setXXX方法为每个占位符设置对应的值,其中XXX表示参数的数据类型,如setInt, setString等。最后,你可以通过executeQuery或executeUpdate方法执行SQL语句,并返回ResultSet或int值。
例如,如果你想查询员工表中ID为1001的员工的信息,你可以这样写:
PreparedStatement ps = con.prepareStatement("select * from Employee where ID = ?");
ps.setInt(1, 1001);
ResultSet rs = ps.executeQuery();
这样,你就不需要拼接字符串来构造SQL语句,也不需要担心ID的值是否包含特殊字符或关键字。
将之前所有的Statement类型改为PreparedStatement类型
package com.jdbc;
import com.goole.util.JDBCUtils_PreparedStatement;
import java.sql.ResultSet;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Scanner;
public class JDBCUtilsDemo_1 {
public static Connection connection;
public static PreparedStatement preparedStatement;
Scanner scanner = new Scanner(System.in);
public static void main(String[] args) {
try {
//1.获取数据库连接和操作对象
connection = JDBCUtils_PreparedStatement.getConnetion();
//2.用户输入信息,使用占位符的sql语句,更新一条数据
String sql = "INSERT INTO student(id, name) values(?, ?)";
System.out.println("请先输入id,再输出姓名,用回车隔开:");
Scanner scanner = new Scanner(System.in);
int id = scanner.nextInt();
String name = scanner.next();
//3.preparedStatement传入带占位符的sql语句,set方法设置每一个位置的值,并执行更新操作
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1, id); //第一个set对应第一个?
preparedStatement.setString(2, name);//第二个set对应第二个?
int res = preparedStatement.executeUpdate();
//4.判断数据是否更新成功
if (res != 0) {
System.out.println("Update success");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
//5.调用重载方法,释放资源
JDBCUtils_PreparedStatement.close(connection, preparedStatement);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
请先输入id,再输出姓名,用回车隔开:
5
Harry
Update success
结果:
其他增删改查大同小异,只需要修改SQL语句