JDBC(JAVA数据库连接)
1.JDBC简介
- JDBC:Java数据库连接,(Java Database Connectivity,简称JDBC)是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法。JDBC也是Sun Microsystems的商标。我们通常说的JDBC是面向关系型数据库的。
- 也就是说要用JAVA语言操作数据库 JAVA中提供了JDBC接口 我们可以通过JDBC来进行数据库的操作。
- JDBC 可以看作是一种JAVA对数据库的驱动
- 除了JAVA官方提供的 java.sql javax.sql 包外 要使用JDBC 还需要导入一个数据库驱动包mysql-connector-java-5.1.47.jar 你要连接哪个版本的数据库 就导入该数据库的驱动包即可。
2.一个具体的JDBC程序
2.1创建一个需要连接的数据库
代码如下:
CREATE DATABASE IF NOT EXISTS test
USE `test`
CREATE TABLE IF NOT EXISTS `患者`(
`姓名` VARCHAR(20) NOT NULL ,
`性别` VARCHAR (8) NOT NULL DEFAULT '男',
`年龄` INT(4) NOT NULL ,
`确诊日期` DATETIME NOT NULL,
`家庭住址` VARCHAR (20) NOT NULL ,
PRIMARY KEY (`姓名`)
)ENGINE =INNODB DEFAULT CHARSET = utf8
在SQLyog中执行如上语句 便 可创建一个名为test的数据库 库中有一个患者表格 储存了患者的信息。
这样我们便创建了一个需要连接的数据库 第一步完成!
2.2在JAVA项目中导入数据库驱动
将下载好的 mysql-connector-java-5.1.47.jar 数据库驱动包导入JAVA中
2.3编写代码建立连接
package javaa.jdbc.ml;
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
import java.sql.*;
//第一个JDBC程序
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 username ="root";
String password ="123456";
//3.连接成功,数据库对象 Connection 代表数据库
Connection connection = DriverManager.getConnection(url, username, password);
//4.执行SQL的对象 Statement 执行sql的对象
Statement statement = connection.createStatement();
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("PASSWORD="+resultSet.getObject("PASSWORD"));
System.out.println("email="+resultSet.getObject("birthday"));
}
///6/释放链接
resultSet.close();
statement.close();
connection.close();
}
}
分解以上步骤
2.3.1装在驱动程序(加载驱动)
装载驱动程序只需要非常简单的一行代码: Class.forName(“com.mysql.jdbc.Driver”); //固定写法 ,加载驱动
因为你连接的是mysql数据库 它的固定写法就是 Class.forName(“com.mysql.jdbc.Driver”);
2.3.2提供你的用户信息和url
String url ="jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=true";
如上 写法也是固定的,jdbc:mysql://localhost:3306 这串代码的意思是声明你的端口号
jdbcstudy是你要要操作的表格的名称 这个不是固定的
useUnicode=true&characterEncoding=utf8&useSSL=true";
这串代码表明 你的字符集是utf8 SSL连接是正确的
我们在连接mysql数据库的时候一般都会在url后面添加useUnicode=true&characterEncoding=UTF-8 ,但是问什么要添加呢?添加的作用是:指定字符的编码、解码格式。
String username ="root";
String password ="123456";
提供你数据库的用户名和密码
2.3.3根据你声明的信息建立连接 获取连接的对象
Connection connection = DriverManager.getConnection(url, username, password);
通过 DriverManager中的 getConnection()方法获取你要连接的数据库对象
Connection 代表数据库。
这个时候你已经成功的连接上你想连接的数据库了
2.3.4创建 JDBC Statements 对象 执行sql语句 完成对数据的增删查改操作
完成数据库的连接后,如何通过JAVA实行对数据的管理呢?
JDBC提供了三个类,用于向数据库发送SQL语句。Connection接口中的三个方法可用于创建这些类的实例。下面列出这些类及其创建方法:
⑴Statement:由方法createStatement所创建。Statement对象用于发送简单的SQL语句。
⑵PreparedStatement:由方法prepareStatement所创建。PreparedStatement对象用于发送带有一个或多个输入参数(IN参数)的SQL语句。PreparedStatement拥有一组方法,用于设置IN参数的值。执行语句时,这些IN参数将被送到数据库中。PreparedStatement的实例扩展了Statement,因此它们都包括了Statement的方法。PreparedStatement对象有可能比Statement对象的效率更高,因为它已被预编译过并存放在那以供将来使用。
⑶CallableStatement:由方法prepareCall所创建。CallableStatement对象用于执行SQL储存程序─一组可通过名称来调用(就象函数的调用那样)的SQL语句。CallableStatement对象从PreparedStatement中继承了用于处理IN参数的方法,而且还增加了用于处理OUT参数和INOUT参数的方法。
不过通常来说createStatement方法用于简单的SQL语句(不带参数)、prepareStatement方法用于带一个或多个IN参数的SQL语句或经常被执行的简单SQL语句,而prepareCall方法用于调用已储存过程。
Statement statement = connection.createStatement();
上述代码便创建了一个Statement对象 statement 用于发送简单的SQL语句
String sql ="SELECT * FROM `users`";
我们定义了一个查找的SQL语句
ResultSet resultSet = statement.executeQuery(sql);//通过ececuteQuery方法执行了SQL语句
statement.executeQuery的返回值是结果集 返回值类型为 ResultSet
statement.executeUpdate的返回值是变换的行数 返回值类型为int
2.3.5返回的结果集
需要注意的要点是:执行不同的SQL语句对应的方法也是不同的
我们使用 executeUpdate 方法是因为在 createTableCoffees 中的 SQL 语句是 DDL (数据定义语言)语句。创建表,改变表,删除表都是 DDL 语句的例子,要用 executeUpdate 方法来执行。你也可以从它的名字里看出,方法 executeUpdate 也被用于执行更新表 SQL 语句。实际上,相对于创建表来说,executeUpdate 用于更新表的时间更多,因为表只需要创建一次,但经常被更新。
被使用最多的执行 SQL 语句的方法是 executeQuery。这个方法被用来执行 SELECT 语句,它几乎是使用最多的 SQL 语句。
简要来说 执行增删改SQL语句的用 executeUpdate(sql)方法
执行查找SQL语句 用 executeQuery(sql)方法
2.3.6 释放连接节约资源
resultSet.close();
statement.close();
connection.close();
3.statement对象详述
Jdbc中的statement对象用于向数据库发送SQL语句,想完成对数据库的增删改查,只需要通过这个对象
向数据库发送增删改查语句即可。
Statement对象的executeUpdate方法,用于向数据库发送增、删、改的sql语句,executeUpdate执行
完后,将会返回一个整数(即增删改语句导致了数据库几行数据发生了变化)。
Statement.executeQuery方法用于向数据库发送查询语句,executeQuery方法返回代表查询结果的
ResultSet对象。
添加操作
1.封装SQL语句 String sql=" INSERT INTO `重症病人表` (`性别`,`年龄`,`确诊日期`,`家庭住址`) VALUES('男','21','2020-02-04 20:58:12','北影')"
2.创建Statement对象
Statement statement = connection.createStatement();
3.使用 Statement的executeQuery方法 传入sql语句参数 完成操作
ResultSet resultSet = statement.executeQuery(sql)
返回值为结果集
增删更新操作
1.封装SQL语句 String sql="UPDATE `重症病人表` SET `年龄`=90 WHERE `姓名`= '丁象' "
2.创建Statement对象
Statement statement = connection.createStatement();
3.使用 Statement的executeQuery方法 传入sql语句参数 完成操作
int a = statement.excuteUpdate(sql)
返回值为变换的行数
SQL注入
SQL是操作数据库数据的结构化查询语言,网页的应用数据和后台数据库中的数据进行交互时会采用SQL。而SQL注入是将Web页面的原URL、表单域或数据包输入的参数,修改拼接成SQL语句,传递给Web服务器,进而传给数据库服务器以执行数据库命令。如Web应用程序的开发人员对用户所输入的数据或cookie等内容不进行过滤或验证(即存在注入点)就直接传输给数据库,就可能导致拼接的SQL被执行,获取对数据库的信息以及提权,发生SQL注入攻击。
具体代码来说
package com.kuang.lesson02;
import com.kuang.lesson02.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class SQL注入 {
public static void main(String[] args) {
// login("kuangshen","123456");
login(" 'or '1=1"," 'or'1=1"); // 技巧
}
// 登录业务
public static void login(String username,String password){
Connection conn =null;
Statement st = null;
ResultSet rs = null;
try {
conn = JdbcUtils.getConnection();
st = conn.createStatement();
// SELECT * FROM users WHERE Name = 'kuangshen' AND password
= '123456';
// SELECT * FROM users WHERE Name = '' or '1=1' AND password
= '' or '1=1';
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 (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtils.release(conn,st,rs);
}
}
}
当你要查询的SQL语句后面的出现 WHERE 语句判定条件
攻击者会通过传达拼凑好的语句 " 'or '1=1"," 'or'1=1") 这样的话你的SQL语句的判定条件会失效
你的数据库会泄露
这就是SQL注入攻击
4.PreparedStatement对象
PreparedStatement 可以防止SQL注入。效率更好!
PreparedStatement:由方法prepareStatement所创建。PreparedStatement对象用于发送带有一个或多个输入参数(IN参数)的SQL语句。PreparedStatement拥有一组方法,用于设置IN参数的值。执行语句时,这些IN参数将被送到数据库中。PreparedStatement的实例扩展了Statement,因此它们都包括了Statement的方法。PreparedStatement对象有可能比Statement对象的效率更高,因为它已被预编译过并存放在那以供将来使用。
查询
package com.kuang.lesson03
import com.kuang.lesson02.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class TestSelect {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement st = null;
ResultSet rs = null;
try {
conn = JdbcUtils.getConnection();
String sql = "select * from users where id = ?"; // 编写SQL
st = conn.prepareStatement(sql); // 预编译
st.setInt(1,2); //传递参数
rs = st.executeQuery(); //执行
if (rs.next()){
System.out.println(rs.getString("NAME"));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtils.release(conn,st,rs);
}
}
}
先进行预编译 sql 对象
执行的时候在传递参数
可以有效防止SQL注入攻击
// PreparedStatement 防止SQL注入的本质,把传递进来的参数当做字符 //
假设其中存在转义字符,比如说 ' 会被直接转义