JDBC入门

110 阅读6分钟

本文已参与「新人创作礼」活动, 一起开启掘金创作之路。

1 JDBC的由来和定义

1.1 JDBC的由来

想要通过Java语言来操作数据库,而市面上数据库厂商很多,使用的方法不统一,那万一遇到需要更换数据库的业务就会非常的麻烦,那就不如来个大统一,制定的统一的规范,让对这些数据库的操作方式在Java程序上一样,这样JDBC就诞生了!

1.2JDBC的定义

  1. JDBC是由SUN公司定义的一套连接所有关系型数据库的接口。
  2. 这些接口的实现由数据库厂商实现。
  3. 每个公司都根据自己的数据库设计jar包。

可以把JDBC看成服装设计公司,数据库看成制衣厂

服装设计公司只负责将服装的图纸设计出来,制衣厂根据图纸将衣服生产出来,而各个制衣厂可能机器和生产流程不一样,但是最后生产出来的服装款式都是一样的。

2 JDBC体验

2.1连接前的准备:

  1. 软件准备:
    1. IDEA(用什么IDE都可以)
    2. Mysql
  2. Jar包准备:
    1. mysql-connector-java-5.1.6.jar
  3. 将Jar包放入lib文件夹下,导入jar包

2.2 JDBC API

接口作用
Driver驱动接口,定义建立链接的方式
DriverManager工具类,用于管理驱动,可以获取数据库的链接
Connection表示Java与数据库建立的连接对象(接口)
PreparedStatement发送SQL语句的工具
ResultSet结果集,用于获取查询语句的结果

2.3 JDBC编码步骤

主要有这六个步骤

  1. 加载驱动,利用Class.forName(Driver)至DriverManager
  2. 获取连接,从DriverManager中,通过JDBC URL,用户名,密码来获取相应的数据库连接(Connection)
  3. 准备发送SQL的工具,获取Connection后,可以创建Statement用来运行SQL语句
  4. 执行SQL,使用statement.executeQuery执行Sql语句
  5. 处理结果集,将结果存放在结果集(ResultSet)中
  6. 释放资源,关闭Statement,关闭Connection。

编码:

代码可以理解为:

  1. 找到你想要送去的制衣厂(Driver)并联系他们的经理(DriverManager)
  2. 和制衣厂经理(DirverManager)取得联系(Connection)并谈好了价钱,经历给我们地址和通行证(URL,USER,PASSWORD)
  3. 这边派一个人(Statement)把我们公司的合同和图纸(Sql)送过去
  4. 制衣厂通过合同和图纸(Sql)开始制作衣服(statement.executeQuery)
  5. 将根据合同和图纸(Sql)生产完成的衣服放到装衣服的箱子里(ResultSet)
  6. 根据合同结束了合作,那送图纸的人(Statement)回到公司,联系(Connection)结束
import java.sql.*;

public class Demo {
    public static final String URL = "jdbc:mysql://localhost:3306/student";
    public static final String USER = "root";
    public static final String PASSWORD = "123456";

    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //1.加载驱动,
        Class.forName("com.mysql.jdbc.Driver");
        //2.获取连接,
        Connection connection =  (Connection)DriverManager.getConnection(URL,USER,PASSWORD);
        //3准备Sql发送的工具
        Statement statement = connection.createStatement();
        //4.执行Sql
        ResultSet resultSet = statement.executeQuery("SELECT * FROM info");
        //5.处理结果集
        while(resultSet.next()){
            int id = resultSet.getInt(1);
            String name = resultSet.getString(2);
            int age = resultSet.getInt(3);
            System.out.println("id: " + id + ",name: " + name + ",age: " + age);
        }
        //6.释放资源
        statement.close();
        connection.close();
    }
}

3 整理和释放

上述代码是可以正常运行的,但是还是存在问题,为了防止SQL语句写错或者其他的问题导致程序一直往下走,我们使用try{}catch{}包裹一些代码,同时也为进一步封装成工具做准备。

代码如下,过程和上面的代码是一样的,只是做了一些小改动,会变得更加的优雅

package com.study.JDBC;

import java.sql.*;

public class Demo {
    public static final String URL = "jdbc:mysql://localhost:3306/student";
    public static final String NAME = "root";
    public static final String PASSWORD = "123456";
    public static final String DRIVER = "com.mysql.jdbc.Driver";

    public static Connection connection;
    public static Statement statement;
    public static ResultSet resultSet;
    public static void main(String[] args) {
        try {
            //1.加载驱动
            Class.forName(DRIVER);
            //2.获取连接
            connection = DriverManager.getConnection(URL,NAME,PASSWORD);
            //3.准备SQL发送工具
            statement = connection.createStatement();
            //4.执行SQL语句
            resultSet = statement.executeQuery("SELECT * FROM info");
            //5.整理结果集
            while(resultSet.next()){
                int id = resultSet.getInt(1);
                String name = resultSet.getString(2);
                int age = resultSet.getInt(3);
                System.out.println("id: " + id + ",name: " + name + ",age: " + age);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                //6.释放资源
                resultSet.close();
                statement.close();
                connection.close();
            }catch (SQLException e){
                e.printStackTrace();
            }
        }

    }
}

4封装JDBCUtils

