JDBC 访问数据库
基本流程
- 导入驱动 Class.forName(driver);
- 获取连接对象 Connection conn
- 执行sql语句
两种方式
- Statement:
- PreparedStatement:
- 解析结果集合
- 关闭连接
具体详解详解
DriverManager 驱动管理对象 获取连接驱动
//url:jdbc:mysql://ip(域名):端口/数据库名称?连接的参数
private static String url = "jdbc:mysql://localhost:3306/ccsh?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC";
private static String driver = "com.mysql.jdbc.Driver";
private static String user = "root";
private static String pwd = "root";
Class.forName(driver);
conn = DriverManager.getConnection(url, user, pwd);
Connection: 数据库连接
作用:
- 获取执行sql的对象方法
- Statement createStatement();
- PreparedStatement preparedStatement(String sql);
- 事务管理方法
开启事务: setAutoCommit(boolean autoCommit);
提交事务: commit()
回滚事务: rollback();
Statement:功能 执行sql对象
1. 执行任意 sql 语句 (数据定义语言DDL,数据控制语言DCL)
boolean execute(String sql);
2. 执行DML语句(insert update delete)、,
ddl语句 create alter drop
int executeUpdate(String sql); 返回值影响的行数
3. 执行DQL语句 select
ResultSet executeQuery(String sql)
Statement存在SQL注入问题:
因为采用字符串拼接,在拼接的时候如果有一些sql的关键字参与字符串拼接
例如
select * from employee
where user_id = '1427' OR 'a' = 'a'
AND user_password = '' or 1=1;
我们并没有输入有用的信息,但是却能查询出数据,这是非常不安全的
PreparedStatement:执行sql的对象
因此使用PreparedStatement 对象解决问题
1. 预编译sql:使用?作为占位符
2. 写入参数
String sql = "select * from parklog where parklog_id=?";
ps = conn.prepareStatement(sql);
ps.setString(1,“2019");
ResultSet:结果集对象 封装查询结果
过程:
- 游标移动 next()游标向下移动一行
- 是否有数据 有数据读取,无数据结束
- 获取数据 getObject(参数"属性"):获取数据
- 查询数据表封装为对象来装载集合返回
JDBC提高
抽取重复代码
重复的过程:
我们发现
- 导入驱动
- 获取连接对象
- 执行sql语句
- 解析结果集合
- 关闭连接
导入驱动,获取连接对象,关闭连接代码是重复的,与具体的操作无关的
所以我们将其提取
导入驱动,获取连接工具类
package jdbc.utils;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class JdbcHelper {
//url:jdbc:mysql://ip(域名):端口/数据库名称?连接的参数
private static String url = "jdbc:mysql://localhost:3306/ccsh?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC";
private static String driver = "com.mysql.jdbc.Driver";
private static String user = "root";
private static String pwd = "root";
static {
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 获取数据库连接
* @return connection
*/
public static Connection getConnection() {
Connection conn = null;
try {
conn = DriverManager.getConnection(url, user, pwd);
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
}
关闭操作工具类
package jdbc.utils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class CloseHelper {
public static void close(Connection conn) {
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void close(Connection conn, PreparedStatement ps) {
try {
conn.close();
ps.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void close(Connection conn, Statement ps) {
try {
conn.close();
ps.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void close(Connection conn, PreparedStatement ps, ResultSet rs) {
try {
conn.close();
ps.close();
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void close(ResultSet rs) {
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
jdbc事务控制:参考数据的事务管理
- 原子性:是指事务包含的所有操作要么全部成功,要么全部失败
- 一致性:一个事务执行之前和执行之后都必须处于一致性状态
- 隔离性:对于任意两个并发的事务T1和T2,在事务T1看来,T2要么在T1开始之前就已经结束,要么在T1结束之后才开始,这样每个事务都感觉不到有其他事务在并发地执行
- 持久性:持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的
JDBC事务操作:
只有DML 数据操作需要需要事务,增删改,查询因为不改变数据库的数据,所以不需要事务管理
具体操作:
1. 开启事务 setAutoCommit(boolean autoCommit)
2. 提交事务 commit()提交事务
3. 回滚事务rollback()回滚事务
添加了事务管理的 CarDao类
package jdbc.jdbc;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import jdbc.entity.Car;
import jdbc.utils.CloseHelper;
import jdbc.utils.JdbcHelper;
public class CarDao {
public Car findOne()
public int deleteOne(String id ) {
Connection conn = null;
PreparedStatement ps = null;
int x = 0;
try {
conn = JdbcHelper.getConnection();
conn.getAutoCommit();
} catch (SQLException e1) {
e1.printStackTrace();
}
sql = "delete from car where car_id=?";
try {
ps = conn.prepareStatement(sql);
ps.setObject(1, id);
x = ps.executeUpdate();
} catch(Exception e) {
e.printStackTrace();
try {
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
} finally {
CloseHelper.close(conn, ps);
}
return x;
}
public int insertOne(Car car) {
//略
return x;
}
public int updateOne(Car car) {
//略
return x;
}
}
今日的JDBC笔记到此