前情提要:MySQL数据库驱动JDBC实操随笔(附文件)_年关的博客-CSDN博客
目录
一、DriverManager
二、ResultSet
编辑
三、 Statement
四、做个登陆验证(假的-都是假的)
演示sql注入
演示PreparedStatement预编译防止sql注入
咱们使用@Test注解进行测试,没有环境的自己装一下或者改一下代码
一、DriverManager
DriverManager在java.sql这个包里面,管理一组 JDBC 驱动程序的基本服务
先看DriverManager经典使用场景
作用:1、管理和注册驱动
2、创建数据库连接
功能:就是类中的方法:registerDriver和getConnection
1.registerDriver注册驱动:告诉程序该使用哪一个数据库驱动jar
static void registerDriver(Driver driver)//注册与给定的驱动程序DriverManager
写的代码使用:
Class.forName("com.mysql.jdbc.Driver");
通过查看源码发现:在com.mysql.jdbc.Driver类中存在静态代码块
Static {
try{
java.sql.DriverManager.registerDriver(new Driver);
}catch (SQLException E){
throw new RuntimeException("Can't register driver!");
}
}
注意的是:在mysql5之后的驱动jar包可以省略注册驱动的步骤
2.getConnection获取数据库连接
方法:static Connection getConnection(String url,String username,String password)
参数:
url:指定连接的路径
语法:jdbc:mysql://ip地址(域名):端口号/数据库名称
例子:jdbc:mysql://localhost:3306/employee
细节:如果连接是本机Mysql服务器,并且默认的端口是3306,则url可以 简写为:jdbc:mysql:///数据库名
二、ResultSet
从数据库获取返回结果集,用于查询语句
@Test
public void ResultSet1() throws Exception {
//1、注册驱动
Class.forName("com.mysql.jdbc.Driver");
String url="jdbc:mysql://192.168.5.222:3306/test";
//这里的192.168.5.222:3306指的是我mysql服务器的ip如果是本机的mysql的话用下面这段
//String url="jdbc:mysql://127.0.0.1:3306/test";
//test指的是所需要用的数据库系统中的具体某一个数据库
String username="root";
String password="123456";
//数据库的账号密码
Connection conn= DriverManager.getConnection(url,username,password);
//sql
String sql="select * from sjj";
//4获取执行sql的对象
Statement stmt=conn.createStatement();
//6.执行查询,得到ResultSet
ResultSet resultSet=stmt.executeQuery(sql);
//处理ResultSet
System.out.println("book_idt|tbook_name");
System.out.println(resultSet);
while(resultSet.next()) {
int id = resultSet.getInt(1);
String name = resultSet.getString("name");
System.out.print(id +"ttt");
System.out.print(name +"n");
}
resultSet.close();
stmt.close();
conn.close();
}
@Test
public void ResultSet2() throws Exception {
//1、注册驱动
Class.forName("com.mysql.jdbc.Driver");
String url="jdbc:mysql://192.168.5.222:3306/test";
//这里的192.168.5.222:3306指的是我mysql服务器的ip如果是本机的mysql的话用下面这段
//String url="jdbc:mysql://127.0.0.1:3306/test";
//test指的是所需要用的数据库系统中的具体某一个数据库
String username="root";
String password="123456";
//数据库的账号密码
Connection conn= DriverManager.getConnection(url,username,password);
//sql
String sql="select * from sjj";
//4获取执行sql的对象
Statement stmt=conn.createStatement();
//6.执行查询,得到ResultSet
ResultSet resultSet=stmt.executeQuery(sql);
//处理ResultSet
System.out.println("book_idt|tbook_name");
//创建集合存放sjj对象
List list=new ArrayList<>();
System.out.println(resultSet);
while(resultSet.next()) {
sjj sjj=new sjj();
int id = resultSet.getInt(1);
String name = resultSet.getString("name");
System.out.print(id +"ttt");
System.out.print(name +"n");
sjj.setId(id);
sjj.setName(name);
list.add(sjj);
}
System.out.println(list);
resultSet.close();
stmt.close();
conn.close();
}
这里我们需要创建一个和实体类来存放数据
package pojo;
public class sjj {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "sjj{" +
"id=" + id +
", name='" + name + ''' +
'}';
}
}
三、 Statement
可以用于执行DML DDL DQL语句
package JDBC_API;
import org.testng.annotations.Test;
import java.sql.*;
//Statement
public class JDbc4_Statement {
@Test
public void testDML() throws Exception {
//
//1、注册驱动
Class.forName("com.mysql.jdbc.Driver");
String url="jdbc:mysql://192.168.5.222:3306/test";
String username="root";
String password="123456";
Connection conn= DriverManager.getConnection(url,username,password);
//sql
String sql="update sjj set id=10 where id=5";
//4获取执行sql的对象
Statement stmt=conn.createStatement();
//6.执行sql
int count=stmt.executeUpdate(sql);
System.out.println(count);
stmt.close();
conn.close();
}
@Test
public void jdbcDDL() throws Exception{
//1、注册驱动
Class.forName("com.mysql.jdbc.Driver");
String url="jdbc:mysql://192.168.5.222:3306/test";
String username="root";
String password="123456";
Connection conn= DriverManager.getConnection(url,username,password);
//sql
String sql="create database db2";
//4获取执行sql的对象
Statement stmt=conn.createStatement();
//6.执行sql 、、DDL语句返回值不再是数字。所以下面的方法注释掉
try {
stmt.executeUpdate(sql);
System.out.println("执行成功");
} catch (Exception e) {
System.out.println("执行失败");
throw new RuntimeException(e);
}
// if(count>0){
// System.out.println("执行成功");
// }else {
// System.out.println("执行失败");
// }
stmt.close();
conn.close();
}
}
四、做个登陆验证(假的-都是假的)
咱们这里用书籍id和名字做账号密码测试
//做个登录验证
@Test
public void ResultSet1() throws Exception {
//1、注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
String url="jdbc:mysql://192.168.5.222:3306/test";
//这里的192.168.5.222:3306指的是我mysql服务器的ip如果是本机的mysql的话用下面这段
//String url="jdbc:mysql://127.0.0.1:3306/test";
//test指的是所需要用的数据库系统中的具体某一个数据库
String username="root";
String password="123456";
//数据库的账号密码
Connection conn= DriverManager.getConnection(url,username,password);
//接收用户名和密码
String Username="仙逆";
String pwd="6";
String sql="select * from sjj where name='"+Username+"' and id="+pwd+"";
System.out.println(sql);
//获取sql对象
Statement stmt=conn.createStatement();
//执行sql语句
ResultSet rs=stmt.executeQuery(sql);
//判断登陆是否成功
if(rs.next()){
System.out.println("登陆成功");
}else {
System.out.println("登陆失败");
}
//释放资源
rs.close();
stmt.close();
conn.close();
}
结果
select * from sjj where name='仙逆' and id=6 登陆成功 =============================================== Default Suite Total tests run: 1, Passes: 1, Failures: 0, Skips: 0 =============================================== 进程已结束,退出代码0
演示sql注入
//演示sql注入
@Test
public void login_Inject() throws Exception {
//1、注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
String url="jdbc:mysql://192.168.5.222:3306/test";
//这里的192.168.5.222:3306指的是我mysql服务器的ip如果是本机的mysql的话用下面这段
//String url="jdbc:mysql://127.0.0.1:3306/test";
//test指的是所需要用的数据库系统中的具体某一个数据库
String username="root";
String password="123456";
//数据库的账号密码
Connection conn= DriverManager.getConnection(url,username,password);
//接收用户名和密码
String Username="xcxcxcc";//一个不存在的账号
String pwd="'' or '1'='1'";
String sql="select * from sjj where name='"+Username+"' and id="+pwd+"";
System.out.println(sql);
//获取sql对象
Statement stmt=conn.createStatement();
//执行sql语句
ResultSet rs=stmt.executeQuery(sql);
//判断登陆是否成功
if(rs.next()){
System.out.println("登陆成功");
}else {
System.out.println("登陆失败");
}
//释放资源
rs.close();
stmt.close();
conn.close();
}
结果注入成功
select * from sjj where name='xcxcxcc' and id='' or '1'='1' 登陆成功 =============================================== Default Suite Total tests run: 1, Passes: 1, Failures: 0, Skips: 0 =============================================== 进程已结束,退出代码0
日志
演示PreparedStatement预编译防止sql注入
在这里说明一下,只是使用这个方法的话仅有防注入功能,如果真的通过预编译提升性能请在连接url参数里设置打开!!!!!
//演示PreparedStatement预编译防止sql注入
@Test
public void login_Inject2() throws Exception {
//1、注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//useServerPrepStmts=true开启预编译功能
String url="jdbc:mysql://192.168.5.222:3306/test?useServerPrepStmts=true";
//这里的192.168.5.222:3306指的是我mysql服务器的ip如果是本机的mysql的话用下面这段
//String url="jdbc:mysql://127.0.0.1:3306/test";
//test指的是所需要用的数据库系统中的具体某一个数据库
String username="root";
String password="123456";
//数据库的账号密码
Connection conn= DriverManager.getConnection(url,username,password);
//接收用户名和密码
String Username="xcxcxcc";//一个不存在的账号
String pwd="'' or '1'='1'";
String sql="select * from sjj where name=? and id=?";
System.out.println(sql);
//获取sql对象
PreparedStatement pstmt=conn.prepareStatement(sql);
pstmt.setString(1,Username);
pstmt.setString(2,pwd);
ResultSet rs=pstmt.executeQuery();//运行时不再需要写语句
//判断登陆是否成功
if(rs.next()){
System.out.println("登陆成功");
}else {
System.out.println("登陆失败");
}
//释放资源
rs.close();
pstmt.close();
conn.close();
}
运行结果:
select * from sjj where name=? and id=? 登陆失败 =============================================== Default Suite Total tests run: 1, Passes: 1, Failures: 0, Skips: 0 ===============================================
改回来用户名和密码
//接收用户名和密码
String Username="仙逆";//一个不存在的账号
String pwd="6";
数据库预编译,自己查查吧
select * from sjj where name=? and id=? 登陆成功 =============================================== Default Suite Total tests run: 1, Passes: 1, Failures: 0, Skips: 0 =============================================== 进程已结束,退出代码0
日志多了一个预编译状态
在这里如果我们保持语句不变的情况下更改参数进行多次sql查询
数据库将会复用曾经的预编译,以此减少性能开销



