JDBC-MySql 01 JDBC操作MySql(增删改查)

第七章 JDBC

一、学习目标
  1. 理解JDBC原理
  2. 掌握Connection接口的使用
  3. 掌握Statement接口的使用
  4. 掌握ResultSet接口的使用
  5. 掌握PreparedStatement接口的使用
二、什么是JDBC?

JDBC(Java DataBase Connectivity)是Java数据库连接技术的简称。是Java和数据库之间的一个桥梁,主要提供连接各种常用数据库的能力 。

在这里插入图片描述

三、为什么需要JDBC?

数据想要持久化保存,就必须保存在磁盘中,而不是在内存中。对于程序中的数据,我们都是使用数据库管理系统来进行管理的,无非也就是增删改查,那么如果在Java程序中进行数据库的操作呢?这就需要使用到JDBC了。事实上,在Java中操作数据库的技术有好几种,比如最原始的JDBC方式,基于JDBC封装的MyBatis框架,或者是ORM框架HibernateSpirngDataJPA等。

所谓的JDBC其实就是一个典型的面向接口编程的案例,SUN公司只负责定义JDBC API接口(也就是 interface 类),但是不负责具体的实现类编写,具体实现类的编写交给各个数据库厂商去实现。这样的好处是,一旦底层更换数据库,Java代码中的程序也不需要去更改。这组操作数据库的API位于Java类库的 java.sql 和 javax.sql两个包下

四、JDBC体系结构

在这里插入图片描述

五、JDBC程序的编写步骤
  • 在Java程序中通过JDBC来操作数据库的步骤是固定的,如下:
  1. 加载并注册驱动程序 Class.forName(“com.mysql.cj.jdbc.Driver”)
  2. 创建Connection连接对象(即Java程序作为客户端与数据库服务器之间建立的那个socket连接,更确切的说是tcp连接)
  3. 创建Statement对象
  4. 执行SQL语句
  5. 获取ResultSet对象(如果不是查询操作,不会有这个步骤)
  6. 释放资源(网络连接总是要释放的,不然随着连接的增多,数据库服务器严重时可能会崩溃)
六、JDBC API

提供者: Sun公司

主要功能: 与数据库建立连接、执行SQL 语句、处理结果

内容: 供程序员调用的接口与类,集成在 java.sql 和javax.sql 包中 如:

1、DriverManager 类 驱动管理类

2、Connection 接口 连接对象

3、Statement 接口 执行对象

4、ResultSet 接口 结果集

6.1DriverManager
  • 提供者:Sun公司
  • 作用:管理各种不同的JDBC驱动
6.2JDBC 驱动
  • 提供者:数据库厂商
  • 作用:负责连接各种不同的数据库
6.3JDBC API主要功能:

与数据库建立连接、执行SQL 语句、处理结果

  • DriverManager :依据数据库的不同,管理JDBC驱动

  • Connection : 负责连接数据库并担任传送数据的任务

  • Statement : 由 Connection 产生、负责执行SQL语句

  • ResultSet: 负责保存Statement执行后所产生的查询结果

6.4Driver接口

Driver接口由数据库厂家提供,作为java开发人员,只需要使用Driver接口就可以了。在编程中要连接数据库,必须先装载特定厂商的数据库驱动程序,不同的数据库有不同的装载方法。如:

  • 装载MySql驱动:Class.forName(“com.mysql.jdbc.Driver”);

  • 装载Oracle驱动:Class.forName(“oracle.jdbc.driver.OracleDriver”);

6.5Connection接口

Connection与特定数据库的连接(会话),在连接上下文中执行sql语句并返回结果。

DriverManager.getConnection(url, user, password)方法建立在JDBC URL中定义的数据库Connection连接上。

//连接MySql数据库:
Connection conn = DriverManager.getConnection("jdbc:mysql://host:port/database", "user", "password");

//连接Oracle数据库:
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@host:port:database", "user", "password");

//连接SqlServer数据库:
Connection conn = DriverManager.getConnection("jdbc:microsoft:sqlserver://host:port; DatabaseName=database", "user", "password");
七、JDBC工作过程图解:

在这里插入图片描述

八、JDBC编程模板

在这里插入图片描述

九、数据库连接三要素
  1. java.sql.Driver 接口的实现类(JDBC API 和对应数据库服务器的连接就是靠这个接口的,否则接口和实现类如何建立联系呢?)

    • 这个驱动实现类是在各个数据库厂商提供的驱动程序中的
  2. 连接URL(这个url中指定了数据库服务器的网络地址和端口号,以及想要使用DBMS中的哪个数据库)

    • 这个URL其实就是相当于一个超链接,一个网址,只不过它采用的协议是jdbc协议而已。如下图驱动程序会根据这个URL的规则,去取出URL中有用的信息

