一、什么是JDBC?
1、JDBC简介
JDBC(Java DataBase Connectivity)是SUN 公司为了简化开发人员的(对数据库的统一)操作,提供了一个(Java操作数据库的)规范,俗称 JDBC。JDBC是Java和数据库之间的一个桥梁,是一个规范而不是一个实现,能够执行SQL语句。它由一组用Java语言编写的类和接口组成。各种不同类型的数据库都有相应的实现。
2、数据库驱动
在应用程序中通过数据库驱动和数据库进行数据的交互。
二、编写JDBC测试代码
测试的数据库代码:
CREATE DATABASE jdbcStudy CHARACTER SET utf8 COLLATE utf8_general_ci;
USE jdbcStudy;
CREATE TABLE users(
id INT PRIMARY KEY,
NAME VARCHAR(40),
PASSWORD VARCHAR(40),
email VARCHAR(60),
birthday DATE
);
INSERT INTO users(id,NAME,PASSWORD,email,birthday)
VALUES(1,'zhansan','123456','[email protected]','1980-12-04'),
(2,'lisi','123456','[email protected]','1981-12-04'),
(3,'wangwu','123456','[email protected]','1979-12-04');
1、导入jar包,添加数据库驱动
在项目目录下创建一个 lib 目录,将自己下载好的 jar 包拷贝进去,
然后右击 lib 目录,添加即可。
2、JDBC测试代码:
package com.hang.demo01;
import java.sql.*;
public class JDBCTest {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//1、加载驱动
Class.forName("com.mysql.jdbc.Driver");
//2、用户信息和URL
String url = "jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL" +
"=true";
String name = "root";
String password = "11235813";
//3、连接成功,获得数据库对象connection
Connection connection = DriverManager.getConnection(url, name, password);
// 4、获取执行SQL的对象statement
Statement statement = connection.createStatement();
//5、SQL的执行对象去执行SQL语句
String sql = "SELECT * FROM users";
ResultSet resultSet = statement.executeQuery(sql);
while (resultSet.next()) {
System.out.println("id="+resultSet.getObject("id"));
System.out.println("name="+resultSet.getObject("name"));
System.out.println("pwd="+resultSet.getObject("password"));
System.out.println("email="+resultSet.getObject("email"));
System.out.println("birth="+resultSet.getObject("birthday"));
System.out.println("------------------------------");
}
//6、释放连接
resultSet.close();
statement.close();
connection.close();
}
}
执行结果:
JDBC执行的步骤:
- 加载驱动
- 获取URL和用户信息,连接数据库
- 获取执行SQL的对象 Statement
- Statement 执行SQL语句,获取结果集
- 释放连接
三、JDBC中的对象
URL
String url = "jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=true";
//格式:协议://主机地址:端口号/数据库名?参数1&参数2&参数3;
//MySql默认端口号:3306 //Oracle默认端口号:1521
//使用Oracle数据库的写法:
//jdbc:oracle:thin@localhost:1521:sid
DriverManager
Connection connection = DriverManager.getConnection(url, username, password);
connection.commit();//提交事务
connection.rollback();//事务回滚
connection.setAutoCommit();//设置自动提交
Statement 执行SQL
statement.executeQuery(); //查询操作返回 ResultSet
statement.execute(); // 执行任何SQL
statement.executeUpdate(); // 更新、插入、删除,都是用这个,返回一个受影响的行数。
ResultSet 封装的结果集:所有的查询结果,这个结果集的本质是一个链表
// 如果知道字段列的类型就使用指定的类型
resultSet.getString();
resultSet.getInt();
resultSet.getFloat();
resultSet.getDate();
// 在不知道列类型的情况下使用
resultSet.getObject();
结果集中指针操作:
resultSet.beforeFirst(); // 移动到结果集链表最前面
resultSet.afterLast(); // 移动到结果集链表最后面
resultSet.next(); //移动到结果集链表下一个数据
resultSet.previous(); //移动到结果集链表前一行
resultSet.absolute(row); //移动结果集链表到指定行
四、Statement 对象
Jdbc中的statement对象用于向数据库发送SQL语句,想完成对数据库的增删改查,只需要通过这个对象向数据库发送增删改查语句即可。
Statement 的两个方法:
- executeUpdate(): 向数据库发送增、删、改的sql语句,executeUpdate执行完后,将会返回一个整数(即增删改语句导致了数据库几行数据发生了变化)。
- executeQuery(): 向数据库发送查询语句,executeQuery方法返回代表查询结果的ResultSet对象。
使用Statement进行增删改查(CRUD):
- Create: 对数据库进行增加数据的操作
示例:
Statement st = conn.createStatement();
String sql = "insert into user(...) values(...) ";
int num = st.executeUpdate(sql);
if(num>0){
System.out.println("插入成功!!!");
}
- Delete: 对数据库进行删除数据的操作
示例:
Statement st = conn.createStatement();
String sql = "delete from user where id=1";
int num = st.executeUpdate(sql);
if(num>0){
System.out.println(“删除成功!!!");
}
- Update: 对数据库进行修改数据的操作
示例:
Statement st = conn.createStatement();
String sql = "update user set name='' where name=''";
int num = st.executeUpdate(sql);
if(num>0){
System.out.println(“修改成功!!!");
}
- Read: 对数据库进行查询的操作
示例:
Statement st = conn.createStatement();
String sql = "select * from user where id=1";
ResultSet rs = st.executeQuery(sql);
while(rs.next()){
//根据获取列的数据类型,分别调用rs的相应方法映射到java对象中
}
五、创建JDBC工具类对数据库进行操作
JDBC驱动的配置文件
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=true
username=root
password=11235813
JDBC工具类
package Utils;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
public class jdbcUtils {
private static String driver = null;
private static String url = null;
private static String username = null;
private static String password = null;
//加载JDBC驱动的配置文件
static {
try {
InputStream in = jdbcUtils.class.getClassLoader().getResourceAsStream("database.properties");
Properties properties = new Properties();
properties.load(in);
driver = properties.getProperty("driver");
url = properties.getProperty("url");
username = properties.getProperty("username");
password = properties.getProperty("password");
//1、加载驱动
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
}
//2、获取连接
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url,username,password);
}
//3、释放连接
public static void release(Connection con, Statement sta, ResultSet res) {
if (res != null) {
try {
res.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (sta != null) {
try {
sta.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (con != null) {
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
向数据库中添加数据
public class TestInsert {
public static void main(String[] args) throws SQLException {
Connection con = null;
Statement sta = null;
ResultSet rea = null;
try {
String sql = "INSERT INTO users(id,`NAME`,`PASSWORD`,`email`,`birthday`)" +
"VALUES(4,'kaka','123456','[email protected]','2020-01-01')";
con = JdbcUtils.getConnection();
sta = con.createStatement();
int i = sta.executeUpdate(sql);
if (i > 0) {
System.out.println("插入成功");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtils.release(con,sta,rea);
}
}
}
删除数据库中的数据
package com.hang.demo01;
import com.hang.demo01.Utils.JdbcUtils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class TestDelete {
public static void main(String[] args) {
Connection con = null;
Statement sta = null;
ResultSet res = null;
try {
String sql = "DELETE FROM users WHERE id = 3";
con = JdbcUtils.getConnection();
sta = con.createStatement();
int i = sta.executeUpdate(sql);
if (i > 0) {
System.out.println("删除成功");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtils.release(con,sta,res);
}
}
}
修改数据库中的数据
public class TestUpdate {
public static void main(String[] args) {
Connection con = null;
Statement sta = null;
ResultSet res = null;
try {
String sql = "UPDATE users SET `NAME`= 'zhaohang' WHERE id = 1";
con = JdbcUtils.getConnection();
sta = con.createStatement();
int i = sta.executeUpdate(sql);
if (i > 0) {
System.out.println("修改成功!");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtils.release(con,sta,res);
}
}
}
查询数据库中的数据
public class TestQuery {
public static void main(String[] args) {
Connection con = null;
Statement sta = null;
ResultSet res = null;
try {
String sql = "SELECT * FROM users WHERE id = 1";
con = JdbcUtils.getConnection();
sta = con.createStatement();
res = sta.executeQuery(sql);
while (res.next()) {
System.out.println("id:"+res.getInt("id"));
System.out.println("name:"+ res.getString("NAME"));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtils.release(con,sta,res);
}
}
}
六、SQL注入
SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。
public class SQLInjection {
public static void main(String[] args) {
//login("zhaohang","8997978");
login("'or' 1=1","8997978");//通过这种方式即使不输入用户名,也可以查询到用户的信息
}
public static void login(String username,String password){
Connection conn =null;
Statement st = null;
ResultSet rs = null;
try {
conn = JdbcUtils.getConnection();
st = conn.createStatement();
String sql = "select * from users where `NAME`='"+username+"' AND `password` ='"+password+"'";
rs = st.executeQuery(sql); //查询完毕会返回一个结果集
while (rs.next()){
System.out.println(rs.getString("NAME"));
System.out.println(rs.getString("password"));
System.out.println("============================");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JdbcUtils.release(conn,st,rs);
}
}
}
PreparedStatement 对象:方式SQL注入
使用PreparedStatement的好处:
- 采用预编译语句集,它内置了处理SQL注入的能力,只要使用它的setXXX方法传值即可。
- .代码的可读性和可维护性.
- 极大地提高了安全性.