JDBC访问数据库的步骤
- 导入sql包
- 加载并注册驱动程序
- 创建connection对象
- 创建statement对象
- 执行SQL语句
- 使用ResultSet对象获取SQL语句执行结果
- 关闭statement对象
- 关闭connection对象
读取properties文件
// 读取jdbc.properties
FileInputStream fileInputStream = new FileInputStream("src/jdbc.properties");
properties.load(fileInputStream);
fileInputStream.close();
// 获取其中信息
String driver = properties.getProperty("driver");
String url = properties.getProperty("url");
String user = properties.getProperty("user");
String password = properties.getProperty("password");
PreparedStatement
防止SQL注入
处理Blob(binary large object)类型对象
比如图片
PreparedStatement preparedStatement = connection.prepareStatement("insert into user values (?, ?, ?)");
preparedStatement.setInt(1, 5);
preparedStatement.setString(2, "sss");
preparedStatement.setBlob(3, new FileInputStream("src/head/1.webp"));
int i = preparedStatement.executeUpdate();
DAO
员工和部门的增删改拆
数据库连接池
dbcp
配置文件
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://root@localhost:3306/test?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false
user=root
password=123456
# 指定数据库连接池中初始化连接数的个数
initialSize=3
# 指定最大的连接数: 同一时刻可以同时向数据库申请的连接数
maxActive=5
# 在数据库连接池中保存的最少的空闲连接的数量
minIdle=2
# 等待数据库连接池分配连接的最长时间. 单位为毫秒. 超出该时间将抛出异常
maxWait=5000
读取配置文件
Properties properties = new Properties();
InputStream inputStream = new BufferedInputStream(new FileInputStream("src/dbcp.properties"));
properties.load(inputStream);
DataSource dataSource = BasicDataSourceFactory.createDataSource(properties);
Connection connection = dataSource.getConnection();
c3p0
相较于dbcp可以自动回收空闲连接
JDBC的一些操作(取得自动生成的主键、批处理、事务)
JDBC 取得数据库自动生成的主键
在增加一条数据后,不仅返回1或0来判断是否添加成功
还能返回增东生成的主键值
在增加数据时,注意自动生成的主键位置填写null
并且在后面添加 Statement.RETURN_GENERATED_KEYS
比如PreparedStatement preparedStatement = connection.prepareStatement("insert into user values (null, ?, ?)", Statement.RETURN_GENERATED_KEYS);
在获取时使用 PreparedStatement的getGeneratedKeys()方法获取ResultSet类型的值
如ResultSet generatedKeys = preparedStatement.getGeneratedKeys();
最后再使用while循环遍历 generatedKeys 的值获取getObject(1)的主键值
如System.out.println(generatedKeys.getObject(1));
批处理
比如在添加100个用户的时候,使用循环一个个添加,耗费时间比使用批处理添加的方式更长
addBatch() 添加要执行的语句
executeBatch() 批处理执行刚添加的语句
// 不使用批处理的添加
PreparedStatement preparedStatement = connection.prepareStatement("insert into user(id, name) values (null, ?)");
for (int i = 0; i < 100; i++) {
preparedStatement.setString(1, "ye" + i);
int i1 = preparedStatement.executeUpdate();
}
// 使用批处理的方式添加
PreparedStatement preparedStatement = connection.prepareStatement("insert into user(id, name) values (null, ?)");
for (int i = 300; i < 400; i++) {
String name = "zhang" + i;
preparedStatement.setString(1, name);
preparedStatement.addBatch();
}
preparedStatement.executeBatch();
事务
和MySQL中的事务一样
需要先设置自动提交方式为false以开启事务
connection.setAutoCommit(false);
使用try-catch-finally,
在try中所有操作完成后添加connection.commit();
在catch中添加connection.rollback();
,在出现异常后回滚
在finally中要设置自动提交方式为true
connection.setAutoCommit(true);
一些问题
访问时报错
Exception in thread "main" com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Could not create connection to database server.
当前MySQL版本是8.0.x,mysql-connector-java依赖包版本是5.1.x版本,版本太低,依赖包版本改成8.0.11就可以解决
依赖包版本更新后,url后面需要加入
?characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false
Class.forName("com.mysql.jdbc.Driver")
要改成Class.forName("com.mysql.cj.jdbc.Driver")
JDBCUtils
JDBC访问数据库的步骤整体来看真正需要改动的也就SQL语句,其他的基本都是重复的,为解决在开发中需要反复编写其他步骤,编写一个JDBCUtils工具类将这些不需要改动的其他步骤封装起来,开发过程中调用起来更方便
import java.io.FileInputStream;
import java.io.IOException;
import java.sql.*;
import java.util.Properties;
public class JDBCUtils {
private static String url;
private static String user;
private static String password;
static {
Properties properties = new Properties();
try {
// 读取配置文件中信息
FileInputStream fileInputStream = new FileInputStream("src/jdbc.properties");
properties.load(fileInputStream);
fileInputStream.close();
String driver = properties.getProperty("driver");
url = properties.getProperty("url");
user = properties.getProperty("user");
password = properties.getProperty("password");
// 加载驱动
Class.forName(driver);
} catch (IOException e) {
throw new RuntimeException(e);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
// 创建connection对象建立连接
static Connection getConnection() throws SQLException {
Connection connection = DriverManager.getConnection(url, user, password);
return connection;
}
static void closeConnection(Connection connection) {
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
static void closeStatement(Statement statement) {
if (statement != null) {
try {
statement.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
static void closeResultSet(ResultSet resultSet) {
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
static void closeCUD(Statement statement, Connection connection) {
closeStatement(statement);
closeConnection(connection);
}
static void closeQuery(ResultSet resultSet, Statement statement, Connection connection) {
closeResultSet(resultSet);
closeStatement(statement);
closeConnection(connection);
}
}