Java中JDBC详解

👏作者简介:大家好,我是Rockey,不知名企业的不知名Java开发工程师
🔥如果感觉博主的文章还不错的话,请👍三连支持👍一下博主哦
📝联系方式:he18339193956,加我进群,大家一起学习,一起读书,一起对抗互联网寒冬👀

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站 点击跳转浏览。

JDBC是什么

概念:Java DataBase Connectivity

  • JDBC本质::其实是官方(sun公司)定义的一套操作所有关系型数据库的规则,即接口。 Java 访问数据库的标准规范.
  • 各个数据库厂商去实现这套接口,提供数据库驱动jar包。我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类。
    在这里插入图片描述

JDBC能做什么

连接数据库

为什么有JDBC

  1. 程序员如果要开发访问数据库的程序, 只需要会调用 JDBC 接口中的方法即可, 不用关注类是如何实现的。
  2. 使用同一套 Java 代码,进行少量的修改就可以访问其他 JDBC 支持的数据库

操作步骤

	1. 导入驱动jar包 mysql-connector-java-5.1.37-bin.jar
		1.复制mysql-connector-java-5.1.37-bin.jar到项目的libs目录下
		2.右键-->Add As Library
	2. 注册驱动
	3. 获取数据库连接对象 Connection
	4. 定义sql
	5. 获取执行sql语句的对象 Statement
	6. 执行sql,接受返回结果
	7. 处理结果
	8. 释放资源
		//1. 导入驱动jar包
        //2.注册驱动
        Class.forName("com.mysql.jdbc.Driver");
        //3.获取数据库连接对象
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db3", "root", "root");
        //4.定义sql语句
        String sql = "update account set balance = 500 where id = 1";
        //5.获取执行sql的对象 Statement
        Statement stmt = conn.createStatement();
        //6.执行sql
        int count = stmt.executeUpdate(sql);
        //7.处理结果
        System.out.println(count);
        //8.释放资源
        stmt.close();
        conn.close();

JDBC 的核心 API

在这里插入图片描述

DriverManager:驱动管理对象

  1. 管理和注册驱动
  2. 创建数据库的连接

类中的方法:
在这里插入图片描述
使用 JDBC 连接数据库的四个参数:
在这里插入图片描述
连接数据库的 URL 地址格式:
协议名:子协议://服务器名或 IP 地址:端口号/数据库名?参数=参数值
在这里插入图片描述
乱码的处理
如果数据库出现乱码,可以指定参数: ?characterEncoding=utf8,表示让数据库以 UTF-8 编码来处理数据。
jdbc:mysql://localhost:3306/数据库?characterEncoding=utf8

Connection 接口:

Connection 接口,具体的实现类由数据库的厂商实现,代表一个连接对象。
在这里插入图片描述

  1. 功能:
    1. 获取执行sql 的对象
    * Statement createStatement()
    * PreparedStatement prepareStatement(String sql)
    2. 管理事务:
    * 开启事务:setAutoCommit(boolean autoCommit) :调用该方法设置参数为false,即开启事务
    * 提交事务:commit()
    * 回滚事务:rollback()

Statement 接口

在这里插入图片描述
Statement 作用:
代表一条语句对象,用于发送 SQL 语句给服务器,用于执行静态 SQL 语句并返回它所生成结果的对象。
Statement 中的方法:
在这里插入图片描述
释放资源

  1. 需要释放的对象: ResultSet 结果集, Statement 语句, Connection 连接
  2. 释放原则:先开的后关,后开的先关。 ResultSet  Statement  Connection
  3. 放在哪个代码块中: finally 块

ResultSet:结果集对象,封装查询结果

  • boolean next(): 游标向下移动一行,判断当前行是否是最后一行末尾(是否有数据),如果是,则返回false,如果不是则返回true
    * getXxx(参数):获取数据
    * Xxx:代表数据类型 如: int getInt() , String getString()
    * 参数:
    1. int:代表列的编号,从1开始 如: getString(1)
    2. String:代表列名称。 如: getDouble(“balance”)

PreparedStatement:执行sql的对象

  1. SQL注入问题:在拼接sql时,有一些sql的特殊关键字参与字符串的拼接。会造成安全性问题
