1.连接方式

- 前端层:由
html、css、js、jquery组成,负责页面展示与用户交互,通过ajax技术与后端通信。 - 后端服务层:以
servlet服务为核心,承担请求处理、业务逻辑实现的功能,通过jdbc技术与数据库交互。 - 数据层:采用
mysql数据库,用于存储应用数据。
2.使用JDBC实现后端和数据库交互的流程

1. 初始化阶段
- 导入驱动包:为 Java 程序提供操作特定数据库的驱动支持,例如操作 MySQL 需导入
mysql-connector-java包。 - DriverManager 注册驱动:通过
DriverManager类将数据库驱动注册到 Java 运行环境,使程序能识别并调用驱动。 - Connection 链接数据库:建立 Java 程序与数据库的连接,需指定数据库 URL、用户名、密码等信息。
2. 数据库操作阶段
- Statement 操作数据库:用于执行 SQL 语句,支持增删改查操作。其中查询操作会生成
ResultSet封装查询结果集,增删改操作则直接执行并返回影响行数。 - ResultSet 封装查询结果集:存储查询得到的数据集,可通过其方法遍历、获取数据。
3. 资源关闭阶段
- 关闭 ResultSet 对象:释放查询结果集占用的资源。
- 关闭 Statement 对象:释放 SQL 语句执行对象占用的资源。
- 关闭 Connection 对象:释放数据库连接资源,这是 JDBC 操作中保证资源释放、避免连接泄漏的关键步骤。
DriverManager - 驱动管理类 - 负责管理数据库驱动连接
Connection - 数据库连接类 - 建立与数据库的连接(包含用户名、密码、URL等参数)
Statement - SQL语句执行器 - 用于编译和执行SQL操作指令
ResultSet - 结果集对象 - 存储并封装SQL查询返回的结果数据
3.操作
1.导包

2.加载驱动
con = DriverManager.getConnection(url,"root","2020");//获取连接
3.连接数据库
Class.forName("com.mysql.cj.jdbc.Driver");//加载驱动
4.操作数据库
statement = con.createStatement();//创建Statement对象
5.返回结果
resultSet = statement.executeQuery(sql);//执行SQl语句
//处理结果集
while(resultSet.next()){//如果有数据
String id = resultSet.getString("id");
String username = resultSet.getString("username");
String password = resultSet.getString("password");
String sex = resultSet.getString("sex");
String age = resultSet.getString("age");
String phone = resultSet.getString("phone");
String address = resultSet.getString("address");
System.out.println(id+" "+username+" "+password+" "+sex+" "+age+" "+phone+" "+address);
}
增删改
不需要resultSet = statement.executeQuery(sql);//执行SQl语句
直接
statement.executeUpdate(sql);//执行SQl语句
4.练习题
查询表user
package com.qcby.sql;
import java.sql.*;
public class JDBCSearchUtil {
public static void main(String[] args) throws SQLException {
String sql ="select * from user";
search(sql);//调用方法
}
public static void search(String sql) throws SQLException {
String url ="jdbc:mysql://localhost:3306/0910demo?useSSL=false&serverTimezone=UTC";
Connection con = null;
Statement statement = null;
ResultSet resultSet = null;
try {
Class.forName("com.mysql.cj.jdbc.Driver");//加载驱动
con = DriverManager.getConnection(url,"root","2020");//获取连接
statement = con.createStatement();//创建Statement对象
resultSet = statement.executeQuery(sql);//执行SQl语句
//处理结果集
while(resultSet.next()){//如果有数据
String id = resultSet.getString("id");
String username = resultSet.getString("username");
String password = resultSet.getString("password");
String sex = resultSet.getString("sex");
String age = resultSet.getString("age");
String phone = resultSet.getString("phone");
String address = resultSet.getString("address");
System.out.println(id+" "+username+" "+password+" "+sex+" "+age+" "+phone+" "+address);
}
}catch (Exception e){
e.printStackTrace();
}finally {
//资源关闭
resultSet.close();
statement.close();
con.close();
}
}
}

统计表的数据
package com.qcby.sql;
import java.sql.*;
public class JDBCGetCountUtil {
public static void main(String[] args) throws SQLException {
String sql ="select count(*) from user";
search(sql);
}
public static void search(String sql) throws SQLException {
String url ="jdbc:mysql://localhost:3306/0910demo?useSSL=false&serverTimezone=UTC";
Connection con = null;
Statement statement = null;
ResultSet set = null;
try {
Class.forName("com.mysql.cj.jdbc.Driver");//加载驱动
con = DriverManager.getConnection(url,"root","2020");//获取连接
statement = con.createStatement();//创建Statement对象
set = statement.executeQuery(sql);//执行SQl语句
while(set.next()){
int count = set.getInt(1);
System.out.println(count);
}
}catch (Exception e){
e.printStackTrace();
}finally {
//资源关闭
set.close();
statement.close();
con.close();
}
}
}