4.1 为什么要封装成工具类?

上述的代码,我们可以将main函数中的程序语句拿出来,写成一个函数,通过传送不通的Sql语句来实现不同函数的使用,如下:

import java.sql.*;

public class Demo {
    public static final String URL = "jdbc:mysql://localhost:3306/student";
    public static final String NAME = "root";
    public static final String PASSWORD = "123456";
    public static final String DRIVER = "com.mysql.jdbc.Driver";

    public static Connection connection;
    public static Statement statement;
    public static ResultSet resultSet;
    public static void main(String[] args) {
        selectAll();
        selectById();
    }
    public static void selectAll(){...}  
    public static void selectById(){...}
}

但是你会发现,如果我们想要换个类写,我们就要把上面的配释文件全部重新写一遍。优秀的程序员要学会ctrl + cctrl + v,但是更优秀的程序员,要学会戒掉它们,那我们是否可以将这些配置文件,写在文件里,然后通过一个工具类来读取这段配置文件,帮助我们配置?当然可以!

4.2 封装过程

  1. 编写好配置文件db.properties

    在相应的包下创建db.properties,并且编写好

    url = jdbc:mysql://localhost:3306/student?characterEncoding=UTF-8
    name = root
    password = 123456
    driver = com.mysql.jdbc.Driver
    
  2. 通过静态代码块来预先执行文件的配置,做预处理。

    static {
            try{
                //这里要使用对应的路径,不然会找不到
                InputStream inputStream = ClassLoader.getSystemResourceAsStream("com/study/JDBC/db.properties");
                Properties properties = new Properties();
                properties.load(inputStream);
    
                driver = properties.getProperty("driver");
                url = properties.getProperty("url");
                name = properties.getProperty("name");
                password = properties.getProperty("password");
                //测试有没有获取到值
                System.out.println("driver:" + driver + "\n" + "url:" + url + "\n" + "name:" + name + "\n" + "password:" + password);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    
  3. 测试上述配置是否成功

    测试的结果是正确的:

  4. 获取连接

    使用这个工具类获取到我们的配置文件的信息后,我们就将这些信息拿去获取连接

    public static Connection getConnection() throws SQLException {
    	return DriverManager.getConnection(url,name,password);
    }
    
  5. 关闭连接

    当然工具类的作用还可以很多,我们还可以将关闭功能也添加上去

    //这里关闭的是Statement和Connection
    public static void close(Statement statement, Connection connection) throws SQLException {
    	if(statement != null){
    		statement.close();
    	}
    	if(connection != null){
    		connection.close();
    	}
    }
    //这里关闭的是ResultSet、Statement和Connection(Sql是没有结果集的)
    public static void close(Statement statement, Connection connection, ResultSet resultSet) throws SQLException {
    	if(resultSet != null){
    		resultSet.close();
    	}
    	if(statement != null){
    		statement.close();
    	}
    	if(connection != null){
    		connection.close();
    	}
    }
    

    4.3Utils的完整代码

    import java.io.InputStream;
    import java.sql.*;
    import java.util.Properties;
    
    public class JDBCUtils {
        private static String driver;
        private static String url;
        private static String name;
        private static String password;
    
        //通过静态代码块来预先执行文件的配置,做预处理。
        static {
            try{
                //这里要使用对应的路径,不然会找不到
                InputStream inputStream = ClassLoader.getSystemResourceAsStream("com/study/JDBC/db.properties");
                Properties properties = new Properties();
                properties.load(inputStream);
    
                driver = properties.getProperty("driver");
                url = properties.getProperty("url");
                name = properties.getProperty("name");
                password = properties.getProperty("password");
    
                System.out.println("driver:" + driver + "\n" + "url:" + url + "\n" + "name:" + name + "\n" + "password:" + password);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    
        //取得连接
        public static Connection getConnection() throws SQLException {
            return DriverManager.getConnection(url,name,password);
        }
    
        //两个关闭函数
        public static void close(Statement statement, Connection connection) throws SQLException {
            if(statement != null){
                statement.close();
            }
            if(connection != null){
                connection.close();
            }
        }
        public static void close(Statement statement, Connection connection, ResultSet resultSet) throws SQLException {
            if(resultSet != null){
                resultSet.close();
            }
            if(statement != null){
                statement.close();
            }
            if(connection != null){
                connection.close();
            }
        }
    }
    

5使用Utils来完成增删改查

接下来就来体验一下我们写的工具类,使用它如何优雅的实现增删改查,这里只演示一个:

import org.junit.Test;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
public class TestUtils {
    public static Connection connection;
    public static Statement statement;
    @Test
    public void testUpdate(){
        try{
            connection = JDBCUtils.getConnection();
            statement = connection.createStatement();
            String sql = "update info set name= 'xiaoliao' where id=5";
            int res = statement.executeUpdate(sql);
            if(res > 0){
                System.out.println("insert success!");
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                JDBCUtils.close(statement,connection);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

6.小结

这里将JDBC的由来和使用过程到将JDBC封装都讲完了,JDBC重要的是多练习和尝试,大家可以在上面讲述的基础上写出更多增删改的SQL语句,熟练掌握怎么使用,后面还有PreparedStatement和问号占位这些知识点,好虚还需要进行一小段的学习。