jdbc开发步骤图

一. JDBC简介
JDBC(java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的API,可以为多种关系数据库提供统一访问,它由一组用java语言编写的类和接口组成。JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序
(1)Java DataBase Connectivity(java数据库连接)
(2)组成包:java.sql.*;javax.sql.*;这两个包都包含在了JDK中。
(3)还需要数据库的驱动,这些驱动就相当于对JDBC规范的实现

主要接口或类
1. DriverManger
作用:
a. 注册驱动
b. 获取与数据库的连接
改进注册驱动:
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
缺点:严重依赖具体的驱动类(导入什么驱动的包就只能注册什么驱动),会导致驱动被注册2次。
获取与数据库的连接
DriverManager.getConnection("jdbc:mysql://localhost:3306/ssm", "root", "hang"); //ssm为数据库名
2. Connection
所有与数据库的交互作用都是基于连接的基础之上的,想要对数据库进行操作,首先要获取此对象,从连接对象中获取执行数据库的statement对象
Statement stmt = conn.createStatement():创建向数据库发送sql的statement对象
Conm.preparedStatement(sql) -------更常用,可进行预编译,防止sql注入
3. Statement
作用:向数据库发送并执行具体的SQL语句
常用的方法:
(1)ResultSet executeQuery(String sql):只适合查询,返回的是查询的结果集
(2)int executeUpdate(String sql):适合DML,或者没有返回结果集的DDL,返回的是影响的记录行数
(3)boolean execute(String sql):执行任何的SQL语句,返回的不是成功与否。有结果集的返回true,没有返回false。

4. PreparedStatement

当再次查询相同的数据时,则直接在缓存中获取,不需要再和数据库进行交换,所以说效率高

5. ResultSet
作用:代表查询语句的查询结果集
二. 入门程序
1. 开发步骤:
(1)创建一个java项目
(2)导入mysql的数据库驱动jar包

(3)注册驱动
(4)获取与数据库的连接
(5)得到代表发送和执行SQL语句的对象--------Statement
(6)执行语句
(7)释放占用的资源
public class TestDemo { public static void main(String[] args) throws Exception { // 注册驱动 DriverManager.registerDriver(new Driver()); // 建立连接 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db_demo1", "root", "feng"); // 获取执行sql语句的对象 Statement st = conn.createStatement(); String sql = "select * from products"; // 执行 返回结果 ResultSet set = st.executeQuery(sql); //遍历结果集 while (set.next()) { //获取字段值 为name的数据 String name = set.getString("name"); System.out.println(name); } // 释放资源 set.close(); st.close(); conn.close(); } }
这个程序存在几个问题:
2. 注册驱动时会出现两次注册,代码扩展性不好问题
由com.mysql.jdbc.Driver()的源码(如下)

mysql的Driver类中有一个静态代码块,静态代码块中已经通过DriverManager注册了这个驱动!
大家都知道静态代码快是在类加载器加载这个类的字节码文件的时候就已经执行了的,也就是说,在DriverManager.registerDriver(new com.mysql.jdbc.Driver())这段代码中,一旦new了这个驱动,这个驱动就已经被加载了!
所以如果DriverManager.registerDriver(new com.mysql.jdbc.Driver()),实际上Mysql的Driver会被加载两次,所以只要new com.mysql.jdbc.Driver();实际上就已经注册驱动了
但是我们能new com.mysql.jdbc.Driver()这样子来注册驱动吗?可以!但是还是不提倡,为什么呢?因为这样的话还有一个问题,这样写十分依赖Jar包,一旦jar包找不到,编译时期就会报错。所以在开发过程中通常写成:Class.forName(“com.mysql.jdbc.Driver”);
这样的话,通过类加载的方式来加载Driver类,照样能够执行static代码块中的注册驱动的方法。而且由于将Driver的位置写成了字符串的形式,对jar包的依赖就降低了,也易于使用配置文件加载这个类,所以下次如果换成连接Oracle或者其他数据库,改一下配置文件再填一个jar包就可以了。


使用Class.forName("com.mysql.jdbc.Driver")进行注册,为了代码的可扩展性,下面采取了读取配置文件的形式获取相应的参数(为了保障资源一定能被释放,应该放到finaly代码块中去)
public class JdbcDemo2 { // 读取配置文件,获取连接需要的数据 static String url; static String userName; static String passWord; static { try { Properties p = new Properties(); p.load(JdbcDemo2.class.getClassLoader().getResourceAsStream("db.properties")); String className = p.getProperty("className"); url = p.getProperty("url"); userName = p.getProperty("userName"); passWord = p.getProperty("passWord"); // 注册驱动 Class.forName("com.mysql.jdbc.Driver"); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { Connection conn = null; Statement st = null; ResultSet set = null; try { // 建立连接 conn = DriverManager.getConnection(url, userName, passWord); // 得到执行sql语句的对象 st = conn.createStatement(); String sql = "select * from products"; // 执行并返回结果 set = st.executeQuery(sql); while(set.next()) { String str = set.getString("price"); System.out.println(str); } } catch (Exception e) { e.printStackTrace(); }finally { // 释放资源 try { if (set != null) { set.close(); set = null; } if (st != null) { st.close(); st = null; } if (conn != null) { conn.close(); conn = null; } } catch (SQLException e) { e.printStackTrace(); } } } }
以上代码中出现的如st = null是为了让jvm更快的回收st对象,即使创建对象的引用指向为空。
3. 工具类的提取(将连接和资源的释放封装)
根据上面的例子发现,获取数据库连接,释放数据库资源的代码都一样,可以提取出来一个方法,当获取连接,释放资源就直接调用方法,减少代码的冗余度。
public class JdbcUtils { static String url; static String userName; static String passWord; static { Properties p = new Properties(); try { p.load(JdbcUtils.class.getClassLoader().getResourceAsStream("properties")); String className = p.getProperty("className"); url = p.getProperty("url"); userName = p.getProperty("userName"); passWord = p.getProperty("passWord"); // 注册 Class.forName(className); } catch (Exception e) { e.printStackTrace(); } } // 获取连接方法 public static Connection getConnection() { Connection conn = null; try { conn = DriverManager.getConnection(url, userName, passWord); } catch (SQLException e) { e.printStackTrace(); } return conn; } // 释放资源 public static void release(ResultSet set, Connection conn,Statement st) { try { if (set != null) { set.close(); set = null; } if (st != null) { st.close(); st = null; } if (conn != null) { conn.close(); conn = null; } } catch (SQLException e) { e.printStackTrace(); } } }
原文:https://www.cnblogs.com/jj1106/p/11503789.html