1 概述
JDBC(Java Database Connectivity)提供了大量的接口,是一种专门用来通过Java程序操作数据库的标准
2 使用步骤
(1)导入jar包(存放了大量Java工具类的压缩包)————该jar包要与数据库版本匹配;
(2)使用工具类,连接数据库 ————获取和数据库的连接;
(3)通过程序操作数据库 ————在程序中执行SQL语句;
(4)通过程序处理结果 ————数据库把结果返回给Java程序,Java程序再去解析结果。
2.1 导入jar包
在IDEA中创建一个project —> 在新建项目中创建一个名为lib的文件夹(右键新建项目 —> new —> directory)—> 导入jar包(将准备好的jar包直接复制粘贴到lib文件夹中)—> 编译jar包(右键导入的jar包 —> add as library)—> 检查是否成功导入jar包(原本导入的jar包没有可以展开的标识,编译成功后,该jar包会出现可展开的标识,具体如下图所示)
2.2 创建程序
在src文件夹中新建一个包(package),在该包中新建Java Class(.java文件),编写程序。
1、获取指定数据库中user表中的数据:
package day01;
import java.sql.*;
public class Test1 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//1、注册驱动
/* Driver在新导入的jar包中是字节码文件(.class文件)
* 所以要想注册驱动,需要利用反射调用Driver.class */
Class<?> aClass = Class.forName("com.mysql.jdbc.Driver");
//2、获取连接
/* 通过 DriverManager类中的 getConnection方法获取指定数据库连接
* getConnection(String url,String user,String password)方法中有三个参数:
* (1)url:访问数据库的 URL 路径。
* jdbc ————是连接数据库的协议
* mysql ————是jdbc的子协议,不同的数据库对应的该值不同
* localhost ————是连接的MySQL数据库服务器的主机IP地址(localhost表示连接的是本机地址)
* 3306 ————是MySQL数据库服务器的端口号
* TestDB ———— 是我们要连接的数据库名。
* MySQL中url地址写法:jdbc:mysql://localhost:3306/TestDB
* Oracle的写法:jdbc:oracle:thin:@localhost:1521:TestDB
* SQL Server的写法:jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=TestDB
* (2)user:连接数据库的用户名
* (3)password:用户名所对应的密码
* */
String url = "jdbc:mysql://localhost:3306/TestDB";
Connection c = DriverManager.getConnection(url, "root", "root");
//3、获取传输器
Statement s = c.createStatement();
//4、执行SQL
/* 通过调用传输器 s的executeQuery方法执行查询的SQL语句
* 并将查询的结果存入ResultSet类型的对象中 */
ResultSet res = s.executeQuery("select * from user");
//5、处理结果集 ————输出查询的所有结果
/* next() ————可以判断res是否还有记录(数据),底层会指向当前对应的一组数据
* getString() ————该方法中可以有两种参数:可以是表的列数,也可以是表中某列的字段名
* 通过该方法可以获取以String的形式获取此ResultSet对象的当前行中指定列的值。
* getInt() ————通过该方法可以获取以Int的形式获取此ResultSet对象的当前行中指定列的值。
* */
while (res.next()){
int col1 = res.getInt(1);
String col2 = res.getString("name");
String col3 = res.getString(3);
System.out.println( "id:" + col1 + "\t name:" + col2 + "\t password:" + col3);
}
//6、释放资源
/* JDBC程序执行结束后,需要将与数据库进行交互的对象释放掉
* 要释放的对象有 ResultSet,Statement,Connection对象
* 释放顺序:先使用的后释放 */
res.close();
s.close();
c.close();
}
}
运行结果:
id:202101 name:Jack password:123
id:202102 name:Bob password:123
id:202103 name:John password:123
2、简单模拟登录功能1——查询指定的用户名和密码是否正确
package day01;
import java.sql.*;
public class Test2 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//注册驱动
Class<?> aClass = Class.forName("com.mysql.jdbc.Driver");
//获取连接
String url = "jdbc:mysql://localhost:3306/TestDB";
Connection c = DriverManager.getConnection(url, "root", "root");
//获取传输器
Statement s = c.createStatement();
//执行SQL
String sql = "select * from user where name='Jack' and password='123'";
ResultSet res = s.executeQuery(sql);
//处理结果集
if (res.next()){
System.out.println("登录成功");
}else {
System.out.println("登录失败");
}
//释放资源
res.close();
s.close();
c.close();
}
}
运行结果:
登录成功
3、简单模拟登录功能2(传输器Statement)——查询从键盘中输入的用户名和密码是否正确
package day01;
import java.sql.*;
import java.util.Scanner;
public class Test3 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
Scanner input = new Scanner(System.in);
System.out.println("请输入用户名:");
String name = input.nextLine();
System.out.println("请输入密码:");
String password = input.nextLine();
//注册驱动
Class<?> aClass = Class.forName("com.mysql.jdbc.Driver");
//获取连接
String url = "jdbc:mysql://localhost:3306/TestDB";
Connection c = DriverManager.getConnection(url, "root", "root");
//获取传输器
Statement s = c.createStatement();
//执行SQL
String sql = "select * from user where name='"+name +"' and password='" + password + "'";
ResultSet res = s.executeQuery(sql);
//处理结果集
if (res.next()){
System.out.println("登录成功");
}else {
System.out.println("登录失败");
}
//释放资源
res.close();
s.close();
c.close();
}
}
输入正确的用户名和密码的运行结果:
请输入用户名:
jack
请输入密码:
123
登录成功
输入错误的用户名的运行结果:
请输入用户名:
qqq
请输入密码:
123
登录失败
上述模拟登录功能有弊端(SQL注入攻击):当输入特殊数据,例如:输入用户名Jack ’ # 不输入密码或输入一个错误的密码,程序仍然可以登录成功
请输入用户名:
Jack'#
请输入密码:
登录成功
因为在SQL语句中,“#”表示注释,加上“#”后,相当于只满足一个名字的条件即可登录成功
SELECT * FROM USER WHERE NAME = 'Jack' and password = '123';
SELECT * FROM USER WHERE NAME = 'Jack'# 'and password = '123';
4、简单模拟登录功能2的改进(传输器PreparedStatement)——查询从键盘中输入的用户名和密码是否正确
因为Statement传输器的功能不够强大,不安全(容易出现SQL注入攻击的现象),且低效,所以用PreparedStatement传输器来替代。
package day01;
import java.sql.*;
import java.util.Scanner;
public class Test4 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
Scanner input = new Scanner(System.in);
System.out.println("请输入用户名:");
String name = input.nextLine();
System.out.println("请输入密码:");
String password = input.nextLine();
Class<?> aClass = Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/cgb2106";
Connection c = DriverManager.getConnection(url, "root", "root");
//获取传输器 ,执行SQL
//SQL骨架,其中 ?表示占位符
String sql = "select * from user where name = ? and password = ? ";
//使用PreparedStatement传输器
PreparedStatement p = c.prepareStatement(sql);
//设置参数
/* setXX()方法——表示将指定参数设置为给定XX类型的值。
* 其中要写两个参数,第一个参数表示给第几个占位符“?”设置值;
* 第二个参数表示给指定的占位符赋值
**/
p.setString(1, name);
p.setString(2, password);
ResultSet res = p.executeQuery();
//处理结果集
if (res.next()) {
System.out.println("登录成功");
} else {
System.out.println("登录失败");
}
//释放资源
res.close();
p.close();
c.close();
}
}
输入正确的用户名和密码的运行结果:
请输入用户名:
Jack
请输入密码:
123
登录成功
输入错误的用户名(Jack’# )的运行结果:
请输入用户名:
Jack'#
请输入密码:
登录失败
Statement和PreparedStatement的区别:
Statement: 不安全(容易出现注入攻击的现象);效率低;SQL语句需要拼接,比较复杂。
PreparedStatement: 安全;效率相对高;不需要SQL拼接,可以直接用,用占位符“?”来表示对应的条件。