JDBC(Mysql撒花)
终于学到你,还好没放弃。
JDBC即Java数据库连接,(Java Database Connectivity,简称JDBC)。
是Java中规范客户端如何访问数据库的接口。
这个接口中有使用数据库的各种方法,这些方法由各大数据库厂商实现。
第一个JDBC程序
创建sql
CREATE DATABASE jdbcStudy CHARACTER SET utf8 COLLATE utf8_general_ci;
USE jdbcStudy;
CREATE TABLE `users`(
id INT PRIMARY KEY,
NAME VARCHAR(40),
PASSWORD VARCHAR(40),
email VARCHAR(60),
birthday DATE
);
INSERT INTO `users`(id,NAME,PASSWORD,email,birthday)
VALUES(1,'zhansan','123456','zs@sina.com','1980-12-04'),
(2,'lisi','123456','lisi@sina.com','1981-12-04'),
(3,'wangwu','123456','wangwu@sina.com','1979-12-04')
JDBC连接数据库的步骤
-
加载数据库驱动。
-
设置用户信息和url。
-
使用DriverManager连接数据库,返回数据库对象。
-
可选:创建sql字符串,该字符串包含需要执行的sql语句。
-
通过数据库对象执行sql字符串,返回包含执行结果的数据集。
-
通过返回的数据集来得到需要的结果。
-
释放所有连接。
package com.rsp2012.controller;
import java.sql.*;
public class SQL {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//1.注册驱动。
//Class.forName("com.mysql.jdbc.Driver");
Class.forName("com.mysql.cj.jdbc.Driver");
//2.用户信息和url,url中使用?链接参数,使用&分割多个参数。
//useUnicode=true:是否指定客户端编码。
//characterEncoding=utf8:指定客户端编码为utf8。
//useSSL=true:使用安全的SSL加密连接。
String url = "jdbc:mysql://localhost:3308/jdbcStudy?useUnicode=true&characterEncoding=utf8&useSSL=true";
String username = "root";
String password = "ganxie2012";
//3.连接数据库,获取数据库连接对象。
//Connection:数据库链接类。
//DriverManager:驱动管理类,需要将数据库的url和用户信息传给驱动管理类来连接数据库,返回一个数据库连接对象。
Connection connection = DriverManager.getConnection(url, username, password);
//4.获取sql对象。
//Statement:sql对象类,相当于sql语句的载体,通过Statement类执行sql语句。
//createStatement方法:使用静态sql,返回该sql的对象。
Statement statement = connection.createStatement();
//5.通过sql对象执行sql语句。
//创建需要执行的sql字符串,该字符串为sql执行语句。
String sql = "SELECT * FROM `users`;";
//ResultSet:结果集对象,用来装sql执行返回的结果。
//executeQuery:方法,该方法用来执行sql的SELECT查询。
ResultSet resultSet = statement.executeQuery(sql);
//resultSet.next():如果next()有数据存在,则为真。
while (resultSet.next()) {
System.out.println("id=" + resultSet.getObject("id"));
System.out.println("name=" + resultSet.getObject("NAME"));
System.out.println("pwd=" + resultSet.getObject("PASSWORD"));
System.out.println("email=" + resultSet.getObject("email"));
System.out.println("birthday=" + resultSet.getObject("birthday"));
}
//6.释放链接。
//释放结果集。
resultSet.close();
//释放sql对象。
statement.close();
//释放数据库连接对象。
connection.close();
}
}
拆解过程
url格式:
协议名://主机地址:端口号/数据库名?参数1&参数2&...
Connection类的作用:
Connection类是一个数据库的对象,可以执行很多数据库层面的代码。
//事务相关
//自动提交事务
connection.setAutoCommit(false);
//提交事务
connection.commit();
//回滚事务
connection.rollback();
Statement类的作用:
Statement类是一个数据库的执行类,可以执行SQL语句。
//增删改,返回受影响的行数
statement.executeUpdate();
//查询,返回ResultSet结果集
statement.executeQuery();
//任意sql语句均可通过execute执行,效率低。
statement.execute();
//执行多个sql,效率低。
statement.executeBatch();
ResultSet类的作用:
ResultSet类是一个结果集对象,封装了所有的查询结果,通过数据的类型来使用。
resultSet.getObject();
resultSet.getInt();
resultSet.getString();
resultSet.getDouble();
resultSet.getDate();
resultSet.getBigDecimal();
ResultSet类也含有一些指针方法,用来遍历结果。
//移动指针到最后
resultSet.afterLast();
//移动指针到最前
resultSet.beforeFirst();
//移动指针到下一个
resultSet.next();
释放资源:
//释放结果集。
resultSet.close();
//释放sql对象。
statement.close();
//释放数据库连接对象,及其耗资源。
connection.close();
封装一个JDBC工具类
1.配置文件
创建一个配置文件,用来配置连接数据库的信息:
存放位置:
-
注意:如果是java程序,请放在src下。
-
我这里是web程序,所以我放在了resources下。
2.配置数据库信息
配置如下:
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3308/jdbcStudy?useUnicode=true&characterEncoding=utf8&useSSL=true
username=root
password=ganxie2012
3.创建工具类
创建工具类:
加载配置文件信息:
public class JdbcUtils {
private static String driver = null;
private static String url = null;
private static String username = null;
private static String password = null;
static {
try {
//使用InputStream读取文件的数据流到java中
InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");
//声明Properties类对象
Properties properties = new Properties();
//使用properties类的load方法来读取文件信息
properties.load(in);
//拿到properties中键值对的值
driver = properties.getProperty("driver");
url = properties.getProperty("url");
username = properties.getProperty("username");
password = properties.getProperty("password");
} catch (Exception e) {
e.printStackTrace();
System.out.println("加载数据库信息失败,请检查配置文件!");
}
}
}
4.工具类实现
public class JdbcUtils {
private static String driver;
private static String url;
private static String username;
private static String password;
static {
try {
//使用InputStream读取文件的数据流到java中
InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");
//声明Properties类对象
Properties properties = new Properties();
//使用properties类的load方法来读取文件信息
properties.load(in);
//拿到properties中键值对的值
driver = properties.getProperty("driver");
url = properties.getProperty("url");
username = properties.getProperty("username");
password = properties.getProperty("password");
//加载驱动
Class.forName(driver);
} catch (Exception e) {
e.printStackTrace();
}
}
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url, username, password);
}
public static void close(ResultSet resultSet, Statement statement, Connection connection) throws SQLException {
if (resultSet != null) {
resultSet.close();
}
if (statement != null) {
statement.close();
}
if (connection != null) {
connection.close();
}
}
}
5.测试工具类
查询数据
public class Sql {
public static void main(String[] args) throws SQLException {
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
connection = JdbcUtils.getConnection();
statement = connection.createStatement();
String sql = "SELECT * FROM `users`;";
resultSet = statement.executeQuery(sql);
while (resultSet.next()) {
System.out.println("id=" + resultSet.getObject("id"));
System.out.println("name=" + resultSet.getObject("NAME"));
System.out.println("pwd=" + resultSet.getObject("PASSWORD"));
System.out.println("email=" + resultSet.getObject("email"));
System.out.println("birthday=" + resultSet.getObject("birthday"));
}
JdbcUtils.close(resultSet,statement,connection);
}
}
增加数据
public class Sql {
public static void main(String[] args) throws SQLException {
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
connection = JdbcUtils.getConnection();
statement = connection.createStatement();
//插入数据
String sql = "INSERT INTO `users`(`id`,`NAME`,`PASSWORD`,`email`,`birthday`)" +
"VALUE('4','liwandong','654321','45646@qq.com','1994-04-04');";
int num = statement.executeUpdate(sql);
if(num>0){
System.out.println("插入成功");
}else {
System.out.println("插入失败");
}
JdbcUtils.close(resultSet,statement,connection);
}
}
删除数据
public class Sql {
public static void main(String[] args) throws SQLException {
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
connection = JdbcUtils.getConnection();
statement = connection.createStatement();
//插入数据
String sql = "DELETE FROM `users` WHERE `id`=4;";
int num = statement.executeUpdate(sql);
if(num>0){
System.out.println("删除成功");
}else {
System.out.println("删除失败");
}
JdbcUtils.close(resultSet,statement,connection);
}
}
修改数据
public class Sql {
public static void main(String[] args) throws SQLException {
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
connection = JdbcUtils.getConnection();
statement = connection.createStatement();
//插入数据
String sql = "UPDATE `users` SET `name`='sb' WHERE `name` ='zhansan';";
int num = statement.executeUpdate(sql);
if(num>0){
System.out.println("修改成功");
}else {
System.out.println("修改失败");
}
JdbcUtils.close(resultSet,statement,connection);
}
}
PreparedStatement对象
PreparedStatement是用来替代Statement使用的类,相比于Statement,PreparedStatement效率更高,更安全,有效隔绝SQL注入。
PreparedStatement在传值过程中,使用占位符来预编译,之后给values赋值。
增加数据
public class Sql {
public static void main(String[] args) throws SQLException {
Connection connection = null;
PreparedStatement preparedStatement = null;
connection = JdbcUtils.getConnection();
//sql语句,使用?占位
String sql = "INSERT INTO `users`(`id`,`NAME`,`PASSWORD`,`email`,`birthday`)" +
"VALUE(?,?,?,?,?);";
//预编译sql语句
preparedStatement = connection.prepareStatement(sql);
//根据索引下标设置值,这里的下标从1开始
preparedStatement.setInt(1,5);
preparedStatement.setString(2,"zhaowu");
preparedStatement.setString(3,"rsp2012");
preparedStatement.setString(4,"505@qq.com");
preparedStatement.setObject(5,"1992-11-5");
//执行sql返回结果
int num = preparedStatement.executeUpdate();
if(num>0){
System.out.println("插入成功");
}else {
System.out.println("插入失败");
}
connection.close();
}
}
删除数据
public class Sql {
public static void main(String[] args) throws SQLException {
Connection connection = null;
PreparedStatement preparedStatement = null;
connection = JdbcUtils.getConnection();
//sql语句,使用?占位
String sql = "DELETE FROM `users` WHERE `id`=?";
//预编译sql语句
preparedStatement = connection.prepareStatement(sql);
//根据索引下标设置值,这里的下标从1开始
preparedStatement.setInt(1,5);
//执行sql返回结果
int num = preparedStatement.executeUpdate();
if(num>0){
System.out.println("删除成功");
}else {
System.out.println("删除失败");
}
connection.close();
preparedStatement.close();
}
}
修改数据
public class Sql {
public static void main(String[] args) throws SQLException {
Connection connection = null;
PreparedStatement preparedStatement = null;
connection = JdbcUtils.getConnection();
//sql语句,使用?占位
String sql = "UPDATE `users` SET `name`=? WHERE `name` =?;";
//预编译sql语句
preparedStatement = connection.prepareStatement(sql);
//根据索引下标设置值,这里的下标从1开始
preparedStatement.setString(1, "zhangsan");
preparedStatement.setString(2, "sb");
//执行sql返回结果
int num = preparedStatement.executeUpdate();
if (num > 0) {
System.out.println("修改成功");
} else {
System.out.println("修改失败");
}
connection.close();
preparedStatement.close();
}
}
查询数据
package com.rsp2012.pojo;
import com.rsp2012.utils.JdbcUtils;
import java.sql.*;
public class Sql {
public static void main(String[] args) throws SQLException {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
connection = JdbcUtils.getConnection();
//sql语句,使用?占位
String sql = "SELECT * FROM `users` where id =?;";
//预编译sql语句
preparedStatement = connection.prepareStatement(sql);
//根据索引下标设置值,这里的下标从1开始
preparedStatement.setObject(1, "1");
//执行sql返回结果
resultSet = preparedStatement.executeQuery();
if (resultSet.next()) {
System.out.println(resultSet.getObject("id"));
System.out.println(resultSet.getObject("NAME"));
System.out.println(resultSet.getObject("PASSWORD"));
System.out.println(resultSet.getObject("email"));
System.out.println(resultSet.getObject("birthday"));
}
connection.close();
resultSet.close();
preparedStatement.close();
}
}
JDBC事务
1.创建一个新表
create table `test` (
`id` int(10) not null auto_increment,
`name` varchar(10) not null,
`score` int(10) not null,
primary key (`id`)
)engine =INNODB default char set =UTF8
2.插入数据
public class Sql {
public static void main(String[] args) throws SQLException {
Connection connection;
PreparedStatement preparedStatement;
connection = JdbcUtils.getConnection();
String sql = "insert into `test`(`name`,`score`) value (?,?),(?,?);";
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1, "李万东");
preparedStatement.setInt(2, 60);
preparedStatement.setString(3, "梧桐");
preparedStatement.setInt(4, 100);
int num = preparedStatement.executeUpdate();
if (num > 0) {
System.out.println("插入成功");
}
}
}
3.手动提交事务
public class Sql {
public static void main(String[] args) {
//初始化对象
Connection connection = null;
PreparedStatement p1 = null;
PreparedStatement p2 = null;
try {
//拿到数据库对象
connection = JdbcUtils.getConnection();
//声明sql字符串
String sql1 = "update `test` set `score` = `score`-5 where `id` = ?";
String sql2 = "update `test` set `score` = `score`+5 where `id` = ?";
//关闭自动提交事务,开启事务
connection.setAutoCommit(false);
//预编译sql
p1 = connection.prepareStatement(sql1);
p2 = connection.prepareStatement(sql2);
p1.setInt(1, 1);
p2.setInt(1, 2);
//执行sql
p1.executeUpdate();
p2.executeUpdate();
//提交事务
connection.commit();
} catch (SQLException e) {
try {
//事务回滚,默认有隐式定义,可以不用写
connection.rollback();
} catch (SQLException ex) {
ex.printStackTrace();
}
e.printStackTrace();
} finally {
try {
//释放资源
connection.close();
p1.close();
p2.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
数据库连接池
之前使用的数据库连接方式是最基本的方式,每次使用都会经历连接——执行——释放的过程。
连接——释放的过程是极度损耗系统资源的,所以主流会使用数据库池化技术。
简单来说就是准备最小连接数数量的Connection放在池子里,用就拿来用,用完再放回去,不用释放。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南