JDBC是什么(一文彻底搞懂JDBC)

 分类:IT知识时间:2023-05-16 07:31:02点击:

JDBC 全称:

JavaDataBase Connection 复制代码

意思就是使用 java 代码连接数据库

但是问题来了,世界上有一堆数据库例如 Mysql、Oracle、mongodb 等,他们的使用方法都不太一样。

难道我要连不同的数据库就需要写不同的 java 程序吗?这也太麻烦了。

为了解决这个问题,SUN 公司(开发JDK的公司)就决定指定一套接口,这套接口就是使用 java 连接数据库的规范,其实就是 JDBC。

而 JDBC 接口的实现类由数据库厂家负责编写,他们编写后把实现类打包成 jar 包。

这个 jar 包就是一个驱动(例如电脑要连上网需要安装网卡驱动),我们下载好这个驱动后把他放到我们的项目里。

接着编写 java 代码去完善 jar 包要求的连接数据库的信息,然后就能连接到与驱动对应的数据库了。

前面我们在学面向对象的时候知道接口体现了多态性。SUN 公司设计一个 JDBC 规范,不用过多关注数据库厂商怎样实现这个接口,大大提高了程序的可扩展性。

这里我们以连接 Mysql 为例。

  1. 将连接 mysql 数据库的 jar 包放到 lib 目录下。

注:jar 包就是连接数据库的驱动。每个数据库的厂商将自己实现了 JDBC 的代码打包成 jar 包。

  1. 将 jar 包作为库添加到项目中。

注:因为 jar 包就是编译后的 java 代码,所以这里就相当于在项目中添加了 java 代码。

选择 lib 目录,右键选择 Add as a Library。

  1. 加载数据库的驱动

Class.forName("com.mysql.jdbc.Driver"); 复制代码

注:这里驱动的名字要和数据库的版本对应。

Mysql5版本:

Class.forName("com.mysql.jdbc.Driver"); 复制代码

Mysql8版本:

Class.forName("com.mysql.cj.jdbc.Driver"); 复制代码
  1. 创建数据库的连接

// 2. 获得数据库连接Stringurl = "jdbc:mysql://localhost:3306/course_price"; Stringuser = "root"; Stringpassword = "12345678"; Connection conn = DriverManager.getConnection(url, user, password); 复制代码

创建数据库的连接需要三个参数:

url,user,password 复制代码

要想连接数据库,第一需要知道数据库是什么类型的数据库,第二需要知道连接的数据库名称吧。所以 url 的格式:

jdbc:数据库类型://localhost:3306/数据库名称 复制代码

有了 url,还需要知道数据库的账号密码。所以有了这三个参数,就能通过 java 程序连接数据库了。

  1. 测试连接

