Java学习笔记-Day31 Java JDBC(一)



一、JDBC的API


Java数据库连接 JDBC(Java Database Connectivity),是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法。

1、Driver类


Driver:驱动程序,会将自身加载到 DriverManager 中去,处理相应的请求并返回相应的数据库连接(Connection)。

  • com.mysql.jdbc.Driver的字节码文件

在这里插入图片描述

Driver 为 com.mysql.jdbc.Driver,在 mysql-connector-java-xxxxx.jar 文件中。该文件的下载地址为:https://downloads.mysql.com/archives/c-j/

在这里插入图片描述
如果想要使用Driver,就必须添加 mysql-connector-java-xxxxx.jar 到项目的 Referenced Libraries中。Referenced Libraries 是存放第三方的 jar 包,也就是存放个人导入的 jar 包。

添加 mysql-connector-java-xxxxx.jar 到 Referenced Libraries 的步骤:

(1)将 mysql-connector-java-xxxxx.jar 文件添加到项目的 src 文件夹中。

在这里插入图片描述
(2)选择 mysql-connector-java-xxxxx.jar 文件,右键点击,选择 Build Path -> Add to Build Path。

在这里插入图片描述
(3)此时,项目中会出现 Referenced Libraries,在Referenced Libraries中会存放 mysql-connector-java-xxxxx.jar 文件。

在这里插入图片描述

  • 加载驱动到虚拟机
	Class.forName("com.mysql.jdbc.Driver");

2、DriverManager类


DriverManager:负责加载各种不同驱动程序(Driver),并根据不同的请求,向调用者返回相应的数据库连接(Connection)。

DriverManager 为 java.sql.DriverManager 。

  • 通过DriverManager.getConnection得到一个数据库连接对象
	Connection conn = DriverManager.getConnection(url, user, password);
  • 部分方法

static Connection getConnection(String url, String user, String password) :尝试建立与给定数据库URL的连接。

① url是统一资源定位符,这里的url是数据库的地址,如: String url = "jdbc:mysql://localhost:3306/schooldb";
② user是数据库的用户名,如:String user = "root";
③ password是数据库的用户的密码,如:String password = "root";

3、Connection接口


Connection:数据库连接,负责与数据库进行通讯,SQL执行以及事务处理都是在某个特定Connection环境中进行的。Connection可以产生用以执行SQL的Statement。

Connection为 java.sql.Connection。

  • 部分方法

(1) 创建一个Satement对象

Statement createStatement():创建一个 Statement对象,用于将SQL语句发送到数据库。

	Statement stmt = conn.createStatement();


(2)创建一个PreparedSatement对象

PreparedStatement prepareStatement(String sql):创建一个 PreparedStatement对象,用于将参数化的SQL语句发送到数据库。

sql是sql语句

	String sql = "SELECT * FROM grade";
	prepareStatement ps = conn.prepareStatement(sql);

(3)事务相关的方法

void commit() throws SQLException:提交事务。

void rollback() throws SQLException:撤销在当前事务中所做的所有更改。

void setAutoCommit(boolean autoCommit) throws SQLException:将此连接的自动提交模式设置为给定状态。

4、Statement接口


Statement:用于执行单次的静态SQL语句并返回其生成的结果的对象。

Statement为 java.sql.Statement。

(1)执行查询的SQL语句,获得结果集

ResultSet executeQuery(String sql):执行给定的SQL语句,该语句返回单个 ResultSet对象。

	Statement stmt = conn.createStatement();
	ResultSet rs = stmt.executeQuery(sql);

注意:

executeQuery方法返回该查询生成数据的ResultSet对象,不管是否有查到数据,rs 都不为 null。如果 rs 有值,则rs.next()方法返回值为true。如果 rs 没有值,则rs.next()方法返回值为false。

(2)执行增加、修改、删除的SQL语句

int executeUpdate(String sql):执行给定的SQL语句,这可能是 INSERT、UPDATE 或 DELETE语句,或者不返回任何内容,如SQL DDL语句的SQL语句。返回值为SQL数据操作语句的行数。

	Statement stmt = conn.createStatement();
	int n = stmt.executeUpdate(sql);

5、PreparedStatement接口


PreparedStatement:用以执行包含动态参数的SQL查询和更新。

PreparedStatement可以使用占位符,是可以预编译的。PreparedStatement比Statement 更安全,能防止 SQL 注入攻击(在拼接SQL语句时,使用条件为真)。

PreparedStatement为 java.sql.PreparedStatement。

  • 部分方法
    (1)setXxx方法
    通过调用Connection对象的prepareStatement方法(传递的参数是sql语句),将会获取到一个PreparedStatement对象。在传递的sql语句可以使用问号 ?代替一个值,之后再调用PreparedStatement对象的setXxx方法为sql语句的问号 ?赋值。

void setInt(int parameterIndex,int x) throws SQLException:将指定的参数设置为给定的Java int值。 当驱动程序将其发送到数据库时,将其转换为SQL INTEGER值。

