一、JDBC是什么?
JDBC 指 Java 数据库连接(Java Database Connectivity),是一种标准Java应用编程接口( JAVA API),JDBC就是一套sun公司定义的接口,JDBC本质上就是Sun公司制定的一套接口(interface)!每个数据库厂商需要实现这套接口。我们只需要调用需要即可用来连接 Java 编程语言和广泛的数据库。
JDBC API 库包含下面提到的每个任务,都是与数据库相关的常用用法。
- 制作到数据库的连接。
- 创建 SQL 或 MySQL 语句。
- 执行 SQL 或 MySQL 查询数据库。
- 查看和修改所产生的记录。
从根本上来说,JDBC 是一种规范,它提供了一套完整的接口,允许便携式访问到底层数据库,因此可以用 Java 编写不同类型的可执行文件,例如:
- Java 应用程序
- Java Applets
- Java Servlets
- Java ServerPages (JSPs)
- Enterprise JavaBeans (EJBs)
所有这些不同的可执行文件就可以使用 JDBC 驱动程序来访问数据库,这样可以方便的访问数据。
JDBC 具有 ODBC 一样的性能,允许 Java 程序包含与数据库无关的代码。
二、使用步骤
1.注册驱动
数据库厂商的Java程序员所写的实现类 叫做驱动 Driver
注册驱动
第一种注册方法代码如下:(不常用)
public class 注册驱动 { public static void main(String[] args) { try { DriverManager.registerDriver(new com.mysql.jdbc.Driver()); } catch (SQLException throwables) { throwables.printStackTrace(); } } }
第二种方利用反射的特性,加载过程中注册驱动的过程。
关于反射的补充: Java中的灵魂-反射机制
关于JDBC—MySQL中以类加载的方式注册驱动(反射)详解链接:
JDBC—MySQL以类加载的方式注册驱动(反射)
class.forName(com.mysql.jdbc.Driver);
上述一行代码就可以通过反射这个动作调用类,实现Driver类的加载 但是需要使用try和catch语句块环绕
2.获取连接
要连接数据库的url---- String url="jdbc:mysql://localhost:3306/test?"+ "useUnicode=true&characterEncoding=UTF8";//防止乱码
要连接数据库的用户名---- String user="xxxx";
要连接数据库的密码---- String pass="xxxx";
接下来我们分析下url:
"jdbc(这是协议以jdbc开头):mysql(这是子协议,数据库管理系统称)://localhost(数据库来源地址):3306(目标端口)/test(要查询的表的表名)?"
"useUnicode=true&characterEncoding=UTF8";添加这个是为了防止乱码,指定使用Unicode字符集 ,且使用UTF-8来编辑。
/* url包括哪几部分: 协议 IP Port 资源名 eg:http://180.101.49.11:80/index.html http:// 通信协议 180.101.49.11 IP地址 80 端口号 index.html 资源名 */
// 2、获取连接 /* url包括哪几部分: 协议 IP Port 资源名 eg:http://180.101.49.11:80/index.html http:// 通信协议 180.101.49.11 IP地址 80 端口号 index.html 资源名 */ // static Connection getConnection(String url, String user, String password) String url = "jdbc:mysql://127.0.0.1:3306/hello"; String user = "root"; System.out.println(" "); String password = "rota"; conn = DriverManager.getConnection(url,user,password); System.out.println("数据库连接对象 : " + conn); //数据库连接对象com.mysql.jdbc.JDBC4Connection@1ae369b7
3.获取数据库操作对象
// 3、获取数据库操作对象 // Statement 类中 createStatement() 创建一个 Statement 对象来将 SQL 语句发送到数据库。 stmt = conn.createStatement(); // 4、执行sql语句 // int executeUpdate(String sql) // 专门执行DML语句 // 返回值是“影响数据库中的记录条数” int count = stmt.executeUpdate("update dept set dname = '销售部',loc = '合肥' where deptno = 20;"); System.out.println(count == 1 ? "保存成功":"保存失败");
4.执行sql语句
// 4、执行sql语句 // int executeUpdate(String sql) // 专门执行DML语句 // 返回值是“影响数据库中的记录条数” int count = stmt.executeUpdate("update dept set dname = '销售部',loc = '合肥' where deptno = 20;"); System.out.println(count == 1 ? "保存成功":"保存失败");
5.处理查询结果集
rs = stmt.executeQuery("select empno,ename,sal from emp"); while(rs.next()){ /* String empno = rs.getString(1); String ename = rs.getString(2); String sal = rs.getString(3); System.out.println(empno + "," + ename + "," + sal); */ /* // 按下标取出,程序不健壮 String empno = rs.getString("empno"); String ename = rs.getString("ename"); String sal = rs.getString("sal"); System.out.println(empno + "," + ename + "," + sal); */ /* // 以指定的格式取出 int empno = rs.getInt(1); String ename = rs.getString(2); double sal = rs.getDouble(3); System.out.println(empno + "," + ename + "," + (sal + 100)); */ int empno = rs.getInt("empno"); String ename = rs.getString("ename"); double sal = rs.getDouble("sal"); System.out.println(empno + "," + ename + "," + (sal + 200)); }
其中执行增删改的方法返回值是int类型
执行查询的方法返回值是操作结果集对象,即使ResultSet的实例化对象!
6.释放资源
finally { // 6、释放资源 // 从小到大依次关闭 //finally语句块内的语句一定会执行! if(stmt != null) { try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if(conn != null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
上述六步连贯:
第一次优化:(比较两种注册驱动的方法)
import java.sql.*; public class JDBCTest01 { public static void main(String[] args) { Connection conn = null; Statement stmt = null;//先创建连接对象 和 操作对象 并且引用为空,是为了对象变量的生命周期不仅仅局限于try语句块内,而是在整个main方法内,方便后续finally语句块内释放资源 try{ // 1、注册驱动 Driver driver = new com.mysql.jdbc.Driver(); //多态,父类型引用指向子类型对象 DriverManager.registerDriver(driver); // 2、获取连接 /* url包括哪几部分: 协议 IP Port 资源名 eg:http://180.101.49.11:80/index.html http:// 通信协议 180.101.49.11 IP地址 80 端口号 index.html 资源名 */ // static Connection getConnection(String url, String user, String password) String url = "jdbc:mysql://127.0.0.1:3306/hello"; String user = "root"; System.out.println(" "); String password = "rota"; conn = DriverManager.getConnection(url,user,password); System.out.println("数据库连接对象 : " + conn); //数据库连接对象com.mysql.jdbc.JDBC4Connection@1ae369b7 // 3、获取数据库操作对象 // Statement 类中 createStatement() 创建一个 Statement 对象来将 SQL 语句发送到数据库。 stmt = conn.createStatement(); // 4、执行sql语句 // int executeUpdate(String sql) // 专门执行DML语句 // 返回值是“影响数据库中的记录条数” int count = stmt.executeUpdate("update dept set dname = '销售部',loc = '合肥' where deptno = 20;"); System.out.println(count == 1 ? "保存成功":"保存失败"); // 5、处理查询结果集 } catch(SQLException e) { e.printStackTrace(); } finally { // 6、释放资源 // 从小到大依次关闭 //finally语句块内的语句一定会执行! if(stmt != null) { try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if(conn != null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
第二次优化:(比较两种注册驱动的方法)
package com.zdx.source.code.jdbc; /* JDBC完成Delete */ import java.sql.*; public class JDBCTest02 { public static void main(String[] args) { // 1、注册驱动 // 2、获取连接 // 3、获取数据库操作对象 // 4、执行sql语句 // 5、获取查询结果集 // 6、释放资源 Connection conn = null; Statement stmt = null; try { Driver driver = new com.mysql.jdbc.Driver(); DriverManager.registerDriver(driver); String url = "jdbc:mysql://127.0.0.1:3306/mydatabase"; String user = "root"; String password = "146"; conn = DriverManager.getConnection(url,user,password); stmt = conn.createStatement(); int count = stmt.executeUpdate("delete from dept where deptno = 50"); System.out.println(count == 1? "删除成功":"删除失败"); } catch(SQLException e){ e.printStackTrace(); } finally { if(conn != null) { try { conn.close(); } catch(SQLException e){ e.printStackTrace(); } } if(stmt != null) { try { stmt.close(); } catch(SQLException e){ e.printStackTrace(); } } } } }
第三次优化:(最佳注册驱动获取连接)
package com.zdx.source.code.jdbc; /* 注册驱动的另一种方式 */ import java.sql.*; public class JDBCTest03 { public static void main(String[] args) { try{ // 注册驱动 Class.forName("com.mysql.jdbc.Driver"); // 获取连接 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydatabase","root","146"); System.out.println(conn); } catch(SQLException e){ e.printStackTrace(); } catch(ClassNotFoundException e){ e.printStackTrace(); } } }
第四次优化:(使用资源绑定器)
package com.zdx.source.code.jdbc; /* 使用资源绑定器 */ import java.sql.*; import java.util.*; public class JDBCTest04 { public static void main(String[] args) { ResourceBundle bundle = ResourceBundle.getBundle("jdbc"); String driver = bundle.getString("driver"); String url = bundle.getString("url"); String user = bundle.getString("user"); String password = bundle.getString("password"); Connection conn = null; Statement stmt = null; try { Class.forName(driver); conn = DriverManager.getConnection(url,user,password); stmt = conn.createStatement(); int count = stmt.executeUpdate("insert into dept(deptno,dname,loc) values(50,'人事部','北京');"); System.out.println(count == 1? "保存成功":"保存失败"); } catch(SQLException e){ e.printStackTrace(); } catch(ClassNotFoundException e) { e.printStackTrace(); } finally { if(conn != null) { try { conn.close(); } catch(SQLException e){ e.printStackTrace(); } } if(stmt != null) { try { stmt.close(); } catch(SQLException e){ e.printStackTrace(); } } } } }
第五次优化:(对操作结果集的处理)
package com.zdx.source.code.jdbc; /* 执行DQL语句 */ import java.sql.*; import java.util.*; public class JDBCTest05 { public static void main(String[] args) { // 1、注册驱动 // 2、建立连接 // 3、获取数据库操作对象 // 4、执行sql语句 // 5、获取查询结果集 // 6、释放资源 Connection conn = null; Statement stmt = null; ResultSet rs = null; try{ ResourceBundle rb = ResourceBundle.getBundle("jdbc"); String driver = rb.getString("driver"); String url = rb.getString("url"); String user = rb.getString("user"); String password = rb.getString("password"); Class.forName(driver); conn = DriverManager.getConnection(url,user,password); stmt = conn.createStatement(); rs = stmt.executeQuery("select empno,ename,sal from emp"); while(rs.next()){ /* String empno = rs.getString(1); String ename = rs.getString(2); String sal = rs.getString(3); System.out.println(empno + "," + ename + "," + sal); */ /* // 按下标取出,程序不健壮 String empno = rs.getString("empno"); String ename = rs.getString("ename"); String sal = rs.getString("sal"); System.out.println(empno + "," + ename + "," + sal); */ /* // 以指定的格式取出 int empno = rs.getInt(1); String ename = rs.getString(2); double sal = rs.getDouble(3); System.out.println(empno + "," + ename + "," + (sal + 100)); */ int empno = rs.getInt("empno"); String ename = rs.getString("ename"); double sal = rs.getDouble("sal"); System.out.println(empno + "," + ename + "," + (sal + 200)); } } catch(Exception e){ e.printStackTrace(); }finally{ if(rs != null){ try{ rs.close(); } catch (Exception e){ e.printStackTrace(); } } if(stmt != null){ try{ stmt.close(); } catch (Exception e){ e.printStackTrace(); } } if(conn != null){ try{ conn.close(); } catch (Exception e){ e.printStackTrace(); } } } } }
总结:
在上述五次优化代码的过程中,针对这六步
// 1、注册驱动 // 2、获取连接 // 3、获取数据库操作对象 // 4、执行sql语句 // 5、获取查询结果集 // 6、释放资源
第一步的注册驱动最终使用了反射,已达最优
第二步的获取连接已达最优,已经有能力去完成JDBC连接数据库的工具类的封装了
看到这里可以移步去学习—————>工具类的封装啦!
注:
第三步的获取数据库操作对象中我们是使用Statement接口
public interface Statement extends Wrapper, AutoCloseable
还可以优化成为PreparedStatement
public interface PreparedStatement extends Statement
在实际开发过程中由于PreparedStatement能防止注入,且预先编译SQL语句的特性使得程序健壮性提高,所以实际开发中99.9%使用PreparedStatement。这是后话,由于封装工具类主要封装的是注册驱动,获取连接和释放资源,后续将专门写一篇博客讨论PreparedStatement
此外在实际开发中除了掌握上述六步还需要掌握事务提交回滚三部曲。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。