三、SQL注入攻击实例

比如在一个登录界面,要求输入用户名和密码:

可以这样输入实现免帐号登录:

用户名: ‘or 1 = 1 –

密 码:

点登陆,如若没有做特殊处理,那么这个非法用户就很得意的登陆进去了.(当然现在的有些语言的数据库API已经处理了这些问题)

这是为什么呢? 下面我们分析一下:

从理论上说,后台认证程序中会有如下的SQL语句:

String sql = "select * from user_table where username=

' "+userName+" ' and password=' "+password+" '";

当输入了上面的用户名和密码,上面的SQL语句变成:

SELECT * FROM user_table WHERE username=

'’or 1 = 1 -- and password='’

分析SQL语句:

条件后面username=”or 1=1 用户名等于 ” 或1=1 那么这个条件一定会成功;

然后后面加两个-,这意味着注释,它将后面的语句注释,让他们不起作用,这样语句永远都能正确执行,用户轻易骗过系统,获取合法身份。

这还是比较温柔的,如果是执行

SELECT * FROM user_table WHERE

username='' ;DROP DATABASE (DB Name) --' and password=''

….其后果可想而知…
2. 解决sql注入问题:使用PreparedStatement对象来解决
	3. 预编译的SQL:参数使用?作为占位符
	4. 步骤:
		1. 导入驱动jar包 mysql-connector-java-5.1.37-bin.jar
		2. 注册驱动
		3. 获取数据库连接对象 Connection
		4. 定义sql
			* 注意:sql的参数使用?作为占位符。 如:select * from user where username = ? and password = ?;
		5. 获取执行sql语句的对象 PreparedStatement  Connection.prepareStatement(String sql) 
		6. 给?赋值:
			* 方法: setXxx(参数1,参数2)
				* 参数1:?的位置编号 从1 开始
				* 参数2:?的值
		7. 执行sql,接受返回结果,不需要传递sql语句
		8. 处理结果
		9. 释放资源
  1. 注意:后期都会使用PreparedStatement来完成增删改查的所有操作
    1. 可以防止SQL注入
    2. 效率更高

案例

需求:确保数据库中有 3 条以上的记录,查询所有的学员信息
在这里插入图片描述

/**
* 查询所有的学生信息
*/
public class Demo6DQL {
public static void main(String[] args) throws SQLException {
		//1) 得到连接对象
		Connection connection =
		DriverManager.getConnection("jdbc:mysql://localhost:3306/day24","root","root");
		//2) 得到语句对象
		Statement statement = connection.createStatement();
		//3) 执行 SQL 语句得到结果集 ResultSet 对象
		ResultSet rs = statement.executeQuery("select * from student");
		//4) 循环遍历取出每一条记录
		while(rs.next()) {
		int id = rs.getInt("id");
		String name = rs.getString("name");
		boolean gender = rs.getBoolean("gender");
		Date birthday = rs.getDate("birthday");
		//5) 输出的控制台上
		System.out.println("编号: " + id + ", 姓名: " + name + ", 性别: " + gender + ", 生日: " +
		birthday);
	}
	//6) 释放资源
	rs.close();
	statement.close();
	connection.close();
	}
}

关于 ResultSet 接口中的注意事项:

  1. 如果光标在第一行之前,使用 rs.getXX()获取列值,报错: Before start of result set
  2. 如果光标在最后一行之后,使用 rs.getXX()获取列值,报错: After end of result set
  3. 使用完毕以后要关闭结果集 ResultSet,再关闭 Statement,再关闭 Connection

结语

🔥一个人可以掌握知识,但只有与他人交流才能形成智慧。
🔥One person can acquire knowledge, but wisdom is formed only in the exchange with others.
📝 欢迎大家关注博主公众号 Rockey小何同学 添加博主微信:he18339193956进群,一起学习,一起成长,一起提高认知。
🏆 我坚信人与人之间的差距是表面上是财富的差距,本质上是大脑中认知的差距,

我们下期再见。

  • 11
    点赞
  • 71
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

时间不会赖着不走

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值