1. 定义
Java DataBase Connectivity是一个独立于特定数据库的管理系统,通用的SQL数据库存取和操作的公共接口。
定义了一组标准,为访问不同数据库提供了同一途径。
2. JDBC体系结构
JDBC接口包括两个层面:
- 面向应用的API,供程序员调用
- 面向数据库的API,供厂商开发数据库的驱动程序
API:
- JDBC API
提供者:Java官方
内容:供开发者调用的接口
java.sql和javax.sql
类:DriverManager类、Connection接口、Statement接口、ResultSet接口 - JDBC Driver Manager
提供方:Java官方
作用:管理不同的JDBC驱动 - JDBC驱动
提供者:数据库厂商
作用:负责连接不同的数据库
3. JDBC的使用
- 加载数据库驱动,Java程序和数据库之间的桥梁
- 获取Connection,Java程序与数据库的一次连接
- 创建Statement对象,由Connection产生,执行SQL语句
- 如果需要接收返回值,创建ResultSet对象,保存Statement执行之后所查询到的结果
3.1 JDBC+MySQL代码案例
public static void main(String[] args) {
// 获取数据库连接
// 1.加载驱动(开发推荐方式)
try {
Class.forName("com.mysql.jdbc.Driver");
// 2.获取与数据库的连接
String url = "jdbc:mysql://localhost:3306/test?userUnicode=true&characterEncoding=UTF-8";
String username = "root";
String password = "123456";
Connection conn = DriverManager.getConnection(url, username, password);
System.out.println(conn);
//插入
String sql = "insert into student(id,name,score,birthday) values(3,'王五',78,'2019-01-01')";
Statement statement = conn.createStatement();
statement.executeUpdate(sql);
//查询
sql = "select * from student";
ResultSet resultSet = statement.executeQuery(sql);
while(resultSet.next()) {
Integer id = resultSet.getInt("id");//代表列名
String name = resultSet.getString(2);//代表列下标
Double score = resultSet.getDouble(3);
Date date = resultSet.getDate(4);
System.out.println(id+"-"+name+"-"+score+"-"+date);
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
3.2 PreparedStatement
Statement的子类,提供了SQL占位符的功能
使用Statement进行开发有两个问题:
- 需要频繁拼接String字符串,出错率较高
- 存在SQL注入的风险
SQL注入: 利用某些系统没有对用户输入的信息进行充分检测,在用户输入的数据中注入非法的SQL语句,从而利用系统的SQL引擎完成恶意行为的做法。
比如下列语句永远成立。
select * from t_user where username = 'lisi' or '1' = '1' and password = '000' or '1' = '1'
3.3 案例代码
不使用PrepareStatement
public static void main(String[] args) {
// 获取数据库连接
// 1.加载驱动(开发推荐方式)
try {
Class.forName("com.mysql.jdbc.Driver");
// 2.获取与数据库的连接
String url = "jdbc:mysql://localhost:3306/test?userUnicode=true&characterEncoding=UTF-8";
String user = "root";
String password = "123456";
Connection conn = DriverManager.getConnection(url, user, password);
String username = "lisi";
String mypassword = "000";
String sql = "select * from t_user where username = '" + username + "' and password = '"+mypassword + "'";
Statement statement = conn.createStatement();
ResultSet resultSet = statement.executeQuery(sql);
if(resultSet.next()) {
System.out.println("登陆成功");
} else {
System.out.println("登陆失败");
}
}catch(ClassNotFoundException e) {
e.printStackTrace();
}catch(SQLException e) {
e.printStackTrace();
}
}
使用PrepareStatement
登陆失败案例
package servlet;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Date;
public class Login {
public static void main(String[] args) {
// 获取数据库连接
// 1.加载驱动(开发推荐方式)
try {
Class.forName("com.mysql.jdbc.Driver");
// 2.获取与数据库的连接
String url = "jdbc:mysql://localhost:3306/test?userUnicode=true&characterEncoding=UTF-8";
String user = "root";
String password = "123456";
Connection conn = DriverManager.getConnection(url, user, password);
String username = "lisi' or '1' = '1";
String mypassword = "000' or '1' = '1";
// String sql = "select * from t_user where username = '" + username + "' and password = '"+mypassword + "'";
String sql = "select * from t_user where username = ? and password = ?";
System.out.println(sql);
PreparedStatement prepareStatement = conn.prepareStatement(sql);
prepareStatement.setString(1, username);
prepareStatement.setString(2, mypassword);
ResultSet resultSet = prepareStatement.executeQuery();
// Statement statement = conn.createStatement();
// ResultSet resultSet = statement.executeQuery(sql);
if(resultSet.next()) {
System.out.println("登陆成功");
} else {
System.out.println("登陆失败");
}
}catch(ClassNotFoundException e) {
e.printStackTrace();
}catch(SQLException e) {
e.printStackTrace();
}
}
}
将用户名和密码设置正确即可
String username = "lisi";
String mypassword = "000";
版权声明:本文为weixin_43820008原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。