JDBC总结——编程步骤及原理


JDBC总结

一、JDBC简介

  • JDBC(Java Data Base Connectivity)是Java语言访问数据库的一套API应用程序编程接口。
  • 本质上来说就是调用者(程序员)和实现者(数据库厂商)之间的协议。
  • jDBC的实现由数据库厂商以驱动程序的形式提供。
  • JDBC API可以让开发人员使用纯java的方式来链接数据库,并进行操作。

二、JDBC原理

在这里插入图片描述

三、JDBC对象介绍

Jdbc常见类

JDBC中的核心类有:DriverManager,Connnection,Statement和ResultSet

1、DriverManager(驱动管理器)的作用有两个

  • 注册驱动:这可以让JDBC知道要使用的是哪个驱动

    DriverManager.registerDriver()方法:了解即可,注册驱动一般用Class.forName()

  • 获取Connection:如果可以获取到Connection,那么说明已经与数据库连接上了
    getConnection()方法:

2、Connection对象表示连接,与数据库的通讯都是通过这个对象展开的:

  • Connection最为重要的一个方法就是用来获取Statement对象
    Statement statement = connection.createStatement();
    代码:

3、Statement是用来向数据库发送SQL语句的,这样数据库就会执行发送过来的SQL语句:

常用的Statement方法

  • int executeUpdate(String sql):执行更新操作(insert,update,delete等)
    • 执行更新操作,即insert,update,delete语句
    • 也可以执行create table,alter table,drop table等语句,但很少用
    • 返回值为操作行数
  • ResultSet executeQuery(String sql):执行查询操作,数据库在执行查询后会把查询结果ResultSet返回
    • 执行查询操作,即select语句
    • 返回ResultSet,即结果集
  • boolean execute();
    • 可以用来执行executeUpdate和executeQuery两个方法能执行的所有sql语句,即可以执行增删改查所有sql语句
    • 该方法的返回的是一个boolean类型,表示SQL语句是否有结果集
    • 如果用该方法执行更新语句,那么还要调用int
      getUpdateCount()来获取insert,update,delete语句所影响的行数
    • 如果使用该方法执行查询语句,那么还要调用ResultSet getResult()来获取select语句的查询结果

三种Statement对象

  • Statement 对象
    • 作用:用于执行不带参数简单 SQL 语句
    • 特点:每次执行 SQL 语句,数据库都要执行 SQL 语句的编译,最好用于仅执行一次查询并返回结果的情形,
    • 效率高于 PreparedStatement
  • PreparedStatement
    • 作用:用于执行带 或 不带 IN参数 的预编译 SQL 语句
    • 特点:
      • ① 是预编译的, 在执行可变参数的一条 SQL 语句时,比 Statement 的效率高,因为 DBMS 预编译一条 SQL,当然会比多次编译一条 SQL 的效率要高
      • ② 安全性好,有效防止 SQL 注入等问题
      • ③ 对于多次重复执行的语句,效率会更高一点,并且这种情况下也比较适合使用 batch
      • ④ 代码的可读性和可维护性好
  • CallableStatement
    • 作用:用于执行对数据库存储过程 的调用
    • 特点:提供了对输出和输入参数的支持
    • 此接口具有对 PreparedStatment 接口提供的输入输出参数的支持

代码:

4、ResultSet对象表示查询结果集,只有在执行查询操作后才会有结果集的产生

  • 结果集是一个二维的表格,有行有列。
  • 操作结果集要利用ResultSet内部的“行光标”,以及获取当前行上的每一列上的数据
  • boolean next();是行光标移动到下一行,并返回移动后的行是否存在
  • getXXX(int index);获取指针所指向的当前行数据
  • colose();释放资源

四、JDBC编程步骤

需要引入mysql-connector-java-5.1.39-bin.jar工具包。
JDBC编程步骤

1、加载mysql数据库驱动

  /**
     * 所有的java.sql.Driver实现类,都提供了static块,
     * 块内的代码就是把自己注册到DriverManager中
     */
 Class.forName("com.mysql.jdbc.Driver");   //加载驱动类(注册驱动)
    /*等价于*/
 com.mysql.jdbc.Driver driver = new com.mysql.jdbc.Driver();   //注册驱动
 DriverManager.registerDriver(driver);

一般都用Class.forName()方法加载驱动。

2、获取链接

//设置参数
String url = "jdbc:mysql://localhost:3306/mybase";
String username = "root";
String password = "123";

//使用url,username,password,得到连接对象
Connection connection = DriverManager.getConnection(url,username,password);

3、获取Statement

(1)获取Statement对象

Statement stm = conn.createStatement();

(2)获取preparedStatement对象

String sql = "select * from emp where job=?";
pstm = conn.prepareStatement(sql);		//创建sql半成品
pstm.setString(1,"clerk");				//参数绑定

①创建sql半成品:通过连接获得PreparedStatement对象,创建时将SQL语句中取值发生变化的部分用占位符?代替。
②参数绑定,即为?赋值(set[type](1,2)方法)第一个参数代表?位置,从1开始;第二个参数是具体取值。

4、执行SQL语句

(1)如果是Statement对象的查询,使用ResultSet rs = stm.executeQuery(sql);
(2)如果是preparedStatement对象的查询,使用ResultSet rs = pstm.executeQuery();
(3)如果有很多sql语句需要执行,就要使用批处理。

5、处理结果集(查询需要)

while(rs.next()){
	 String number = rs.getString(1);		//通过列编号来获取该列的值 
    String name = rs.getString("name");  	//通过列名称来获取该列的值
    int age = rs.getInt(3);
    String gender = rs.getString(4);
    System.out.println(number + "," + name + "," + age + "," + gender);
}

6、关闭链接

// 倒关(先得到的资源后关闭,后得到的资源先关闭)
rs.close();
stm.close();
conn.close();   //这个必须要关

五、规范代码示例

1、创建Statement连接数据库

import java.sql.*;

public class testStatement {
	public static void main(String[] args) {
		Connection conn = null;
		Statement stm = null;
		ResultSet rs = null;
		
		try {
			//1、加载驱动
			Class.forName("com.mysql.jdbc.Driver");
			//2、获取连接
			String url = "jdbc:mysql://localhost:3306/mybase?serverTimezone=UTC";
			String user = "root";
			String password = "159357";
			conn = DriverManager.getConnection(url, user, password);
			//3、创建Statement对象
			stm = conn.createStatement();
			//4、执行sql语句
			//查询数据库statement.executeQuery(查询sql)
			String sql = "select * from emp";
			rs = stm.executeQuery(sql);
			
			//修改操作数据库 statement.executeUpdate(增删改sql)
			/*String sql = "insert into emp(ename,job,deptno) values('小龙人','manager',10)";
			String sql = "delete from emp where ename='小龙人'";
			String sql = "update emp set job='leader' where ename='张伟'";
			int lines = stm.executeUpdate(sql);
			System.out.println("影响的行数"+lines);
			*/
			//5、处理结果集
			while(rs.next()){
				//int empno = rs.getInt(1);
				int empno = rs.getInt("empno");
				String ename = rs.getString(2);
				String job = rs.getString(3);
				int mgr = rs.getInt(4);
				Date hiredate = rs.getDate(5);
				double  sal= rs.getDouble(6);
				//double comm = rs.getDouble(7);
				double comm = rs.getDouble("comm");
				int deptno = rs.getInt(8);
				System.out.println(empno+" "+ename+" "+job+" "+mgr
				+" "+hiredate+" "+sal+" "+comm+" "+deptno);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			//6.关闭链接
            if(resultSet != null)
            {
                resultSet.close();
            }
            if(statement != null)
            {
                statement.close();
            }
            if(connection != null)
            {
                connection.close();
            }
	}
}

3、创建preparedStatement连接数据库

pstm构建动态sql
解决Sql注入攻击漏洞,可以使用PreparedStatement来执行sql。它是
Statemnet的一个子接口使用步骤分为3步:

(1)创建:通过链接获得PreparedStatement对象

	String sql="select * from user_luxw where username=? Andpassowrd=?";
	PreoparedStatment pstm = conn.prepareStatement(sql);
创建时,将SQL语句中取值发生变化的部分用占位符(?)替代。

(2)给?赋值(也称参数绑定)

/*使用set[Type]方法给?赋值。其中Type表示?表示?位置的数据类型。第一个参数代表问号
位置从1开始;第二个参数是具体取值,比如:*/
pstm.setString(1,username);
pstm.setString(2,password);

(3)执行SQL

	pstm.executeQuery();
	pstm.executeUpdate();	//执行更新时使用
此时JDBC将所有?对应的参数发送至数据库服务器,调用在共享池中由第一步创建的预编译的SQL并执行

完整代码:

package jdbc;

import java.sql.*;
import java.util.Date;

/**
 - 类说明:
 - 		JDBC创建PreparedStatement对象连接数据库
 */
public class testPreparedStatement {
	public static void main(String[] args) {
		Connection conn = null;
		PreparedStatement pstm = null;
		ResultSet rs = null;
		try {
			// 1.加载驱动
			Class.forName("com.mysql.jdbc.Driver");
			// 2.获取连接
			String url = "jdbc:mysql://localhost:3306/mybase?useUnicode=true&characterEncoding=utf-8";
			String user = "root";
			String password = "123";
			conn = DriverManager.getConnection(url, user, password);
			// 3.创建PreparedStatement,预编译sql语句
			String sql = "select * from emp where job=?";
			pstm = conn.prepareStatement(sql);//创建sql半成品
			pstm.setString(1,"clerk");//参数绑定
			//4.执行sql语句
			rs = pstm.executeQuery();
			//5.处理结果集
			while(rs.next()){
				int empno = rs.getInt("empno");
				String ename = rs.getString("ename");
				String job = rs.getString(3);
				int mgr = rs.getInt("mgr");
				Date hiredate = rs.getDate(5);
				double sal = rs.getDouble("sal");
				double comm = rs.getDouble("commit");
				int deptno = rs.getInt(8);
				System.out.println(empno+" "+ename+" "+job+" "+mgr+" "+hiredate+" "+sal+" "+comm+" "+deptno);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			// 6.关闭连接/释放资源
			try {
				rs.close();
				pstm.close();
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
}

4、Statement和preparedStatement比较

  • statement的执行过程: 创建stm对象—>进行编译—>执行(执行一条sql语句10秒).
  • PreparedStatement的执行过程:
    创建pstm对象(sql半成品)—>设置值—>执行发送数据(执行一条sql语句需要12秒,但是设置sql和值只需要2秒)

5、批处理

(1)Statement完成批处理

  • 使用Statement对象添加要批量执行SQL语句
  • 执行批处理SQL语句:Statement.executeBatch();
  • 清除批处理命令:Statement.clearbatch();

优点:可以向数据库发送多条不同的SQL语句。
缺点:SQL语句没有预编译。
当向数据库发送多条语句相同,但仅参数不同的SQL语句时,需重复写上很多条SQL语句。

完整代码:

import java.sql.*;

/*
 * statement批处理
 */
public class testStatementBatch {
	public static void main(String[] args) throws ClassNotFoundException, SQLException {
		//加载链接
		Class.forName("com.mysql.jdbc.Driver");
		//获取链接
		Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mybase?serverTimezone=UTC", "root", "159357");
		//创建Statement
		Statement stm = conn.createStatement();
		String sql = "insert into emp(ename,job,deptno) values('小龙人','clerk',20)";
		String sql1 = "insert into emp(ename,job,deptno) values('美人鱼','leader',10)";
		String sql2 = "update emp set ename='小龙人1' where ename='小龙人'";
		//添加批处理
		stm.addBatch(sql);
		stm.addBatch(sql1);
		stm.addBatch(sql2);
		//执行批处理ִ
		stm.executeBatch();
		//清除批处理
		stm.clearBatch();
		//释放资源
		stm.close();
		conn.close();
	}
}

(2)PreoparedStatment批处理

  • 采用PrepareStatement.addBatch()实现批处理

优点:发送的是预编译后的SQL语句,执行效率高
缺点:只能应用在SQL语句相同,但参数不同的批处理中,因此此种形式的批处理经常用于在同一个表中批量插入数据,或批量更新表的数据。

import java.sql.*;

/*
 * prepareStatement批处理
 */
public class testPreparedStatemnetBatch {
	public static void main(String[] args) throws Exception {
		//加载驱动
		Class.forName("com.mysql.jdbc.Driver");
		//获取链接
		Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mybase?serverTimezone=UTC", "root", "159357");
		String sql="insert into emp(empno,ename,deptno) values(?,?,?)";
		//创建preparedStatemet
		PreparedStatement pstm = conn.prepareStatement(sql);
		//pstm绑定数据
		for(int i=3008;i<4008;i++){
			pstm.setInt(1, i);
			pstm.setString(2, "李白"+i);
			pstm.setInt(3,20);
			//添加批处理
			pstm.addBatch();
			//ִ执行批处理
			if(i%100==0){
				pstm.executeBatch();
				pstm.clearBatch();
			}
		}
		//执行批处理
		pstm.executeBatch();
		//释放资源
		pstm.close();
		conn.close();
	}
}
发布了22 篇原创文章 · 获赞 14 · 访问量 1178

猜你喜欢

转载自blog.csdn.net/weixin_44157233/article/details/103986556