增加数据
package com.qcby.sql;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBCInsertUtil {
public static void main(String[] args) throws SQLException {
String sql ="insert into user (username,password,sex,age,phone,address) values('admin','123456','男',18,'12345678901','上海')";
insert(sql);
}
public static void insert(String sql) throws SQLException {
String url ="jdbc:mysql://localhost:3306/0910demo?useSSL=false&serverTimezone=UTC";
Connection con = null;
Statement statement = null;
try {
Class.forName("com.mysql.cj.jdbc.Driver");//加载驱动
con = DriverManager.getConnection(url,"root","2020");//连接数据库
statement = con.createStatement();//创建Statement对象
statement.executeUpdate(sql);//执行SQL语句
}catch (Exception e){
e.printStackTrace();
}finally {
//资源关闭
statement.close();
con.close();
}
}
}

改变数据
package com.qcby.sql;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBCUppdateUtil {
public static void main(String[] args) throws SQLException {
String sql ="update user set username = '老王' where id = 7";
update(sql);
}
public static void update(String sql) throws SQLException {
String url ="jdbc:mysql://localhost:3306/0910demo?useSSL=false&serverTimezone=UTC";
Connection con = null;
Statement stat = null;
try {
Class.forName("com.mysql.cj.jdbc.Driver");//加载驱动
con = DriverManager.getConnection(url,"root","2020");//连接数据库
stat = con.createStatement();//创建Statement对象
stat.executeUpdate(sql);//更新数据库
}catch (Exception e){
e.printStackTrace();
}
finally {
//资源关闭
stat.close();
con.close();
}
}
}

删除数据
package com.qcby.sql;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBCDeleteUtil {
public static void main(String[] args) throws SQLException {
String sql ="delete from user where id = 8";
delete(sql);
}
public static void delete(String sql) throws SQLException {
String url ="jdbc:mysql://localhost:3306/0910demo?useSSL=false&serverTimezone=UTC";//数据库连接地址
Connection con =null;
Statement stat = null;
try{
Class.forName("com.mysql.cj.jdbc.Driver");//加载驱动
con = DriverManager.getConnection(url,"root","2020");//连接数据库
stat = con.createStatement();//创建Statement对象
stat.executeUpdate(sql);//更新数据库
}catch (Exception e){
e.printStackTrace();
}
finally {
//资源关闭
stat.close();
con.close();
}
}
}

5.sql注入攻击
sql注入攻击是如何产生的:
在用户本地拼接sql语句,将拼接好的sql语句发送给数据库,数据库会执行sql语句;
如果用户输入的参数能改变sql语句的规则,那么数据库就会执行用户输入的sql语句。
处理方式:
预编译的sql模板:通过?占位符的方式,将不含参数值的sql模板提前发送给数据,数据库提前解析sql语句,生成执行计划。
安全绑定参数:用户输入的参数当中一旦检测到特殊字符('',or...),PreparedStatment会将其转义从而不会对sql语句进行影响;
参数类型校验:setString () setInt () setBoolean () setDouble () 对输入的参数进一步校验。
案列:
package com.qcby.sql;
import java.sql.*;
import java.util.Collections;
import java.util.Scanner;
public class LoginUtil {
public static void main(String[] args) throws SQLException {
Scanner sc = new Scanner(System.in);
System.out.println("请输入用户名:");
String username = sc.nextLine();
System.out.println("请输入密码:");
String password = sc.nextLine();
String sql = "select * from user where username = '" + username + "' and password = '" + password + "'";
System.out.println(sql);
search(sql);
}
public static void search(String sql) throws SQLException {
String url = "jdbc:mysql://localhost:3306/0910demo?useSSL=false&serverTimezone=UTC";
Connection con =null;
Statement statement = null;
ResultSet set = null;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
con=DriverManager.getConnection(url,"root","2020");
statement = con.createStatement();
set = statement.executeQuery(sql);
//处理查询结果
if(set.next()){
System.out.println("登录成功!");
}else {
System.out.println("登录失败!");
}
}catch (Exception e){
e.printStackTrace();
}finally {
//释放资源
set.close();
statement.close();
con.close();
}
}
}

这里的输入使用‘’将select * from user where username = '" + username + "' and password = '" + password + "' 中的单引号吸附将语句的条件转变,这是一种很危险的操作。
package com.qcby.sql;
import java.sql.*;
import java.util.Scanner;
public class LoginUtil2 {
public static void main(String[] args) throws SQLException {
Scanner sc = new Scanner(System.in);
System.out.println("请输入用户名:");
String username = sc.nextLine();
System.out.println("请输入密码:");
String password = sc.nextLine();
String sql = "select * from user where username = ? and password = ?";
search(sql, username, password);
}
public static void search(String sql, String username, String password) throws SQLException {
String url = "jdbc:mysql://localhost:3306/0910demo?useSSL=false&serverTimezone=UTC";
Connection con = null;
PreparedStatement statement = null;
ResultSet set = null;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
con= DriverManager.getConnection(url,"root","2020");
statement = con .prepareStatement(sql);
statement.setString(1,username);
statement.setString(2,password);
set = statement.executeQuery();//执行SQl语句
if(set.next()){
System.out.println("登录成功!");
}else {
System.out.println("登录失败!");
}
}catch (Exception e){
e.printStackTrace();
}finally {
//释放资源
set.close();
statement.close();
con.close();
}
}
}

安全绑定参数:用户输入的参数当中一旦检测到特殊字符('',or...),PreparedStatment会将其转义从而不会对sql语句进行影响;

1022

被折叠的 条评论
为什么被折叠?



