一:JDBC简介
我们学习了数据库,数据库实现了数据的持久化,但我们最终要在程序里处理数据啊,那java代码中怎么去访问数据库读写数据呢?这就要用到sun公司设定的一套数据库标准了,这套标准就是JDBC(Java Database Connectivity)。
但它只是规范,不做具体实现。于是数据库厂商又根据JDBC标准,实现自家的驱动Driver。如:mysql驱动com.mysql.cj.jdbc.Driver,Oracle的驱动oracle.jdbc.OracleDriver。有了这套解决方案,java就可以访问数据库中的数据了。
一句话概括:JDBC就是我们用IDEA连接数据库的工具,通过它可以实现在IDEA中对MYSQL进行增删改查的操作。
二:步骤
1.在idea中创建一个项目,并导入JDBCjar包
这里需要注意一点:你安装的哪个版本的 Mariadb 就需要安装对应版本的jar包(需要私我)
mariadb | mysql |
10.2/10.3/10.4 | 5.7 |
10.5 | 8.0 |
2.然后就可以开始写案例了.
package cn.tedu.review;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class TestJdbc {
public static void main(String[] args) throws Exception {
Class.forName("com.mysql.cj.jdbc.Driver"); //注册驱动器
String url ="jdbc:mysql://localhost:3306/cgb201901";//指定连接的数据库
//遵循的协议:IP地址:端口号 /数据库名
String user="root";//用户名
String pwd ="root";//密码
Connection c = DriverManager.getConnection(url, user, pwd);//获取连接器
Statement s = c.createStatement();//获取传输器
//s.executeUpdate("update emp set ename ='rousi' where emptno =1");//增删改用executeUpdate()方法,然后再查询
ResultSet r = s.executeQuery("select * from emp");//查询使用executeQuery()
while (r.next()){//此处调用r.next()方法:判断是否还有元素
for (int i = 1; i <4 ; i++) {//利用for循环对结果进行遍历,表中有几列就遍历几次
System.out.print(r.getObject(i));/*调用r.getObject方法可以获得数字,字符串所有类型的元素*/
}
System.out.println();
}
r.close();//关流
s.close();
c.close();
}
}
前面的几步都比较固定,可以将其进行封装提高复用性。
三:JDBC模拟用户登录系统
1.在数据库中创建一个模拟用户资料的表格。
CREATE TABLE IF NOT EXISTS `user`(
`name` VARCHAR(20) NOT NULL COMMENT '姓名',
`password` VARCHAR(20) NOT NULL COMMENT '密码')
ENGINE=INNODB DEFAULT CHARSET=utf8;
INSERT INTO `user`(`name`,`password`)
VALUE('jack',123456),('rousi',666666)
2.写JDBC代码
package cn.tedu.review;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Scanner;
public class TestJdbc {
public static void main(String[] args) throws Exception {
Class.forName("com.mysql.cj.jdbc.Driver");//注册驱动器
String url ="jdbc:mysql://localhost:3306/cgb201901";//指定连接的数据库
//遵循的协议:IP地址:端口号 /数据库名
String user="root";//用户名
String pwd ="root";//密码
Connection c = DriverManager.getConnection(url, user, pwd);//获取连接器
Statement s = c.createStatement();//获取传输器
System.out.println("请输入您的名字");
String name = new Scanner(System.in).nextLine();
System.out.println("请输入您的密码");
String passWord = new Scanner(System.in).nextLine();
String sql ="select * from user where name = '"+name+"'and passWord='"+passWord+"'";
ResultSet r = s.executeQuery(sql);
if (r.next()){//我们在数据库中查询数据,如果有证明账户存在,即登陆成功。
System.out.println("恭喜您登陆成功");
}else {
System.out.println("登陆失败");
}
r.close();
s.close();
c.close();
}
}
运行输入正确的账户密码提示登陆成功。
3.SQL攻击(SQL注入)
虽然咱们登陆成功,但是存在一个很严重的bug。演示如下:
当我们在名字出输入:jack' # 后 系统也成功登陆,这就是SQL攻击(SQL注入)。
原因:用户可以输入任意内容,而传输器只会单纯拼接内容,而无法识别特殊符号,致使MYSQL执行的时候也连同特殊符号一起执行,而#是注释,会注释掉后面所有内容。
解决方案:既然这个传输器不行,咱们就换一个传输器。
4.PreparedStatement 传输器
package cn.tedu.review;
import java.sql.*;
import java.util.Scanner;
public class TestJdbc1 {
public static void main(String[] args) throws Exception {
Class.forName("com.mysql.cj.jdbc.Driver");//注册驱动器
String url ="jdbc:mysql://localhost:3306/cgb201901";//指定连接的数据库
//遵循的协议:IP地址:端口号 /数据库名
String user="root";//用户名
String pwd ="root";//密码
Connection c = DriverManager.getConnection(url, user, pwd);//获取连接器
String sql="select * from user where name = ?and passWord=?";//sql骨架,‘?’叫做占位符
PreparedStatement p = c.prepareStatement(sql);//prepareStatement传输器的使用方法是需要sql语句参数
System.out.println("请输入您的名字");
String name = new Scanner(System.in).nextLine();
System.out.println("请输入您的密码");
String passWord = new Scanner(System.in).nextLine();
p.setObject(1,name);//setObject()是给对应下标占位符赋予数值
p.setObject(2,passWord);
ResultSet r = p.executeQuery();
if (r.next()){
System.out.println("恭喜您登陆成功");
}else {
System.out.println("登陆失败");
}
r.close();
p.close();
c.close();
}
}
结果就是我们解决了sql攻击问题,再次输入注释符#已经不起作用了。
原理:我们使用prepareStatement传输器,在sql语句中用占位符‘?’提前预定了name和password的位置,输入的内容就会判定为name 和password 的内容,不再进行拼接。