void setString(int parameterIndex,String x) throws SQLException:将指定的参数设置为给定的Java String值。 当它发送到数据库时,驱动程序将其转换为SQL VARCHAR或LONGVARCHAR值。

	String sql = "UPDATE grade SET gradename = ? WHERE gradeid = ?;";
	ps = conn.prepareStatement(sql);
	ps.setString(1, grade.getGradeName());
	ps.setInt(2, grade.getGradeInt());


(2)执行查询的SQL语句,获得结果集

ResultSet executeQuery() throws SQLException:执行此 PreparedStatement对象中的SQL查询,并返回查询 PreparedStatement的 ResultSet对象。

	ResultSet rs = ps.executeQuery();


(3)执行增加、修改、删除的SQL语句

int executeUpdate() throws SQLException:执行在该SQL语句PreparedStatement对象,它必须是一个SQL数据操纵语句,如 INSERT 、UPDATE 或 DELETE,或不返回任何内容的SQL语句,例如DDL语句。

	int n = ps.executeUpdate();

6、ResultSet接口


ResultSet 接口表示数据库结果集的数据表,通常通过查询语句生成。ResultSet 是一个存储查询结果的对象,同时这个对象还具有操纵数据的功能。

ResultSet 是非离线读取,ResultSet 在数据库连接关闭之后就不能使用了,必须要在一直保持连接的状态才能使用,否则需要使用到Rowset离线结果集。

ResultSet 只能读取一次。在执行 Statement 的executeQuery方法的时候,会自动关闭上一次调用 Statement 的executeQuery方法的结果集。

ResultSet 是 java.sql.ResultSet 。

  • 处理结果集
	while (rs.next()) {
		int id = rs.getInt("gradeid");
		String name = rs.getString("gradename");
		System.out.println(id + "\t" + name);
	}

(1)next()方法

一个 ResultSet 对象具有一个光标指向当前行的结果集。调用 next() 会将光标从当前位置向下移动一行。ResultSet的光标最初位于第一行之前,第一次调用 next()方法会使第一行成为当前行,第二次调用next()方法会使第二行成为当前行,依此类推。当光标位于最后一行之后,也就是 ResultSet 集合中已经没有下一行了,此时调用 next() 方法将会返回 false。 所以可以在 while 循环中使用 next() 来迭代结果集。

boolean next() throws SQLException:将光标从当前位置向下移动一行。


(2)getXxx方法

ResultSet 提供用于从当前行获取列值的获取方法,可以使用列的索引编号或列的名称来获取列的值。一般情况下,使用列索引较为高效,列的编号从1开始。为了获得最大的可移植性,应该按从左到右的顺序读取每行中的结果集列, 每列只能读取一次。用作获取方法的输入的列名称不区分大小写。

调用 getXxx(int fieldIndex) 或者 getXxx(String columnName) 方法获取数据库的表中的字段值。

int getInt(int columnIndex) throws SQLException:以Java编程语言中的 int此 ResultSet对象当前行中指定列的值。 参数columnIndex是列的编号,如数据库表的第一列是1,第二列是2,依此类推。返回的结果是列的值,如果值为SQL NULL ,则返回的值为0。

int getInt(String columnLabel) throws SQLException:这个检索的当前行中指定列的值 ResultSet作为对象 int在Java编程语言。参数columnLabel 是使用SQL AS子句指定的列的标签。 返回的结果是列的值,如果值为SQL NULL ,返回值为0 。

  • ResultSet接口的继承关系
    在这里插入图片描述

二、JDBC的使用步骤


(1)通过 Class.forName("com.mysql.jdbc.Driver") 加载驱动。

(2)通过DriverManager的静态方法 getConnection(url,user,passsword) 获取数据库连接。

(3)通过 Connection 的 prepareStatement 方法获取 PreparedStatement 对象。

(4)通过 PreparedStatement 预编译对象执行SQL语句,获取结果。① 查询:调用 executeQuery 方法获取 ResultSet 结果集。② 增加、删除、修改:调用 executeUpdate 方法获取int值。

(5)处理结果:① ResultSet:通过 next() 方法遍历 ResultSet 。 ② int值表示的是受到影响的行数。

(6)通过 close() 方法释放资源。

  • 实体类 grade
public class Grade {
	private int gradeInt;
	private String gradeName;
	public int getGradeInt() {
		return gradeInt;
	}
	public void setGradeInt(int gradeInt) {
		this.gradeInt = gradeInt;
	}
	public String getGradeName() {
		return gradeName;
	}
	public void setGradeName(String gradeName) {
		this.gradeName = gradeName;
	}
	public Grade(int gradeInt, String gradeName) {
		super();
		this.gradeInt = gradeInt;
		this.gradeName = gradeName;
	}
	public Grade() {
		super();
	}
}

