JDBC编程
前置知识
- Java 中 Properties 类是用于读取配置文件(
.properties
、.cfg
)中的配置信息。通常会将变动不大的配置信息存储在以.properties
结尾的配置文件中,可以通过java.util.Properties
类读取配置文件,将配置信息注入到配置类中- 如 properties 文件内容的格式是 键=值 形式,键不能够重复
java.driver=com.mysql.jdbc.Driver
- 如 properties 文件内容的格式是 键=值 形式,键不能够重复
- 什么是事务:事务是逻辑上的一组操作组合,要么都执行成功,要么执行失败回滚
- 事务四大特性(ACID)
- 原子性(Atomicity):事务是一个不可分割的工作单位,事务中的操作要么全部成功,要么全部失败
- 一致性(Consistency):事务必须使数据库从一个一致性状态变为另一个一致性状态。即事务按照预期效果生效,数据状态也是预期的状态
- 隔离性(Isolation):在多个用户并发访问数据库时,数据库为每一个用户开启的事物,不能别其他事务操作数据所干扰,多个并发事务之间要相互隔离
- 持久性(Durability):事务一旦被提交,对数据库的数据更改是永久性的,即使数据库故障也不会被影响到
JDBC简介
JDBC是一套统一的、基于Java语言的关系数据库编程接口规范,允许把SQL语句作为参数通过JDBC接口发送给数据库,数据库接受到SQL后进行语法分析、验证,然后执行、响应。在JDBC接口规范的基础上,不同的关系型数据库厂商提供了访问自己数据库的具体实现,这些具体的实现称为JDBC驱动
JDBC相关接口说明
DriverManager
驱动管理器,提供驱动注册方法,并管理着一个已经注册到DriverManager中的驱动列表
Driver
Driver接口由数据库厂家提供,作为开发人员,只需要使用Driver接口就可以了。在编程中要连接数据库,必须先装载特定厂商的数据库驱动程序,如:
- 装载MySQL驱动:
Class.forName("com.mysql.jdbc.Driver");
Connection
它表示程序与数据库服务器之间的单个连接,通过它可以发送一系列SQL语句到数据库服务器,并且可以控制这些SQL语句的提交和终止
- 连接MySQL数据库:
Connection connection = DriverManager.getConnection("jdbc:mysql://host:port/database", "user", "password");
常用Connection方法
- createStatement():创建Statement对象,执行静态SQL语句
- prepareStatement(sql) :预处理SQL语句,返回PrepareStatement对象
- prepareCall(sql):预处理存储过程的调用,返回CallableStatement对象
- setAutoCommit(boolean autoCommit):设置事务是否自动提交
- commit() :提交事务
- rollback() :回滚事务
- close():关闭连接
Statement
用于执行静态SQL语句并返回它所生成结果的对象
三种Statement类:
- Statement:由方法
connection.createStatement()
创建,用于发送简单的SQL语句(不带参数) - PreparedStatement :由方法
connection.prepareStatement(sql)
创建,用于发送含有一个或多个参数的SQL语句。PreparedStatement对象比Statement对象的效率更高,并且可以防止SQL注入 - CallableStatement:由方法
connection.prepareCall()
创建,用于调用存储过程
常用Statement方法:
- execute(String sql):运行sql语句,返回是否有结果集
- executeQuery(String sql):运行select语句,返回ResultSet结果集
- executeUpdate(String sql):运行insert/update/delete操作,返回更新的行数
- addBatch(String sql) :把多条sql语句放到一个批处理中
- executeBatch():向数据库发送一批sql语句执行
ResultSet
查询结果集处理接口,Statement及其子类执行executeQuery方法后返回该类型对象
常用方法:
- next():使游标从结果集的当前位置向前移动一行(注意:游标初始位置是在第一行之前,所以第一次执行next方法后游标指向第一行)
- getXXX(columnIndex):获取XXX类型的第columnIndex列的值(columnIndex指select子句中字段的索引,从1开始)
- getXXX(columnLabel):获取XXX类型的字段名(或别名)为columnLabel的字段值
- getObject(columnIndex | columnLabel):根据查询结果中列的索引位置或字段名获取字段值
- close():释放资源
JDBC入门使用
具体步骤:
- 加载JDBC驱动程序
- 建立数据库连接Connection
- 创建执行SQL的语句Statement
- 处理执行结果ResultSet
- 释放资源
导入依赖
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
创建DB的配置文件
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/jdbc
jdbc.username=root
jdbc.password=123456
创建JDBC工具类
用于加载JDBC驱动程序,提供获取Connection对象和释放资源方法
import java.io.IOException;
import java.sql.*;
import java.util.Objects;
import java.util.Properties;
/**
* @describe 读取数据库配置文件,获取连接对象
*/
public class JdbcUtils {
public static Properties properties = new Properties();
static {
try {
//加载properties配置文件
properties.load(ClassLoader.getSystemResourceAsStream("db.properties"));
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 获取connection对象
*/
public static Connection getConnection() {
try {
//注册驱动
Class.forName(properties.getProperty("jdbc.driver"));
//建立连接
return DriverManager
.getConnection(properties.getProperty("jdbc.url"), properties.getProperty("jdbc.username"), properties.getProperty("jdbc.password"));
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
return null;
}
}
/**
* 释放资源
*/
public static void release(ResultSet resultSet, Statement statement, Connection connection) {
try {
if (Objects.nonNull(resultSet)) {
resultSet.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (Objects.nonNull(statement)) {
statement.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (Objects.nonNull(connection)) {
connection.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
JDBC的使用
建表
CREATE TABLE users (
id int(11) NOT NULL AUTO_INCREMENT,
name varchar(30) DEFAULT NULL,
password varchar(32) DEFAULT NULL,
email varchar(20) DEFAULT NULL,
birthday date DEFAULT NULL,
introduction longblob,
create_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
实体类
@Data
@AllArgsConstructor
public class User implements Serializable {
private Long id;
private String name;
private String password;
private String email;
private Date birthday;
private Blob introduction;
private LocalDateTime createAt;
@Tolerate
public User() {
}
}
JDBC的CRUD
import com.wen.pojo.User;
import com.wen.utils.JdbcUtils;
import java.io.*;
import java.sql.*;
import java.time.LocalDateTime;
import java.util.Objects;
public class UserTest {
public static void main(String[] args) {
query();
}
public static void insert() {
Connection connection = JdbcUtils.getConnection();
PreparedStatement preparedStatement = null;
try {
if (Objects.nonNull(connection)) {
//手动提交事务
connection.setAutoCommit(false);
//创建预编译sql语句
String insertSql = "insert into users(name,password,email,birthday,introduction,create_at) values(?,?,?,?,?,?)";
preparedStatement = connection.prepareStatement(insertSql);
preparedStatement.setString(1,"mysql");
preparedStatement.setString(2,"123456");
preparedStatement.setString(3,"123456@mail.com");
preparedStatement.setDate(4, new Date(System.currentTimeMillis()));
preparedStatement.setClob(5, new BufferedReader(new InputStreamReader(new ByteArrayInputStream("hello world".getBytes()))));
preparedStatement.setTimestamp(6, Timestamp.valueOf(LocalDateTime.now()));
//执行sql语句
preparedStatement.execute();
//提交事务
connection.commit();
}
} catch (SQLException e) {
e.printStackTrace();
try {
//异常回滚
connection.rollback();
} catch (SQLException sqlException) {
sqlException.printStackTrace();
}
} finally {
//关闭连接
JdbcUtils.release(null,preparedStatement,connection);
}
}
public static void update() {
Connection connection = JdbcUtils.getConnection();
PreparedStatement preparedStatement = null;
try {
if (Objects.nonNull(connection)) {
//手动提交事务
connection.setAutoCommit(false);
//创建预编译sql语句
String updateSql = "update users set name = ?,password = ?,create_at = ? where id = ?";
preparedStatement = connection.prepareStatement(updateSql);
preparedStatement.setString(1,"mysql");
preparedStatement.setString(2,"456789");
preparedStatement.setTimestamp(3,Timestamp.valueOf(LocalDateTime.now()));
preparedStatement.setLong(4,1);
//执行sql语句
preparedStatement.executeUpdate();
//提交事务
connection.commit();
}
} catch (SQLException e) {
e.printStackTrace();
try {
//异常回滚
connection.rollback();
} catch (SQLException sqlException) {
sqlException.printStackTrace();
}
} finally {
JdbcUtils.release(null,preparedStatement,connection);
}
}
public static void delete() {
Connection connection = JdbcUtils.getConnection();
PreparedStatement preparedStatement = null;
try {
if (Objects.nonNull(connection)) {
//手动提交事务
connection.setAutoCommit(false);
//创建预编译sql语句
String deleteSql = "delete from users where id = ?";
preparedStatement = connection.prepareStatement(deleteSql);
preparedStatement.setLong(1,1);
//执行sql语句
preparedStatement.executeUpdate();
//提交事务
connection.commit();
}
} catch (SQLException e) {
e.printStackTrace();
try {
//异常回滚
connection.rollback();
} catch (SQLException sqlException) {
sqlException.printStackTrace();
}
} finally {
//关闭连接
JdbcUtils.release(null,preparedStatement,connection);
}
}
public static void query(){
Connection connection = JdbcUtils.getConnection();
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
if (Objects.nonNull(connection)) {
//手动提交事务
connection.setAutoCommit(false);
//创建预编译sql语句
String deleteSql = "select * from users order by birthday desc";
preparedStatement = connection.prepareStatement(deleteSql);
//执行sql语句
resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
User user = new User();
user.setId(resultSet.getLong(1));
user.setName(resultSet.getString(2));
user.setPassword(resultSet.getString(3));
user.setEmail(resultSet.getString(4));
user.setBirthday(resultSet.getDate(5));
user.setIntroduction(resultSet.getBlob(6));
user.setCreateAt(resultSet.getTimestamp(7).toLocalDateTime());
System.out.println(user);
}
//提交事务
connection.commit();
}
} catch (SQLException e) {
e.printStackTrace();
try {
//异常回滚
connection.rollback();
} catch (SQLException sqlException) {
sqlException.printStackTrace();
}
} finally {
//关闭连接
JdbcUtils.release(resultSet,preparedStatement,connection);
}
}
public static void batch() {
Connection connection = JdbcUtils.getConnection();
PreparedStatement preparedStatement = null;
try {
if (Objects.nonNull(connection)) {
//手动提交事务
connection.setAutoCommit(false);
//创建预编译sql语句
String insertSql = "insert into users(name,password,email,birthday) value(?,?,?,?)";
preparedStatement = connection.prepareStatement(insertSql);
for (int i = 0; i < 1000; i++) {
preparedStatement.setString(1,String.join("_","mysql",Integer.toString(i)));
preparedStatement.setString(2,"123456");
preparedStatement.setString(3,"123456@mail.com");
preparedStatement.setDate(4, new Date(System.currentTimeMillis()));
preparedStatement.addBatch();
}
//执行sql语句
preparedStatement.executeBatch();
//提交事务
connection.commit();
}
} catch (SQLException e) {
e.printStackTrace();
try {
//异常回滚
connection.rollback();
} catch (SQLException sqlException) {
sqlException.printStackTrace();
}
} finally {
//关闭连接
JdbcUtils.release(null,preparedStatement,connection);
}
}
}