MySql的初学习 -- 第十三章 -- JDBC、Sql注入、JDBC控制事务
博客说明
文章内容输出来源:拉勾教育Java就业急训营
什么是JDBC
JDBC就是一套操作关系数据库的规则(接口),数据库厂商需要实现这套接口,并提供数据库驱动的Jar包
使用这套接口,真正执行的是对应驱动包中的实现类
JDBC安装
- 将MySQL驱动包添加到jar包库文件夹中,Myjar文件夹,用于存放当前项目需要的所有jar包
- 在 idea中 配置jar包库的位置
- 配置jar包库
- 注册驱动
public class JDBCDemo01 {
public static void main(String[] args) throws Exception {
//1.注册驱动(可以省略,从jdbc3开始)
Class.forName("com.mysql.jdbc.Driver");
//2.获取连接 connection连接对象
/**
url的组成
jdbc:mysql: --> 协议
localhost:3306 --> 主机IP:端口
db1 --> 数据库
#可以不写
?characterEncoding=UTF-8(防止乱码) --> 参数名 = 参数值
*/
String url = "jdbc:mysql://localhost:3306/db1?characterEncoding=UTF-8";
DriverManager.getConnection(url,"root","123456");
}
}
使用JDBC运行SQL
Connection接口中的方法 | 说明 |
---|---|
Statement createStatement() | 创建 SQL语句执行对象 |
Statement类 常用方法 | 说明 |
---|---|
int executeUpdate(String sql); | 执行insert update delete语句.返回int类型,代表受影响的行 数 |
ResultSet executeQuery(String sql); | 执行select语句, 返回ResultSet结果集对象 |
使用executeUpdate
public class JDBCDemo01 {
public static void main(String[] args) throws Exception {
//1.注册驱动(可以省略,从jdbc3开始)
Class.forName("com.mysql.jdbc.Driver");
//2.获取连接 connection连接对象
String url = "jdbc:mysql://localhost:3306/db1?characterEncoding=UTF-8";
Connection con = DriverManager.getConnection(url, "root", "123456");
//3.获取语句执行平台
Statement statement = con.createStatement();
//3.1 通过 statement 对象的 executeUpdate 方法创建一张表
String sql = "create table test(id int,name varchar(20),age int);";
int i = statement.executeUpdate(sql);
System.out.println(i);
//4.关闭流
statement.close();
con.close();
}
}
使用executeQuery
public class JDBCDemo01 {
public static void main(String[] args) throws Exception {
//1.注册驱动(可以省略,从jdbc3开始)
Class.forName("com.mysql.jdbc.Driver");
//2.获取连接 connection连接对象
String url = "jdbc:mysql://localhost:3306/db1?characterEncoding=UTF-8";
Connection con = DriverManager.getConnection(url, "root", "123456");
//3.获取语句执行平台
Statement statement = con.createStatement();
//3.1 执行查询操作,使用executeQuery()
String sql = "select * from table1";
ResultSet resultSet = statement.executeQuery(sql);
//通过while循环获取resultSet中的数据
while (resultSet.next()) {
//获取id
int id = resultSet.getInt("id");
//获取姓名
String name = resultSet.getString("name");
System.out.println(id + "," + name);
}
//4.关闭流
resultSet.close();
statement.close();
con.close();
}
}
释放资源
- 需要释放的对象:ResultSet 结果集,Statement 语句,Connection 连接
- 释放原则:先开的后关,后开的先关。ResultSet ==> Statement ==> Connection
- 关闭可以放在 finally 块 中执行( try / catch / finally )
👇 👇 👇 👇 👇 👇 👇 👇 👇 👇
public class JDBCDemo01 {
public static void main(String[] args){
Connection con = null;
Statement statement = null;
ResultSet resultSet = null;
try {
//1.注册驱动(可以省略,从jdbc3开始)
Class.forName("com.mysql.jdbc.Driver");
//2.获取连接 connection连接对象
String url = "jdbc:mysql://localhost:3306/db1?characterEncoding=UTF-8";
con = DriverManager.getConnection(url, "root", "123456");
//3.获取语句执行平台
statement = con.createStatement();
//3.1 通过 statement 对象的 executeUpdate() 方法创建一张表
//String sql = "create table test(id int,name varchar(20),age int);";
//int i = statement.executeUpdate(sql);
//System.out.println(i);
//3.1 执行查询操作,使用executeQuery()
String sql = "select * from employee";
resultSet = statement.executeQuery(sql);
//通过while循环获取resultSet中的数据
while (resultSet.next()) {
//获取id
int id = resultSet.getInt("id");
//获取姓名
String name = resultSet.getString("name");
System.out.println(id + "," + name);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
//4.关闭流
try {
resultSet.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
try {
con.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
步骤总结
- 获取驱动(可以省略)
- 获取连接
- 获取Statement对象
- 处理结果集(只在查询时处理)
- 释放资源
JDBC工具类
因为前三部都是固定且复杂,因此可以创建一个JDBC工具类提高效率
复制就能用:URL那改一下自己的数据库名即可
👇👇👇👇👇
package com.jdbc;
import java.sql.*;
/**
* JDBC工具类
*/
public class JDBCUtils {
//1.将连接信息定义为 字符串常量
public static final String DRIVERNAME = "com.mysql.jdbc.Driver";
public static final String URL = "jdbc:mysql://localhost:3306/db1?characterEncoding=UTF-8";
public static final String USER = "root";
public static final String PASSWORD = "123456";
//2.静态代码块
static{
try {
//注册驱动
Class.forName(DRIVERNAME);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 获取连接的 静态方法
* @return
*/
public static Connection getConnection(){
//获取连接对象 并返回
try {
Connection connection = DriverManager.getConnection(URL, USER, PASSWORD);
return connection;
} catch (SQLException throwables) {
throwables.printStackTrace();
return null;
}
}
/**
* 结束资源方法(增删改)
* @param connection
* @param statement
*/
public static void CloseJDBC(Connection connection, Statement statement){
if(connection != null && statement != null){
try {
statement.close();
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
/**
* 结束资源方法(查)
* @param connection
* @param statement
* @param resultSet
*/
public static void CloseJDBC(Connection connection, Statement statement, ResultSet resultSet){
if(connection != null && statement != null && resultSet != null){
try {
resultSet.close();
statement.close();
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
使用JDBC工具类完成DML操作、DQL操作
package com.jdbc;
import org.junit.Test;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBCDemo01 {
/**
* 通过JDBC工具类增加数据
* @throws SQLException
*/
@Test
public void testInsert() throws SQLException {
//通过JDBC工具类获取连接
Connection con = JDBCUtils.getConnection();
//获取statement对象
Statement statement = con.createStatement();
//Sql
String sql = "insert into test value (2,'小明',8)";
//添加数据进数据库
int i = statement.executeUpdate(sql);
System.out.println(i);
//关闭连接
JDBCUtils.CloseJDBC(con,statement);
}
/**
* 通过JDBC工具类修改数据
* @throws SQLException
*/
@Test
public void testUpdate() throws SQLException {
//通过JDBC工具类获取连接
Connection connection = JDBCUtils.getConnection();
//获取statement对象
Statement statement = connection.createStatement();
//Sql
String sql = "Update test set name = '小红' where id = 1";
//添加数据进数据库
int i = statement.executeUpdate(sql);
System.out.println(i);
//关闭连接
JDBCUtils.CloseJDBC(connection,statement);
}
/**
* 使用JDBC工具类删除数据
* @throws SQLException
*/
@Test
public void testDelete() throws SQLException {
//通过JDBC工具类获取连接
Connection connection = JDBCUtils.getConnection();
//获取statement对象
Statement statement = connection.createStatement();
//Sql
String sql ="Delete from test where id = 5";
//添加数据进数据库
int i = statement.executeUpdate(sql);
System.out.println(i);
//关闭连接
JDBCUtils.CloseJDBC(connection,statement);
}
/**
* 使用JDBC工具类查询数据
* @throws SQLException
*/
@Test
public void testSelect() throws SQLException {
//通过JDBC工具类获取连接
Connection connection = JDBCUtils.getConnection();
//获取statement对象
Statement statement = connection.createStatement();
//Sql
String sql = "Select * from test";
//获取resultSet集
ResultSet resultSet = statement.executeQuery(sql);
//遍历输出数据
while(resultSet.next()){
int id = resultSet.getInt("id");
String name = resultSet.getString("name");
int age = resultSet.getInt("age");
System.out.println("编号:" + id + ",姓名:" + name + ",年龄:" + age);
}
//关闭连接
JDBCUtils.CloseJDBC(connection,statement,resultSet);
}
}
Sql注入
用户输入的密码和 SQL 语句进行字符串拼接。用户输入的内容作为了 SQL 语句语法的一部分,改变了 原有 SQL 真正的意义,以上问题称为 SQL 注入 .
详细过程等我有空后补
预处理对象
为了防止Sql注入,可以使用预处理对象进行防护
预处理对象:PrepareStatement 是 Statement接口的子接口
使用预处理对象 他有预编译的功能,提高SQL的执行效率
使用预处理对象 通过占位符的方式,设置参数,可以有效防止SQL注入
/**
* 使用PreparedStatement接口防止Sql注入
* @param args
* @throws SQLException
*/
public static void main(String[] args) throws SQLException {
//通过JDBC工具类获取连接
Connection connection = JDBCUtils.getConnection();
//使用?占位符来设置参数
String sql = "select * from test where id=? and pwd=?";
//获取prepareStatement对象
PreparedStatement ps = connection.prepareStatement(sql);
Scanner scanner = new Scanner(System.in);
System.out.println("请输入账号:");
String id = scanner.nextLine();
System.out.println("请输入密码:");
String pwd = scanner.nextLine();
//设置参数,使用setXXX(占位符的位置(整数),要设置的值)的方法设置占位符的参数
ps.setString(1,id);//设置第一个?的值为id
ps.setString(2,pwd);//设置第二个?的值为pwd
//查询
ResultSet resultSet = ps.executeQuery();
if(resultSet.next()){
System.out.println("成功:" + id);
}else{
System.out.println("失败:" + "Error");
}
//关闭连接
JDBCUtils.CloseJDBC(connection,ps,resultSet);
}
JDBC控制事务
事务相关API:使用 Connection中的方法实现事务管理
方法 | 说明 |
---|---|
void setAutoCommit(boolean autoCommit) | 参数是 true 或 false 如果设置为 false,表示关闭自动提交,相 当于开启事务 |
void commit() | 提交事务 |
void rollback() | 回滚事务 |
package com.jdbc;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class TestJDBCTransaction {
//使用JDBC操作事务
public static void main(String[] args) {
Connection connection = null;
PreparedStatement ps = null;
try {
//1.获取连接
connection = JDBCUtils.getConnection();
//2.开启事务
connection.setAutoCommit(false);
//3.获取预处理对象 执行SQL(两次操作)
//3.1小明账户-500
ps = connection.prepareStatement("Update test set money = money - ? where name = ?");
ps.setInt(1,500);
ps.setString(2,"小明");
ps.executeUpdate();
//手动添加异常,测试事务的回滚,不想发生异常请注销下面的代码
System.out.println(1 / 0);
//3.1小红账户+500
ps = connection.prepareStatement("Update test set money = money + ? where name = ?");
ps.setInt(1,500);
ps.setString(2,"小红");
ps.executeUpdate();
//4.提交事务(正常情况)
connection.commit();
System.out.println("转账成功");
} catch (SQLException throwables) {
throwables.printStackTrace();
//5.出现异常就回滚事务
try {
connection.rollback();
} catch (SQLException e) {
e.printStackTrace();
}
} finally {
//6.释放资源
JDBCUtils.CloseJDBC(connection,ps);
}
}
}