JDBC知识第一部分—JDBC的介绍以及获取数据库连接的几种方式
JDBC的介绍以及获取数据库连接的几种方式
1.JavaWeb技术体系
2.JDBC概述
2.1 数据持久化
持久化(persistence):把数据保存在可掉电式存储设备中以供之后使用。大多数情况下,特别是企业级应用,数据持久化意味着将内存中的数据保存在硬盘中加以固化,而持久化的过程大多都是通过各种关系数据库来完后的。
持久化的主要应用是将内存中的数据存储在关系型数据库中,当然也可以存储在磁盘文件、xml数据文件中。
2.2 Java中的数据存储技术
在Java中数据存储技术可以分为如下几类:
JDBC直接访问数据库。
JDO(Java Data Object)技术。
第三方O/R技术,如hibernate、mybatis等
JDBC是Java访问数据库的基石,JDO、Hibernate、Mybatis等技术只是对JDBC进行了封装
2.3 JDBC介绍
JDBC(Java DataBase Connectivity)是一个独立于特定数据库管理系统、通用SQL数据库存取和操作的公共接口(一组API)。定义了用来访问数据库的标准Java类库,(java.sql、javax.sql)使用这些类库可以以一种标准的方法,方便的访问数据库资源。
JDBC为访问不同的数据库提供了一种统一的途径,为开发者屏蔽了一些细节问题。
JDBC的目标是使Java程序员可以通过JDBC链接任何一种提供了JDBC驱动程序的数据库系统,这样使得程序员无需了解每一个数据库系统的特点,大大的提高了开发的效率。
在没有JDBC的情况下,Java程序访问1数据库时是这样的
有了JDBC之后,Java程序通过以下方式访问数据库
总结如下:
2.4 JDBC的体系结构
JDBC接口(API)提供了两个层次
面向应用的API:Java API,抽象接口,供应用程序开发人员使用(链接数据库、执行sql语句、获得结果)
面向数据库的API:Java Driver API,供开发商开发数据库驱动程序用。
2.5 JDBC的编写步骤
3. 获取数据库连接的五种方法
注意:数据库的连接在使用完之后需要手动关闭,且必须关闭,对于出现异常的地方,我们需要使用try-catch-finally语句来处理,下面代码只是测试并未采用正确的处理方式,正确的处理方法会放在封装类中体现。
方式一:使用Driver接口实现类(最原始的方法)
@Test public void getConnectionFirst() throws SQLException { //1.创建一个Driver实例,Driver是一个接口,需要用实现类来创建实例 Driver driver =new com.mysql.cj.jdbc.Driver(); /*这里注意:mysql8.0以上版本需要添加时区,否则获取不到数据库的连接 报错信息:java.sql.SQLException: The server time zone value '�й���ʱ��' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the 'serverTimezone' configuration property) to use a more specifc time zone value if you want to utilize time zone support. */ String url="jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=true"; Properties properties=new Properties(); properties.setProperty("user","root"); properties.setProperty("password","root"); //使用Driver的connect方法来获取一个数据库连接,需要传递两个参数,一个是String类型的url,一个用于与数据库连接的账号和密码(可以传递一个properties对象,也可以直接传入账号和密码) Connection connect = driver.connect(url,properties); System.out.println(connect); }
方式二:对方式一进行优化,避免出现第三方类com.mysql.cj.jdbc.Driver.我们使用反射的技术在动态获取driver实例
@Test public void getConnectionSecond() throws Exception { //使用反射来替换第三方类的出现 Class driver = Class.forName("com.mysql.cj.jdbc.Driver"); Driver instance = (Driver) driver.newInstance(); String url="jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=true"; Properties properties=new Properties(); properties.setProperty("user","root"); properties.setProperty("password","root"); Connection connect = instance.connect(url, properties); System.out.println(connect); }
方式三:使用DriverManger类来获取数据库连接,DriverManager类用来管理数据库中的所有驱动程序,是JDBC的管理层,作用于用户和驱动程序之间,跟踪可用的驱动程序,并在数据库的驱动程序之间建立连接.此外,DriverManager类中的方法都是静态方法,所以在程序中无须对它进行实例化,直接通过类名就可以调用.DriverManager类的常用方法有getConnection(String url,String user,String password)方法
@Test public void getConnectionThree() throws Exception { Class name = Class.forName("com.mysql.cj.jdbc.Driver"); Object instance = name.newInstance(); Driver manager = (Driver) instance; //使用driverManger替换Driver来获取连接,使用drivermanager需要注册驱动 /* DriverManager类用来管理数据库中的所有驱动程序,是JDBC的管理层,作用于用户和驱动程序之间, 跟踪可用的驱动程序,并在数据库的驱动程序之间建立连接.此外,DriverManager类中的方法都是静态方法, 所以在程序中无须对它进行实例化,直接通过类名就可以调用. */ DriverManager.deregisterDriver(manager); // String url="jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=true"; Properties properties=new Properties(); properties.setProperty("user","root"); properties.setProperty("password","root"); // Connection connection = DriverManager.getConnection(url, "root", "root"); Connection connection = DriverManager.getConnection(url, properties); System.out.println(connection); }
方式四:简化方式三中的代码。在Driver的实现类中(com.mysql.cj.jdbc.Driver)定义了一个注册驱动的静态代码块,所以我们无需亲自去注册,可以直接使用DriverManager类来调用相应的方法
@Test public void getConnectionForth() throws Exception { //1.在Driver类的源码中,定义了一个自动注册驱动信息的静态代码块如下: /*源码地址在mysql的jar包com.mysql.cj.jdbc.Driver类中 public class Driver extends NonRegisteringDriver implements java.sql.Driver { public Driver() throws SQLException { } static { try { DriverManager.registerDriver(new Driver()); } catch (SQLException var1) { throw new RuntimeException("Can't register driver!"); } } } */ //因此可以对方式三中的代码进行进一步的优化 //获取数据库驱动信息 Class aClass = Class.forName("com.mysql.cj.jdbc.Driver"); //直接使用DriverManger的getConnection()方法获取数据库连接 String url="jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=true"; Connection connection = DriverManager.getConnection(url, "root", "root"); System.out.println(connection); }
方式五:使用配置文件来读取数据库的相关配置。这样我们在修改数据库信息时,无需修改代码,只需要修改配置文件即可(该方式是最终版的获取数据库连接的方式,也是开发中较为常用的方式)
@Test public void getConnectionFifth() throws Exception { //使用配置文件来读取数据库相关信息,好处是当我们需要修改数据库的连接信息时无需修改代码,直接修改配置文件即可 //1.使用当前类对象创建一个输入流 InputStream is = GetConnection.class.getClassLoader().getResourceAsStream("jdbc.properties"); //2.使用properties加载配置文件 Properties properties = new Properties(); properties.load(is); //3.获取数据库连接 Class.forName(properties.getProperty("driverClass")); Connection connection = DriverManager.getConnection(properties.getProperty("url"), properties.getProperty("user"), properties.getProperty("password")); System.out.println(connection); }
封装一个公共类用来获取数据库连接:在一个项目中,我们需要对数据库进行频繁的增删改查操作,为了提高代码的重用性,降低代码的冗余度,我们可以考虑将获取数据库连接以及关闭数据库连接的代码封装成为一个工具类,在之后的开发中,需要使用到相应的代码只需要直接使用即可。
/** *@description: 可重用的用来获取数据库连接的方法 *@author: summerHouAnNing *@creatTime: 2021/4/10--14:44 *@Param: *@return: **/ public static Connection getConnection() throws Exception { //1.使用反射提供一个输入流用来读取配置文件 InputStream asStream = ClassLoader.getSystemClassLoader().getResourceAsStream("jdbc.properties"); //2.使用properties对象加载配置文件 Properties properties = new Properties(); properties.load(asStream); //3.加载驱动 Class aClass = Class.forName(properties.getProperty("driverClass")); //4.使用DriverManager获取数据库连接 Connection connection = DriverManager.getConnection(properties.getProperty("url"), properties.getProperty("user"), properties.getProperty("password")); return connection; }
/** *@description: 可重用的用来关闭数据库连接的方法 *@author: summerHouAnNing *@creatTime: 2021/4/10--14:44 *@Param: *@return: **/ public static void closeConnection(Connection coon){ try { if (coon != null) coon.close(); } catch (SQLException throwables) { throwables.printStackTrace(); } }