概述:DriverManager 是驱动管理类
作用
// 返回数据库连接的对象,url 是指定连接路径,user 是数据库用户名 password 是数据库密码
static Connection getConnection(String url , String user , String password);
jdbc:mysql://IP地址(域名):端口号/数据库名称
如果连接的是本机 MySQL 服务器,并且端口号默认则 url简写为:jdbc:mysql:///数据库名称>
示例代码
// 1、获取数据库连接对象-自行更换数据库用户名和密码
Connection con = DriverManager.getConnection("jdbc:mysql:///test","root","root");
概述:Connection 是数据库连接类
作用
方法 | 作用 |
---|---|
Statement createStatement(); | 返回执行 SQL 对象 |
PreparedStatement prepareStatement(String sql); | 返回执行 SQL 对象,和上述对象有区别 |
方法 | 作用 | 注意事项 |
---|---|---|
setAutoCommit(boolean autoCommit); | 开启事务 | 方法参数设置为 false ,即开启事务,反之 |
commit(); | 提交事务 | 事务执行中未出现错误,执行提交 |
rollback(); | 回滚事务 | 事务执行中出现错误,执行回滚 |
示例代码(这里只为演示,并无实际效果,具体看后续案例)
// 1、获取数据库连接对象
Connection con = DriverManager.getConnection("jdbc:mysql:///test","root","root");
// 2、获取执行 SQL 对象
Statement st = con.createStatement();
// ? 后续会讲,看下去
PreparedStatement pst = con.prepareStatement("SELECT * FROM account WHERE id = ?");
// 1、开启事务
con.setAutoCommit(false);
// 2、提交事务
con.commit();
// 3、回滚事务
con.rollback();
概述:执行 SQL 的对象
常用方法
方法 | 作用 |
---|---|
boolean execute(String sql); | 可以执行任意的 SQL 语句 |
int executeUpdate(String sql); | 执行 DML、DDL语句,返回值:影响的行数,>0 则代表执行成功 |
ResultSet executeQuery(String sql); | 执行 DQL 查询语句 |
示例代码
-- 创建一个数据库
CREATE DATABASE IF NOT EXISTS test CHARACTER SET utf8;
-- 使用数据库
USE test;
-- 创建一个账户表
CREATE TABLE account(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(20),
balance DOUBLE
);
-- 向账户表中添加数据
INSERT INTO account(NAME , balance) VALUES('张三',1000),('李四',1000);
-- 查询账户表
SELECT * FROM account;
public class Test1 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
// 1、注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
// 2、获取数据库连接对象
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "root");
// 3、获取执行 SQL 对象
Statement st = con.createStatement();
// 4、定义 SQL 语句
String sql1 = "SELECT * FROM account WHERE id = 2";
String sql2 = "UPDATE account SET balance = balance - 500 WHERE id = 1";
// 5、执行 SQL 语句
boolean flag = st.execute(sql1);
int lineNum = st.executeUpdate(sql2);
ResultSet rs = st.executeQuery(sql1);
// 6、输出结果
System.out.println(flag + " " + lineNum);
// 输出 ResultSet 结果集结果
while(rs.next()){
int id = rs.getInt(1);
String name = rs.getString("name");
double balance = rs.getDouble(3);
System.out.println(id + "---" + name + "---" + balance);
}
// 7、释放资源
st.close();
con.close();
}
}
运行结果:
true 1
2—李四—1000.0
概述:执行 SQL 的对象(可以防止 SQL 注入)
SQL 注入!!!
常用方法
方法 | 作用 | 参数 |
---|---|---|
setXxx(参数1,参数2) | 给 ?赋值,Xxx代表数据类型 | 参数1:?的位置编号(从1开始) 参数2:赋给?的值 |
示例代码(此对象如何使用)
-- 创建一个数据库
CREATE DATABASE IF NOT EXISTS test CHARACTER SET utf8;
-- 使用数据库
USE test;
-- 创建一个账户表
CREATE TABLE account(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(20),
balance DOUBLE
);
-- 向账户表中添加数据
INSERT INTO account(NAME , balance) VALUES('张三',1000),('李四',1000);
-- 查询账户表
SELECT * FROM account;
public class Test2 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
// 1、注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
// 2、获取数据库连接对象
Connection con = DriverManager.getConnection("jdbc:mysql:///test", "root", "root");
// 3、定义 SQL 语句,这里使用占位符 ?
String sql = "UPDATE account SET balance = balance - ? WHERE id = ?";
// 4、创建 执行 SQL 对象
PreparedStatement pst = con.prepareStatement(sql);
// 5、设置参数,给第一个?设置值为 500 给第二个?设置值为 1
pst.setInt(1,500);
pst.setInt(2,1);
// 6、执行 SQL 语句
int lineNum = pst.executeUpdate();
// 7、输出结果
System.out.println(lineNum);
// 8、释放资源
pst.close();
con.close();;
}
}
运行后,可看到控制台输出结果 1 ,数据库中编号 1 的balance 变成了 500
概述:结果集对象,用来封装查询结果的
常用方法
方法 | 作用 | 注意事项 |
---|---|---|
boolean next(); | 游标向下移动一行,判断当前行是否有数据 | 有数据返回 true 无数据返回 false |
getXxx(参数); | 获取数据 | Xxx:代表数据类型 参数是 int 类型,代表列的编号(从1开始), 参数是 String 类型,代表列名称 |
代码示例
ResultSet rs = st.executeQuery(sql1);
//循环判断游标是否是最后一行末尾。
while(rs.next()){
//获取数据
int id = rs.getInt(1);
String name = rs.getString("name");
double balance = rs.getDouble(3);
System.out.println(id + "---" + name + "---" + balance);
}
概述:事务,一个包含多个步骤的业务操作。如果这个业务操作被事务管理,多个步骤要么同时成功,要么同时失败。
操作事务的三个步骤
代码示例(这里有很多的写法并不严谨,只是为了更好的演示效果,数据库还是上述步骤中用到过的)
public class Test3 {
public static void main(String[] args) {
// 这里为了省事,简单这样写
String url = "jdbc:mysql://localhost:3306/test";
String user = "root";
String password = "root";
Connection con = null;
PreparedStatement pst1 = null;
PreparedStatement pst2 = null;
try {
// 1、注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
// 2、获取数据库连接
con = DriverManager.getConnection(url,user,password);
// 3、开启事务
con.setAutoCommit(false);
// 4、定义 SQL 语句,sql1 张三-500 sql2 李四+500
String sql1 = "UPDATE account SET balance = balance - ? WHERE id = ?";
String sql2 = "UPDATE account SET balance = balance + ? WHERE id = ?";
// 5、获取执行 SQL 对象
pst1 = con.prepareStatement(sql1);
pst2 = con.prepareStatement(sql2);
// 6、设置 占位符值
pst1.setInt(1,500);
pst1.setInt(2,1);
pst2.setInt(1,500);
pst2.setInt(2,2);
// 7、执行 SQL
pst1.executeUpdate();
// 手动制造异常,可以运行次后,看下数据库的数字,再注释掉这行再运行,再看数据库数字
int i = 3/0;
pst2.executeUpdate();
// 提交事务,因为遇见异常,所以这步代码并不执行
con.commit();
} catch (Exception e) {
try{
if(con != null){
// 事务回滚,当 con 不为空的时候,才回滚
con.rollback();
}
}catch (SQLException e1){
e1.printStackTrace();
}
e.printStackTrace();
} finally {
try {
// 释放资源
pst1.close();
pst2.close();
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
概述:SQL 语句拼接时,用一些特殊的关键字参与字符串拼接,会造成安全性问题
代码示例
-- 创建数据库
CREATE DATABASE IF NOT EXISTS test CHARACTER SET utf8;
-- 创建 user 表
CREATE TABLE USER(
username VARCHAR(20), -- 用户名
PASSWORD VARCHAR(20) -- 密码
);
-- 插入数据
INSERT INTO USER VALUES('lisi',"a'or'a'='a");
-- 查询数据,可发现下边 3行都会显示此条信息,这样错误太明显了,这是为什么?
SELECT * FROM USER WHERE username = 'lisi' AND PASSWORD = 'a'OR'a'='a';
SELECT * FROM USER WHERE username = 'fhdsjkf' AND PASSWORD = 'a' OR 'a' = 'a';
SELECT * FROM USER WHERE username = 'a' AND PASSWORD = 'a' OR 'a' = 'a';
注意:为什么上述3行都能显示呢?看下边两个框,可以知道,查询语句的条件有两个,中间又用 OR ,根据或的特性,只要满足其一即可,第二个红框,很明显一直是对的,所以就能查询出来。