1、查询数据

  • 查询全部年级信息
	/** 查询全部年级信息 */
	public static List<Grade> ListGrade() {
		List<Grade> list = new ArrayList<Grade>();
		Connection conn = null;
		Statement stmt = null;
		ResultSet rs = null;
	
		String url = "jdbc:mysql://localhost:3306/schooldb";
		String user = "root";
		String password = "root";	
		try {
			Class.forName("com.mysql.jdbc.Driver");
			conn = DriverManager.getConnection(url, user, password);
			String sql = "SELECT * FROM grade;";
			stmt = conn.createStatement();
			rs = stmt.executeQuery(sql);
			while (rs.next()) {
				Grade grade = new Grade(rs.getInt("gradeid"), rs.getString("gradename"));
				list.add(grade);
				grade = null;
			}
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				rs.close();
				stmt.close();
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}	
		return list;
	}

  • 根据年级编号查询年级信息
	/** 根据年级编号查询年级信息 */
	public static Grade getGradeById(int gradeid) {
		Grade grade = null;
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;	
		String url = "jdbc:mysql://localhost:3306/schooldb";
		String user = "root";
		String password = "root";	
		try {
			Class.forName("com.mysql.jdbc.Driver");
			conn = DriverManager.getConnection(url, user, password);
			String sql = "SELECT * FROM grade WHERE gradeid = ?;";
			ps = conn.prepareStatement(sql);
			ps.setInt(1, gradeid);
			rs = ps.executeQuery();
			if (rs.next()) {
				grade = new Grade(rs.getInt("gradeid"), rs.getString("gradename"));
			}	
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				rs.close();
				ps.close();
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return grade;
	}

2、增加数据

  • 添加年级信息
/** 添加年级信息 */
	public static int addGrade(String gradename) {
		int result = -1;
		Connection conn = null;
		PreparedStatement ps = null;
		String url = "jdbc:mysql://localhost:3306/schooldb";
		String user = "root";
		String password = "root";
		try {
			Class.forName("com.mysql.jdbc.Driver");
			conn = DriverManager.getConnection(url, user, password);
			String sql = "INSERT INTO grade(gradeid,gradename) VALUES(DEFAULT,?);";
			ps = conn.prepareStatement(sql);
			ps.setString(1, gradename);
			result = ps.executeUpdate();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				ps.close();
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return result;
	}

3、删除数据

  • 删除年级信息
/** 删除年级信息 */
	public static int deleteGrade(int gradeid) {
		int result = -1;
		Connection conn = null;
		PreparedStatement ps = null;
		String url = "jdbc:mysql://localhost:3306/schooldb";
		String user = "root";
		String password = "root";
		try {
			Class.forName("com.mysql.jdbc.Driver");
			conn = DriverManager.getConnection(url, user, password);
			String sql = "DELETE FROM grade WHERE gradeid = ?";
			ps = conn.prepareStatement(sql);
			ps.setInt(1, gradeid);
			result = ps.executeUpdate();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				ps.close();
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return result;
	}

4、修改数据

  • 修改年级信息
	/** 修改年级信息 */
	public static int updateGrade(Grade grade) {
		int result = -1;
		Connection conn = null;
		PreparedStatement ps = null;
		String url = "jdbc:mysql://localhost:3306/schooldb";
		String user = "root";
		String password = "root";
		try {
			Class.forName("com.mysql.jdbc.Driver");
			conn = DriverManager.getConnection(url, user, password);
			String sql = "UPDATE grade SET gradename = ? WHERE gradeid = ?;";
			ps = conn.prepareStatement(sql);
			ps.setString(1, grade.getGradeName());
			ps.setInt(2, grade.getGradeInt());
			result = ps.executeUpdate();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				ps.close();
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return result;
	}

三、JDBC的相关知识

1、Statement 和 PreparedStatement的区别


(1)PreparedStatement 继承自 Statement,二者都是接口。
(2)PreparedStatement 表示预编译的 SQL 语句的对象,SQL 语句被预编译并存储在 PreparedStatement 对象中,可以使用此对象多次高效地执行该语句。
(3)Statement 用于执行静态 SQL 语句并返回它所生成结果的对象,不能使用占位符。
(4)PreparedStatement 极大地提高了安全性,由于支持了占位符的写法,所以避免了sql语句的注入。

2、关于JDBC中的加载驱动


在 com.mysql.jdbc.Driver 的源码中有一段静态代码段是用来注册驱动的,当加载Driver类时,就会执行这段静态代码段,所以可以通过 Class.forName("com.mysql.jdbc.Driver"); 或者 new com.mysql.jdbc.Driver(); 来加载驱动。

低版本的 mysql 驱动包需要通过 Class.forName("com.mysql.jdbc.Driver"); 或者 new com.mysql.jdbc.Driver(); 来加载驱动。例如:mysql-connector-java-5.1.5.jar

高版本的 mysql 驱动包不需要通过 Class.forName("com.mysql.jdbc.Driver"); 或者 new com.mysql.jdbc.Driver(); 来加载驱动。例如:mysql-connector-java-5.1.18.jar

mysql驱动包的高版本和低版本有些不同,在高版本的 mysql 驱动包中多了一个service文件夹。在该文件夹中有个 java.sql.Driver 文件,在该文件中包含 com.mysql.jdbc.Driver。

在这里插入图片描述
在这里插入图片描述

在 JDK 中有个特性:SPI(服务提供接口)在Jar 包的 JVM 会将在 Meta-Inf\service\某个接口 中定义的那个类 自动加载到 JVM 中。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值