JDBC —— Java编程语言操作数据库的技术
Java中提供了一个技术:JDBC(Java database connection),JDBC代码都位于Java的java.jar包下,是Java专门用来提供的操作各种各样的数据库的工具。Java.jar包下提供的JDBC技术大部分都是接口interface,接口只是告诉了我们如果你要连接数据库,你应该怎么做,每一个方法代表什么含义,每一个接口基本上都没有实现类。
每个接口的实现类,每种数据库的具体如何使用JDBC连接,每一步方法如何操作,Java需要让数据库的服务厂商给我们提供。一般情况下,服务器厂商写好之后,都是给我们开发者提供了一个jar包,jar包中封装了连接对应数据库底层的实现。
一、JDBC如何操作数据库
预备环节:引入施工队 —— 导包 —— 数据库服务器厂商给我们提供的JDBC的实现包
1、选址,加载驱动
2、创建桥梁,建立连接
3、准备物资,在Java中创建一个SQL语句
4、准备一个小推车 —— 必须根据桥梁创建
5、小推车带着物资去数据库进行执行,
6、得到返回的结果,进行处理
7、毁车炸桥
代码详解版
package com.kang.jdbc01;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
/**
* JDBC操作数据库
*/
public class Demo01 {
public static void main(String[] args) {
Connection connection = null;
Statement statement = null;
/**
* mysql : com.mysql.jdbc.Driver com.mysql.cj.jdbc.Driver
* oracle : oracle.jdbc.driver.OracleDriver
*/
try {
/**
* 1、选址 —— 加载驱动
*/
Class.forName("com.mysql.cj.jdbc.Driver");
/**
* 2、创建和数据库之间的连接
* 最好需要三个要素:
* url:数据库的连接地址 ,不同的数据库的url写法是不一样的
* mysql: jdbc:mysql://ip:port/database_name?key=value&key=value...
* serverTimezone=UTC
* useUnicode=true
* characterEncoding=UTF-8
* username:数据库的用户名
* password:数据库的密码
*/
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/school_zb?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8", "root", "root");
/**
* 3、准备SQL语句
* DML
* DQL
* TCL
*/
String sql = "insert into student(student_age,student_sno,student_phone,student_name,student_department_id) values(18,'s025','19812344567','zs',2)";
/**
* 4、准备一个小推车:JDBC当中有两种小推车
* Statement —— 不能防止SQL注入
* PrepareStatement —— 可以预防SQL注入
*/
statement = connection.createStatement();
/**
* 5、小推车带着SQL语句去数据库执行
* DML:statement.executeUpdate(DMLSQL):int
* DQL:statement.executeQuery(DQLSQL):ResultSet
* DDL:statement.execute(DDLSQL):boolean
*/
int result = statement.executeUpdate(sql);
/**
* 6、处理返回结果
*/
if(result > 0){
System.out.println("执行成功,数据库受影响了" + result + "行!");
}else {
System.out.println("服务器内部异常,请稍后重试或者练习管理员!");
}
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} catch (SQLException e) {
throw new RuntimeException(e);
}finally {
/**
* 7、关闭资源 三个资源
* Connection
* Statement
* ResultSet(在执行DQL时需要关闭)
* 先创建的后关闭,后创建的先关闭
*/
if(statement != null) {
try {
statement.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
if(connection != null) {
try {
connection.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
}
}
无解析版
package com.kang.jdbc01;
import java.sql.*;
public class Demo02 {
public static void main(String[] args) {
Connection connection = null;
Statement statement = null;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/school_zb?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8","root","root");
//String sql = "update student set student_phone = '15678941234' where student_name = 'zs'";
String sql = "delete from student where student_id = 3";
statement = connection.createStatement();
int result = statement.executeUpdate(sql);
if(result > 0){
System.out.println("该语句影响了" + result+ "行!");
}else {
System.out.println("请稍后重试或联系服务商!");
}
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} catch (SQLException e) {
throw new RuntimeException(e);
}
if(statement != null){
try {
statement.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}if(connection != null){
try {
connection.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
}
package com.kang.jdbc01;
import java.sql.*;
/**
* JDBC操作数据库 —— 查询数据
*/
public class Demo03 {
public static void main(String[] args) {
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/school_zb?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8", "root", "root");
String sql = "select * from dept where department_id = 1";
statement = connection.createStatement();
resultSet = statement.executeQuery(sql);
//获取结果集中所有虚拟表格的数据
while(resultSet.next()){
//获取当前行的数据
int departmentId = resultSet.getInt("department_id");
String departmentName = resultSet.getString("department_name");
String leader = resultSet.getString("leader");
String departmentAddress = resultSet.getString("department_address");
String departmentIntro = resultSet.getString("department_intro");
int majorNumber = resultSet.getInt("major_number");
System.out.println(departmentId + departmentName + leader + departmentAddress + departmentIntro + majorNumber);
}
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} catch (SQLException e) {
throw new RuntimeException(e);
}finally {
if(resultSet != null){
try {
resultSet.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
if(statement != null){
try {
statement.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
if(connection != null){
try {
connection.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
}
}
SQL注入
package com.kang.jdbc01;
import javax.swing.*;
import java.sql.*;
/**
* JDBC两种小推车:
* Statement:不能防止SQL注入
* statement在执行SQL语句前,是带着参数一起去编译的,因此如果参数中出现了SQL中一些特殊字符,会被识别为SQL语句的一部分
* PreparedStatement:可以预防SQL注入
* 预编译小推车,执行SQL前,如果SQL中需要传递参数,那么使用占位符?把SQL语言编译了,后期执行的时候传入参数,所有的参数 全部当作普通的数据处理,而非SQL的特殊字符处理。
*/
public class Demo04 {
public static void main(String[] args) {
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
try {
String username = JOptionPane.showInputDialog("请输入用户名");
String password = JOptionPane.showInputDialog("请输入密码");
Class.forName("com.mysql.cj.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/school_zb?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8", "root", "root");
String sql = "select * from user where user_name='"+username+"' and password = '"+password+"'";
System.out.println(sql);
statement = connection.createStatement();
resultSet = statement.executeQuery(sql);
//获取结果集中所有虚拟表格的数据
while(resultSet.next()){
//获取当前行的数据
String userName = resultSet.getString("user_name");
String pass = resultSet.getString("password");
System.out.println(userName+pass);
}
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} catch (SQLException e) {
throw new RuntimeException(e);
}finally {
if(resultSet != null){
try {
resultSet.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
if(statement != null){
try {
statement.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
if(connection != null){
try {
connection.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
}
}
解决SQL注入
package com.kang.jdbc01;
import javax.swing.*;
import java.sql.*;
public class Demo05 {
public static void main(String[] args) {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
String username = JOptionPane.showInputDialog("请输入用户名");
String password = JOptionPane.showInputDialog("请输入密码");
Class.forName("com.mysql.cj.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/school_zb?serverTimezone=UTC&useUnicode=true&characterEncoding=UTF-8", "root", "root");
String sql = "select * from user where user_name=? and password =?";
//准备小推车 —— 顺带着SQL语句一起准备了 这样的话会把SQL语句给提前编译了
preparedStatement = connection.prepareStatement(sql);
//需要替换占位符
preparedStatement.setString(1,username);
preparedStatement.setString(2,password);
//执行SQL语句得到返回结果
resultSet = preparedStatement.executeQuery();
//获取结果集中所有虚拟表格的数据
while(resultSet.next()){
//获取当前行的数据
String userName = resultSet.getString("user_name");
String pass = resultSet.getString("password");
System.out.println(userName+pass);
}
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} catch (SQLException e) {
throw new RuntimeException(e);
}finally {
if(resultSet != null){
try {
resultSet.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
if(preparedStatement != null){
try {
preparedStatement.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
if