1.基本概念
概念
JDBC(java database connectivity Java数据库连接
)是一种用于执行SQL语句的JavaAPI,可以为多种关系型数据库提供统一访问,由一组用Java语句编写的类和接口组成的
本质
Java官方提供的一套规范(接口)
,用于帮助开发者快速访问其使用的关系型数据库的连接
2.快速入门
导入相关jar包
//1、注册驱动
//mysql version版本为5
Class.forName("com.mysql.jdbc.Driver")
//mysql version版本为8
Class.forName("com.mysql.cj.jdbc.Driver");
//2、获取连接
Connection conn = DriverManager.getConnection("jdbc:mysql://连接ip地址:3306/数据库名称","用户名","密码");
//3、获取执行sql的对象并且执行
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select * from student");
/*
PreparedStatement pstmt = conn.prepareStatement("insert into user values (?,?,?)");
pstmt.setInt(1,12);
pstmt.setString(2,"zhangsan");
pstmt.setString(3,"nan");
int count = pstmt.executeUpdate();
*/
//4、处理结果
List<Student> stus = new ArrayList<>();
while(rs.next()){
Student stu = new Student();
int sid = rs.getInt("sid");
String name = rs.getString("name");
stu.setSid(sid);
stu.setName(name);
stus.add(stu);
}
//5、释放资源(遵循先用后关)
rs.close();
stmt.close();
conn.close();
JDBC功能类详解
DriverManager 驱动管理对象
1.注册驱动
-注册提供的驱动程序:static void registerDriver(Driver driver)
-编写代码:
version(5): Class.forName("com.mysql.jdbc.Driver")
version(8): Class.forName("com.mysql.cj.jdbc.Driver")
-com.mysql.jdbc.Driver类中存在静态代码块
![](https://img.haomeiwen.com/i26538554/cc2f156353d10e61.png)
注意:
- 不需要通过调用DriverManager中静态方法
registerDriver(Driver driver)
,因为只要Driver类被使用,则会执行静态代码快完成驱动注册,否则会出现重复注册,在new Driver对象是,需要先加载Driver类,加载这个类时,这个类中的static代码块会执行,在这个代码块中有一段代码就是DriverManager.registerDriver(new Driver())
; - mysql5之后可以省略注册驱动步骤
2.获取连接
获取数据集连接对象 static connection getConnection(string url, string username, string password)
参数说明:
url
:指定连接数据库
username
:用户名
password
:密码
Connection 数据库连接对象
- 获取执行者对象
普通执行者对象:Statement createStatement()
效率低,存在sql注入风险;
预编译执行者对象:Preparedstatement preparedstatement(String sql)
效率高,无注入风险; - 管理事务
开启事务:setAutoCommit(boolean autoCommit)
;参数为false,开启事务
提交事务:commit()
;
回滚事务:rollback()
; - 释放资源
立刻将数据库连接对象资源释放:void close()
;
Statement 执行sql语句对象
- 执行DML语句
int executeUpdate(String sql)
; - 执行DQL语句
resultSet executeQuery(String sql)
; - 释放资源:
void colse()
;
ResultSet查询结果集对象
- 判断结果集是否还有数据
boolean next()
初始行为行头;
有数据返回true,并索引向下移一行;无数据返回false;
-获取结果集的数据:XX getXxx(列名);
XX:表示返回值数据类型
ega:String getString("name")
|int getInt("age")
;
-释放资源void close()
;
SQL注入攻击
什么为SQL注入攻击
就是利用SQL语句的漏洞来对系统进行攻击
SQL注入攻击演示
//java代码
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println(username);
System.out.println(password);
try {
Connection conn = JdbcUtils1.getConn();
Statement statement = conn.createStatement();
ResultSet resultSet = statement.executeQuery("select * from student where sname = '" +username + "' and age = " +password + "");
System.out.println("select * from student where sname = '" +username + "' and age = " +password + "");
while (resultSet.next()) {
String sname = resultSet.getString("sname");
int age = resultSet.getInt("age");
System.out.println(sname + "==" + age);
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
//获取结果
username:qq
password: 20 or 1=1
SQL语句: select * from student where sname = 'qq ' and age = 20 or 1=1
结果集:
张三==18
李思思==19
李虎==20
李四==21
王五==22
qq==10
xx==60
qqq==28
//数据库数据
id sname age birthdate
1 张三 18 2020-10-01
2 李思思 19 2021-10-01
3 李虎 20 2021-10-02
4 李四 21 2021-10-03
5 王五 22 2021-10-04
7 qq 10 1994-04-29
8 xx 60 1994-04-29
16 qqq 28 1994-04-27
SQL注入攻击原理
- 按照正常的思维来说,密码处输入的内容应该是密码组成;
- 但通过上面的案例可以发现其中存在着巨大的漏洞发生在SQL语句的拼接上;
SQL注入攻击解决
使用预编译执行者对象Preparedstatement
1.在执行SQL语句之前,将SQL语句进行预编译;明确SQL语句的格式不变,剩余部分就都认为是参数
2.SQL语句中使用?为参数的占位符
![](https://img.haomeiwen.com/i26538554/6b97cb808e6c2577.png)
网友评论