publicstaticvoidmain(String[] args) { Connection conn = null; try{ // 1. 加载数据库驱动Class.forName("com.mysql.cj.jdbc.Driver"); // 2. 获得数据库连接Stringurl = "jdbc:mysql://localhost:3306/course_price"; Stringuser = "root"; Stringpassword = "12345678"; // 3. 创建数据库的连接conn = DriverManager.getConnection(url, user, password); if(null!=conn){ System.out.println("数据库连接成功"); }else{ System.out.println("数据库连接失败"); } } catch(Exception e) { e.printStackTrace(); } finally{ //4、释放资源if(conn != null) { try{ conn.close(); } catch(SQLException e) { e.printStackTrace(); } } } } 复制代码

测试结果:

注:Connection、PrepareStatement、ResultSet 都会占用一定的资源,它们需要全部释放/关闭。

  1. 常见错误

账号或者密码错误

Access denied foruser 'root'@'localhost'(usingpassword: YES) 复制代码

数据库名称错误

Unknowndatabase 'course_pric'复制代码

url 中数据库类型错误

Nosuitabledriverfoundforjdbc:mysq://localhost:3306/course_price复制代码

我们在开发的时候,一般会将连接数据库的信息写到配置文件里面。这样如果连接信息有改变,直接改配置文件里面的信息就行。

url=jdbc:mysql://localhost:3306/course_price user=root password=12345678 driver:com.mysql.jdbc.Driver复制代码

// 1. 加载配置文件Properties pro=newProperties(); pro.load(newFileReader("resource/jdbc.properties")); // 2. 获取配置文件中连接数据库的信息Stringurl=pro.getProperty("url"); Stringuser=pro.getProperty("user"); Stringpassword=pro.getProperty("password"); Stringdriver=pro.getProperty("driver"); 复制代码
publicstaticvoidmain(String[] args) { Connection conn = null; try{ // 1. 加载配置文件Properties pro=newProperties(); pro.load(newFileReader("resource/jdbc.properties")); // 2. 获取配置文件中连接数据库的信息Stringurl=pro.getProperty("url"); Stringuser=pro.getProperty("user"); Stringpassword=pro.getProperty("password"); Stringdriver=pro.getProperty("driver"); // 3. 加载数据库的驱动Class.forName(driver); // 4. 创建数据库的连接conn = DriverManager.getConnection(url, user, password); if(null!=conn){ System.out.println("数据库连接成功"); }else{ System.out.println("数据库连接失败"); } } catch(Exception e) { e.printStackTrace(); } finally{ //5、释放资源if(conn != null) { try{ conn.close(); } catch(SQLException e) { e.printStackTrace(); } } } } 复制代码

连接数据库之后我们就可以使用 java 程序操作数据库,尽情地蹂躏数据库中的数据了。

那怎样操作数据库中的数据呢?其实就是使用 java 程序执行 SQL 语句,然后返回执行结果。

我们创建的数据库连接对象 connection 有一个小弟,这小弟叫数据库操作对象,它专门用来执行 SQL 语句并返回执行结果。

这个小弟有两种类型:

Statement和 PrepareStatement。 复制代码

Statement 是先进行 SQL 语句拼接,再进行 SQL 语句的编译,存在SQL注入问题。

PreparedStatement 是预先编译 SQL 语句(带有占位符的SQL),然后再给占位符赋值,可以防止 SQL 注入。

因为 PreparedStatement 效率高并且可以防 SQL 注入,所以这里我们使用 PreparedStatement 对象进行增删改查。

publicstaticvoidmain(String[] args) { Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; try{ // 1. 加载配置文件Properties pro = newProperties(); pro.load(newFileReader("resource/jdbc.properties")); // 2. 获取配置文件中连接数据库的信息Stringurl = pro.getProperty("url"); Stringuser = pro.getProperty("user"); Stringpassword = pro.getProperty("password"); Stringdriver = pro.getProperty("driver"); // 3. 加载数据库的驱动Class.forName(driver); // 4. 创建数据库的连接conn = DriverManager.getConnection(url, user, password); // 5. sql 语句Stringsql = "select * from user"; // 6. 创建执行sql的对象ps = conn.prepareStatement(sql); // 7. 执行结果rs = ps.executeQuery(); while(rs.next()) { System.out.println("id:"+ rs.getString("id")); System.out.println("name:"+ rs.getString("name")); System.out.println("------"); } } catch(Exception e) { e.printStackTrace(); } finally{ //8、释放资源if(conn != null) { try{ conn.close(); } catch(SQLException e) { e.printStackTrace(); } } if(ps != null) { try{ ps.close(); } catch(SQLException e) { e.printStackTrace(); } } if(rs != null) { try{ rs.close(); } catch(SQLException e) { e.printStackTrace(); } } } } 复制代码

注:

  • ResultSet 表示执行的结果

  • while(resultSet.next()) 表示如果执行结果有数据,就一直遍历数据。

执行结果:

publicstaticvoidmain(String[] args) { Connection conn = null; PreparedStatement ps = null; try{ // 1. 加载配置文件Properties pro = newProperties(); pro.load(newFileReader("resource/jdbc.properties")); // 2. 获取配置文件中连接数据库的信息Stringurl = pro.getProperty("url"); Stringuser = pro.getProperty("user"); Stringpassword = pro.getProperty("password"); Stringdriver = pro.getProperty("driver"); // 3. 加载数据库的驱动Class.forName(driver); // 4. 创建数据库的连接conn = DriverManager.getConnection(url, user, password); // 5. sql 语句Stringsql = "insert into user(id,name) values(?,?)"; // 6. 创建执行sql的对象ps = conn.prepareStatement(sql); // 7. 给 ?赋值ps.setInt(1, 5); ps.setString(2, "张无忌"); // 8. 执行sqlint count = ps.executeUpdate(); if(count > 0) { System.out.println("添加成功"); } else{ System.out.println("添加失败"); } } catch(Exception e) { e.printStackTrace(); } finally{ //9、释放资源if(conn != null) { try{ conn.close(); } catch(SQLException e) { e.printStackTrace(); } } if(ps != null) { try{ ps.close(); } catch(SQLException e) { e.printStackTrace(); } } } } 复制代码

执行结果:

publicstaticvoidmain(String[] args) { Connection conn = null; PreparedStatement ps = null; try{ // 1. 加载配置文件Properties pro = newProperties(); pro.load(newFileReader("resource/jdbc.properties")); // 2. 获取配置文件中连接数据库的信息Stringurl = pro.getProperty("url"); Stringuser = pro.getProperty("user"); Stringpassword = pro.getProperty("password"); Stringdriver = pro.getProperty("driver"); // 3. 加载数据库的驱动Class.forName(driver); // 4. 创建数据库的连接conn = DriverManager.getConnection(url, user, password); // 5. sql 语句Stringsql = "update user set name = ? where id = ?"; // 6. 创建执行sql的对象ps = conn.prepareStatement(sql); // 7. 给 ?赋值ps.setString(1, "周芷若"); ps.setInt(2, 5); // 8. 执行sqlint count = ps.executeUpdate(); if(count > 0) { System.out.println("修改成功"); } else{ System.out.println("修改失败"); } } catch(Exception e) { e.printStackTrace(); } finally{ //9、释放资源if(conn != null) { try{ conn.close(); } catch(SQLException e) { e.printStackTrace(); } } if(ps != null) { try{ ps.close(); } catch(SQLException e) { e.printStackTrace(); } } } } 复制代码

执行结果:

publicstaticvoidmain(String[] args) { Connection conn = null; PreparedStatement ps = null; try{ // 1. 加载配置文件Properties pro = newProperties(); pro.load(newFileReader("resource/jdbc.properties")); // 2. 获取配置文件中连接数据库的信息Stringurl = pro.getProperty("url"); Stringuser = pro.getProperty("user"); Stringpassword = pro.getProperty("password"); Stringdriver = pro.getProperty("driver"); // 3. 加载数据库的驱动Class.forName(driver); // 4. 创建数据库的连接conn = DriverManager.getConnection(url, user, password); // 5. sql 语句Stringsql = "delete from user where id = ?"; // 6. 创建执行sql的对象ps = conn.prepareStatement(sql); // 7. 给 ?赋值ps.setInt(1, 4); // 8. 执行sqlint count = ps.executeUpdate(); if(count > 0) { System.out.println("删除成功"); } else{ System.out.println("删除失败"); } } catch(Exception e) { e.printStackTrace(); } finally{ //9、释放资源if(conn != null) { try{ conn.close(); } catch(SQLException e) { e.printStackTrace(); } } if(ps != null) { try{ ps.close(); } catch(SQLException e) { e.printStackTrace(); } } } } 复制代码

执行结果:

从上面的例子中,我们发现每次操作都要写一堆连接数据库的信息,操作完还要释放资源,真是烦死了。那能不能简化一下呢?

能,把数据库连接封装成工具类

我们之前学 static 关键字的时候知道 static 修饰的方法可以直接用类名调用,所以特别适合工具类的使用。

JDBC 工具类:

publicclassJDBCUtils{ privatestaticString user; privatestaticString password; privatestaticString url; privatestaticString driver; static{ // 静态代码块只需要加载一次,读取资源文件try{ // 1. 加载配置文件Properties pro = newProperties(); pro.load(newFileReader("resource/jdbc.properties")); // 2. 获取配置文件中连接数据库的信息url = pro.getProperty("url"); user = pro.getProperty("user"); password = pro.getProperty("password"); driver = pro.getProperty("driver"); // 3. 创建数据库连接驱动Class.forName(driver); } catch(FileNotFoundException e) { e.printStackTrace(); } catch(IOException e) { e.printStackTrace(); } catch(ClassNotFoundException e) { e.printStackTrace(); } } // 4. 获取连接对象publicstaticConnection getConnection()throwsSQLException { returnDriverManager.getConnection(url, user, password); } // 5. 释放资源publicstaticvoidclose(PreparedStatement ps, Connection conn){ close(null, ps, conn); } // 6. 释放资源(重载)publicstaticvoidclose(ResultSet rs, PreparedStatement ps, Connection conn){ if(null!= rs) { try{ rs.close(); } catch(SQLException e) { e.printStackTrace(); } } if(null!= ps) { try{ ps.close(); } catch(SQLException e) { e.printStackTrace(); } } if(null!= conn) { try{ conn.close(); } catch(SQLException e) { e.printStackTrace(); } } } } 复制代码

有了 JDBC 连接的工具类,代码就可以很清爽,例如:

publicstaticvoidmain(String[] args){ Connection conn = null; PreparedStatement ps = null; try{ // 1. 获取数据库连接对象conn = JDBCUtils.getConnection(); // 2. sql 语句String sql = "delete from user where id = ?"; // 3. 创建执行sql的对象ps = conn.prepareStatement(sql); // 4. 给 ?赋值ps.setInt(1, 4); // 5. 执行sqlintcount = ps.executeUpdate(); if(count > 0) { System.out.println("删除成功"); } else{ System.out.println("删除失败"); } } catch(Exception e) { e.printStackTrace(); } finally{ // 6. 释放资源JDBCUtils.close(ps, conn); } }

除注明外的文章,均为来源:老汤博客,转载请保留本文地址!
原文地址: