文章目录
- 一、JDBC技术
- 1.1、JDBC概念
- 1.2、JDBC作用
- 1.3、JDBC工作原理
- 1.4、JDBC工作流程
- 二、使用JDBC访问数据库
- 2.1、创建Maven项目
- 2.2、添加数据库依赖
- 2.2.1、mysql依赖
- 2.2.2、oracle依赖
- 2.3、编写代码
- 2.3.1、加载驱动
- 2.3.2、通过DriverManager获取connection连接
- 2.3.3、执行SQL语句
- 2.3.4、获取执行返回值
- 2.3.5、释放资源
- 三、使用JDBC访问数据库代码
- 3.1、增
- 3.2、删
- 3.3、改
- 3.4、查
- 四、Statement与PreparedStatement
- 4.1、两者之间的关系:
- 4.2、两者之间的区别:
- 4.2.1、statement使用
- 4.3、Statement执行容易出现情况(SQL注入)
一、JDBC技术
1.1、JDBC概念
JDBC(Java DataBase Connectivity)是一种Java数据库连接技术,能实现Java程序对各种数据库的访问。由一组使用Java语言编写的类和接口组成,这些类和接口称为JDBC API,它们位于java.sql以及javax.sql包中。
1.2、JDBC作用
- 建立与数据库之间的访问连接。
- 将编写好的SQL语句发送到数据库执行。
- 对数据库返回的结果进行处理。
1.3、JDBC工作原理
- JDBC API 定义了一系列的接口和类,集成在java.sql和javax.sql包中
- DriverManager 管理各种不同的JDBC驱动
- JDBC驱动 负责连接不同类型的数据库
1.4、JDBC工作流程
二、使用JDBC访问数据库
2.1、创建Maven项目
2.2、添加数据库依赖
2.2.1、mysql依赖
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.29</version>
</dependency>
2.2.2、oracle依赖
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.4</version>
</dependency>
2.3、编写代码
2.3.1、加载驱动
// mysql驱动
Class.forName("com.mysql.jdbc.Driver");
// oracle驱动
Class.forName("oracle.jdbc.driver.OracleDriver");
2.3.2、通过DriverManager获取connection连接
mysql
- mysql路径 jdbc:mysql://mysql地址:端口/数据库名
- mysql默认端口为3306
oracle
- oracle路径 jdbc:oracle:thin:@oracle地址:端口:数据库实例名
- oracle默认端口为1521
//参数(路径,用户名,密码)
// mysql
connection = DriverManager.getConnection("jdbc:mysql://192.168.136.204:3306/jdbcdb", "root", "root");
// oracle
connection = DriverManager.getConnection("jdbc:oracle:thin:@192.168.136.52:1521:prod", "taibai", "fei");
2.3.3、执行SQL语句
创建PreparedStatement实例执行sql语句
String sql = "insert into dog (name,health,love,strain,lytm) values (?,?,?,?,now())";
String name = "小黑子";
Integer health = 100;
Integer love = 68;
String strain = "泰迪";
Date lytm = new Date(System.currentTimeMillis());
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1,name);
preparedStatement.setInt(2,health);
preparedStatement.setInt(3,love);
preparedStatement.setString(4,strain);
// preparedStatement.setDate(5,lytm);
2.3.4、获取执行返回值
int result = preparedStatement.executeUpdate();
if (result > 0){
System.out.println("新增"+name+"成功");
}
2.3.5、释放资源
preparedStatement.close();
connection.close();
三、使用JDBC访问数据库代码
3.1、增
package org.example.ceshi;
import java.sql.*;
/**
* @program: jdbcstu
* @interfaceName Dog
* @description:
* @author: 太白
* @create: 2023-01-02 14:39
**/
public class Dog {
public static void main(String[] args) {
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql://192.168.136.204:3306/jdbcdb", "root", "root");
// 增
String sql = "insert into dog(name,health,love,strain,lytm) value (?,?,?,?,now())";
String name = "可鲁可";
Integer health = 99;
Integer love = 100;
String strain = "哈士奇";
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1,name);
preparedStatement.setInt(2,health);
preparedStatement.setInt(3,love);
preparedStatement.setString(4,strain);
int insert = preparedStatement.executeUpdate();
if (insert > 0) {
System.out.println("添加狗狗"+name+"成功");
}
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
try {
if (connection != null){
connection.close();
}
if (preparedStatement != null){
preparedStatement.close();
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
}
3.2、删
package org.example.ceshi;
import java.sql.*;
/**
* @program: jdbcstu
* @interfaceName Dog
* @description:
* @author: 太白
* @create: 2023-01-02 14:39
**/
public class Dog {
public static void main(String[] args) {
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql://192.168.136.204:3306/jdbcdb", "root", "root");
// 删
String sql = "delete from dog where id = ?";
Integer id = 8;
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1,id);
int delete = preparedStatement.executeUpdate();
if (delete > 0){
System.out.println("删除id为"+id+"成功");
}
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
try {
if (connection != null){
connection.close();
}
if (preparedStatement != null){
preparedStatement.close();
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
}
3.3、改
package org.example.ceshi;
import java.sql.*;
/**
* @program: jdbcstu
* @interfaceName Dog
* @description:
* @author: 太白
* @create: 2023-01-02 14:39
**/
public class Dog {
public static void main(String[] args) {
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql://192.168.136.204:3306/jdbcdb", "root", "root");
// 改
String sql = "update dog set name=?,health=?,love=?,strain=? where id=?";
String name = "阿黄";
Integer health = 89;
Integer love = 99;
String strain = "柴犬";
Integer id = 7;
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1,name);
preparedStatement.setInt(2,health);
preparedStatement.setInt(3,love);
preparedStatement.setString(4,strain);
preparedStatement.setInt(5,id);
int update = preparedStatement.executeUpdate();
if (update > 0){
System.out.println("修改id为"+id+"成功");
}
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
try {
if (connection != null){
connection.close();
}
if (preparedStatement != null){
preparedStatement.close();
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
}
3.4、查
package org.example.ceshi;
import java.sql.*;
/**
* @program: jdbcstu
* @interfaceName Dog
* @description:
* @author: 太白
* @create: 2023-01-02 14:39
**/
public class Dog {
public static void main(String[] args) {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql://192.168.136.204:3306/jdbcdb", "root", "root");
// 查
String sql = "select id,name,health,love,strain,lytm from dog";
preparedStatement = connection.prepareStatement(sql);
resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
System.out.print(resultSet.getInt("id"));
System.out.print(resultSet.getString("name"));
System.out.print(resultSet.getInt("health"));
System.out.print(resultSet.getInt("love"));
System.out.print(resultSet.getString("strain"));
System.out.println(resultSet.getDate("lytm"));
}
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
try {
if (connection != null){
connection.close();
}
if (preparedStatement != null){
preparedStatement.close();
}
if (resultSet!=null){
resultSet.close();
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
}
四、Statement与PreparedStatement
4.1、两者之间的关系:
preparedstatement和statement两者都是用来执行sql查询语句的API之一。
preparedstatement接口继承了statement接口。
4.2、两者之间的区别:
statement不对sql语句做处理,直接交给数据库;而prepraedstatement是支持预编译的,会将编译好的sql语句放在数据库端,相当于缓存,对于多次重复执行的sql语句,使用prepraedstatement可以使得代码的执行效率更高。
使用statement对象,在数据库只执行一次存取的时候,用statement对象进行处理,prepraedstatement对象的开销对statement大,对于一次性操作并不会带来额外的好处。
执行许多sql语句的JDBC程序产生大量的statement和preparedstatement对象,通常以为preparedstatement比statement对象更有效。
statement的sql语句使用字符串拼接的方式,非常容易导致出错,且存在sql注入的风险,preparedstatement使用“?”占位符,提升了代码的可读性和可维护性,并且这种绑定参数的方式可以有效地防止sql注入。
4.2.1、statement使用
在statement.execute的方法官方解释为:
执行给定的SQL语句,该语句可能返回多个结果。在某些(不常见的)情况下,一条SQL语句可能返回多个结果集和/或更新计数。通常你可以忽略它,除非你(1)执行一个你知道可能返回多个结果的存储过程,或者(2)动态执行一个未知的SQL字符串。 execute方法执行一条SQL语句并指示第一个结果的形式。然后必须使用getResultSet或getUpdateCount方法检索结果,并使用getMoreResults方法移动到任何后续结果。 注意:该方法不能在PreparedStatement或CallableStatement上调用。 形参: sql -任何sql语句 返回值: 如果第一个结果是ResultSet对象,则为true;如果是更新计数或没有结果,则为False
String name = "可鲁可";
Integer health = 99;
Integer love = 100;
String strain = "哈士奇";
String sql = "insert into dog (name,health,love,strain,lytm) values ('"+name+"','"+health+"','"+love+"','"+strain+"',now())";
statement = connection.createStatement();
statement.execute(sql);
4.3、Statement执行容易出现情况(SQL注入)
在此处这些变量都应该为页面传值,可能会传值为:
String name = “; drop database jdbc; drop table dog;”;
那么执行的sql语句就会是:
insert into dog (name,health,love,strain,lytm)
values (“; drop database jdbc; drop table dog;”,99,100,“哈士奇”,now());
那么在数据库中上述SQL语句执行顺序为:
- 由于insert into dog (name,health,love,strain,lytm) values ("; 语句报错
- 会执行下一条语句:drop database jdbc;
- 再下一条语句:drop table dog;
- 最后:",99,100,“哈士奇”,now()); 这条也会报错
这样的执行就会导致数据库与表皆都被删除。
上述过程就为SQL注入。