在这里插入图片描述

  1. 用户名和密码(要想操作数据库,是必须要提供对应的用户名和密码以验证身份的)
    • 这个在JDBC API中可以单独指定,也可以直接把它拼接到url后的参数中
十、使用纯Java方式连接MySql数据库:
  • 由JDBC驱动直接访问数据库

  • 优点: 完全Java代码,快速、跨平台

  • 缺点: 访问不同的数据库需要下载专用的JDBC驱动

package cn.ketai.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

/**
 * @author Aiden
*/
public class JDBCDemo {
	/**
	 * 准备工作: 
	 * 1.从官网下载MySql驱动包:https://dev.mysql.com/downloads/file/?id=494900
	 * 2.将驱动包引入到项目工程中
	 */
	public static void main(String[] args) {
		Connection conn = null;//连接对象
		try {
			// 1.加载驱动
			Class.forName("com.mysql.cj.jdbc.Driver");
			// 2.建立数据库连接
			conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/epet?serverTimezone=Asia/Shanghai", "root", "root");
			// 判断是否连接成功
			if (conn != null) {
				System.out.println("连接成功。");
			} else {
				System.out.println("连接失败!!!");
			}
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			if (conn != null) {// 3.如果连接不为空则关闭当前连接
				try {
					conn.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}
	}
}
十一、使用Statement执行对象实现新增操作
package cn.ketai.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
/**
 * @author Aiden
 */
public class StatementDemo {

	public static void main(String[] args) {
		Connection conn = null;//连接对象
		Statement stmt = null;//执行对象
		try {
			// 1.加载驱动
			Class.forName("com.mysql.cj.jdbc.Driver");
			// 2.建立数据库连接
			conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/epet?serverTimezone=Asia/Shanghai", "root", "root");
			// 3.实例化执行对象
			stmt = conn.createStatement();
			// 4.准备要执行的新增Sql语句:
			String sql = "INSERT INTO `dog`(`name`,`health`,`love`,`strain`)VALUES ('阿牧',98,90,'牧羊犬');";
			// 5.开始执行并返回执行结果,返回受影响行数
			int result = stmt.executeUpdate(sql);
			if (result > 0) {
				System.out.println("操作成功");
			} else {
				System.out.println("操作失败!!!");
			}
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			if (stmt != null) {
				try {
					stmt.close();// 关闭执行对象
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
			if (conn != null) {
				try {
					conn.close();// 关闭当前连接
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}
	}
}
十二、使用Statement执行对象实现修改操作
package cn.ketai.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

/**
 * @author Aiden
 */
public class StatementDemo2 {

	public static void main(String[] args) {
		Connection conn = null;//连接对象
		Statement stmt = null;//执行对象
		try {
			// 1.加载驱动
			Class.forName("com.mysql.cj.jdbc.Driver");
			// 2.建立数据库连接
			conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/epet?serverTimezone=Asia/Shanghai", "root", "root");
			// 3.实例化执行对象
			stmt = conn.createStatement();
			// 4.准备要执行的修改Sql语句:
			String sql = "update dog set love=90,health=100 where id=1;";//变化执行的sql语句
			// 5.开始执行并返回执行结果,返回受影响行数
			int result = stmt.executeUpdate(sql);
			if (result > 0) {
				System.out.println("操作成功");
			} else {
				System.out.println("操作失败!!!");
			}
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			if (stmt != null) {
				try {
					stmt.close();// 关闭执行对象
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
			if (conn != null) {
				try {
					conn.close();// 关闭当前连接
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}
	}

}
十三、使用Statement和ResultSet实现查询操作
package cn.ketai.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

/**
 *    @author  Aiden   
 */
public class ResultSetDemo {

	public static void main(String[] args) {
		Connection conn = null;//连接对象
		Statement stmt = null;//执行对象
		ResultSet rs=null;//结果集
		try {
			// 1.加载驱动
			Class.forName("com.mysql.cj.jdbc.Driver");
			// 2.建立数据库连接
			conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/epet?serverTimezone=Asia/Shanghai", "root", "root");
			// 3.实例化执行对象
			stmt = conn.createStatement();
			// 4.准备要执行的查询Sql语句:
			String sql = "SELECT `id`,`name`,`health`,`love`,`strain` FROM `dog`;";
			//5.开始执行并返回执行结果
			rs=stmt.executeQuery(sql) ;
			//循环遍历显示
			System.out.println("编号\t名字\t健康值\t亲密度\t品种");
			while (rs.next()) {
				System.out.println(rs.getInt("id")+"\t"+rs.getString("name")+"\t"
			    +rs.getInt("health")+"\t"+rs.getInt("love")+"\t"+rs.getString("strain"));
			}
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			if(rs!=null) {
				try {
					rs.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
			if (stmt != null) {
				try {
					stmt.close();// 关闭执行对象
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
			if (conn != null) {
				try {
					conn.close();// 关闭当前连接
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

十四、Statement常用方法
方法名说 明
ResultSet executeQuery(String sql)执行SQL查询并获取到ResultSet对象
int executeUpdate(String sql)可以执行插入、删除、更新等操作,返回值是执行该操作所影响的行数**
boolean execute(String sql)可以执行任意SQL语句,然后获得一个布尔值,表示是否返回ResultSet
十五、ResultSet常用方法
方法名说 明
boolean next( )将游标从当前位置向下移动一行
boolean previous()游标从当前位置向上移动一行
void close()关闭ResultSet对象
int getInt(int colIndex)以int形式获取结果集当前行指定列号值
int getInt(String colLabel)以int形式获取结果集当前行指定列名值
float getFloat(int colIndex)以float形式获取结果集当前行指定列号值
float getFloat(String colLabel)以float形式获取结果集当前行指定列名值
String getString(int colIndex)以String形式获取结果集当前行指定列号值
String getString(String colLabel)以String形式获取结果集当前行指定列名值
十六、SQL注入
package cn.ketai.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;
/**
 * @author Aiden
 */
public class LoginDemo {
	public static void main(String[] args) {
		Connection conn = null;// 连接对象
		Statement stmt = null;// 执行对象
		ResultSet rs = null;// 结果集
		Scanner input = new Scanner(System.in);
		try {
			// 1.加载驱动
			Class.forName("com.mysql.cj.jdbc.Driver");
			// 2.建立数据库连接
			conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/epet?serverTimezone=Asia/Shanghai", "root", "root");
			// 3.实例化执行对象
			stmt = conn.createStatement();
			System.out.println("请输入用户名:");
			String name = input.next();
			System.out.println("请输入密码:");
			String password = input.next();
			// 4.拼接登录查询语句:
			String sql = " SELECT * FROM `master` WHERE `name`='" + name + "' AND `password`='" + password + "';";
			// 5.开始执行并返回执行结果
			rs = stmt.executeQuery(sql);
			if (rs.next()) {
				System.out.println("登录成功。");
			}else {
				System.out.println("登录失败,用户名密码错误!");
			}

		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			if (rs != null) {
				try {
					rs.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
			if (stmt != null) {
				try {
					stmt.close();// 关闭执行对象
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
			if (conn != null) {
				try {
					conn.close();// 关闭当前连接
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

测试结果:

请输入用户名:
李明
请输入密码:
123'or'1'='1
登录成功。
十七、如何避免SQL注入的隐患?

使用PreparedStatement 接口

  • 继承自 Statement接口
  • 比Statement对象使用起来更加灵活,更有效率
  • 提高了代码的可维护性,提高了安全性。
十八、PreparedStatement 执行对象
package cn.ketai.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;

/**
 * @author Aiden
 */
public class PreparedStatementDemo {
	public static void main(String[] args) {
		Connection conn = null;// 连接对象
		PreparedStatement pstmt = null;// 执行对象
		ResultSet rs = null;// 结果集
		Scanner input = new Scanner(System.in);
		try {
			// 1.加载驱动
			Class.forName("com.mysql.cj.jdbc.Driver");
			// 2.建立数据库连接
			conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/epet?serverTimezone=Asia/Shanghai", "root", "root");
			// 用户控制天输入
			System.out.println("请输入用户名:");
			String name = input.next();
			System.out.println("请输入密码:");
			String password = input.next();
			// 3.登录验证查询语句:
			String sql = " SELECT * FROM `master` WHERE `name`=? AND `password`=?;";
			// 4.实例化执行对象
			pstmt = conn.prepareStatement(sql);
			//5.设置参数
			pstmt.setObject(1, name);
			pstmt.setObject(2, password);
			// 5.开始执行并返回执行结果
			rs = pstmt.executeQuery();
			if (rs.next()) {
				System.out.println("登录成功。");
			} else {
				System.out.println("登录失败,用户名密码错误!");
			}
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			if (rs != null) {
				try {
					rs.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
			if (pstmt != null) {
				try {
					pstmt.close();// 关闭执行对象
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
			if (conn != null) {
				try {
					conn.close();// 关闭当前连接
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}
	}
}
十九、常见错误

使用JDBC连接数据库时,经常出现的错误

  1. JDBC驱动类的名称书写错误,导致ClassNotFoundException异常
  2. 数据连接字符串、数据库用户名、密码错误,导致SQLException异常
  3. 数据库操作结束后,没有关闭数据库连接,导致仍旧占有系统资源
  4. 关闭数据库连接语句没有放到finally语句块中,导致语句可能没有被执行
二十、本章总结

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

众生云海,一念初见

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

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

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

打赏作者

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

抵扣说明:

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

余额充值