前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JDBC从0到1的学习 (提供JDBC 工具类,数据库连接池工具类)

JDBC从0到1的学习 (提供JDBC 工具类,数据库连接池工具类)

作者头像
一写代码就开心
发布2022-05-14 09:50:17
6870
发布2022-05-14 09:50:17
举报
文章被收录于专栏:java和python

目录

1 jdbc概念

2 jdbc原理

也就是,jdbc是基准,其他公司,比如mysql,oracle这些公司,基于这个jdbc基本,封装jdbc基准里面的api,变为自己的,也就是变为自己的东西,这个就是驱动类;

我们连接mysql,需要mysql的驱动类driver;连接oracle,需要oracle的驱动类,这些驱动类就是各个数据库厂家提供的;

3 jdbc加载驱动代码

我们创建一个maven,导入mysql的依赖

代码语言:javascript
复制
    <!--mysql驱动包-->
    <dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.35</version>
        </dependency>
    </dependencies>

以上这个是mysql的驱动包,这个就是mysql数据库公司封装了jdbc之后,自己的东西,以后我们使用这个驱动包,就可以在代码里面连接mysql数据库,并且操作数据库了;

以上在maven项目的pom文件里面写了这个,就相当于引入了mysql的驱动

mysql的驱动名称是com.mysql.jdbc.Driver

这个是mysql公司定的,我们使用就可以,我们在项目里面看看,能不能拿到这个对应的驱动

以上说明,只要添加了驱动,我们就可以在代码里面获取到驱动;

3.1 看源码

首先我们导入mysql的jar包,这个jar包就是mysql公司,封装了jdbc接口实现的一个项目,一个jar包就是一个项目,因为这个项目实现了java的jdk给提供的jdbc的接口,所以,我们就可以使用这个项目进行操作数据库,首先,每一个项目都有一个项目的入口,mysql的这个jar包也有,现在就是叫做驱动类,只要我们自己的项目,加载了这个驱动类,那么就有了mysql这个jar包的入口了;

1 我们看mysql的jar包的源码

找到驱动类

看这个类里面的代码

就相当于,我们一创建这个驱动类的对象,或者加载这个类,那么当前的jar包就和我们的jdk关联了;

3.2 为什么不需要我们自己注册

因为人家的jar包,已经有一个配置文件,这个里面配置了驱动类,直接读取这个配置文件,直接就可以进行注册,不需要我们自己注册

4 类对象介绍

4.1 DriverManager

这个类是jdk里面的,

4.2 Connection

这个类的对象,就是获取到了对应数据库的对象,之后根据这个对象,就可以操作数据库

4.3 statement

4.4 ResultSet

5 JDBC 工具类

这个工具类的作用就是,以后有人拿到这个代码,按照这个工具类里面的方法就可以操作数据库了

写一个配置文件

配置文件里面的内容是

代码语言:javascript
复制
url=jdbc:mysql://localhost:3306/eshop
user=root
password=123456
driver=com.mysql.jdbc.Driver
代码语言:javascript
复制
public class JDBCUtils {

// 1 私有构造方法
    private JDBCUtils(){};


//    2 声明所需要的配置变量
    private static String url ;
    private static String user ;
    private static String password ;
    private static String driver;


//    3 提供静态代码块,读取配置文件里面的信息为变量赋值,注册驱动
    static {
        Properties pro = new Properties();
        //这里是通过类加载器获取jdbc.propertise的绝对路径
        //首先获取类的加载器,然后通过类的加载器获取src路径下资源的绝对路径
        //这里的意思是不管模块如何移植,只要在模块当中,就能通过相对路径找到
        //绝对路径
        ClassLoader loader = JDBCUtils.class.getClassLoader();
        //通过类加载器获取scr路径下的资源的绝对路径
        URL res = loader.getResource("JDBC.properties");
        //获取绝对路径
        String path = res.getPath();

        try {
            pro.load(new FileReader(path));
        } catch (IOException e) {
            e.printStackTrace();
        }
        url = pro.getProperty("url");
        user = pro.getProperty("user");
        password = pro.getProperty("password");
        driver = pro.getProperty("driver");


        try {
            Class.forName(driver);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }


//    获取连接对象
    public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection(url,user,password);
    }


//    关闭statement对象   和   Connection对象
    public static void close(Statement stmt, Connection conn){
        if (stmt!=null){
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if (conn!=null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }


//     关闭statement对象   和   Connection对象  和  ResultSet对象
    public static void close(ResultSet rs, Statement stmt, Connection conn){

        if (rs!=null){
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if (stmt!=null){
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if (conn!=null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }


}

6 解决sql注入问题

就是使用预编译

7 JDBC 管理事务

如果多个方法都有事务,一个方法调用另一个方法,那么要保证多个方法使用的数据库的连接对象是同一个;

8 jdbc 获取数据库连接对象connection

我们在项目里面已经加载了驱动,之后根据驱动,就可以连接到mysql数据库了;这个驱动里面有很多的接口或者类,我们在代码里面只要操作这些,就可以操作数据库了;

我们首先要使用驱动获取到数据库连接,就是相当于获取到一个数据库对象,以后就可以拿这个对象进行操作数据库了;

代码语言:javascript
复制
package com.jing;/**
 * @author jing
 * @date 2022/3/29  --  19:13
 */

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

/**
 * @author jing
 * @date 2022年03月29日 19:13
 */
public class jdbctest02 {

//    我要连接哪个数据库
    private static String dbUrl="jdbc:mysql://localhost:3306/eshop";
//    数据库的用户名
    private static String username = "root";
//    数据库的密码
    private static String password = "123456";
//    使用哪个驱动进行连接数据库
    private static String jdbcName = "com.mysql.jdbc.Driver";

    public static void main(String[] args) {
        try {
//            当前项目加载驱动
            Class.forName(jdbcName);
            System.out.println("加载成功");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            System.out.println("加载失败");
        }
        Connection connection =null;
        try {
//            DriverManager 是驱动包里面的类,使用这个类里面的各种各样的方法进行操作数据库
            connection = DriverManager.getConnection(dbUrl, username, password);
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

    }
}

我们获取到connection对象,以后就在项目里面,就可以使用这个去操作数据库;

9 使用statement接口实现crud

我们以上已经获取到了数据库连接对象connection,使用这个获取statement接口对象,使用里面的方法就可以执行sql语句了,这个sql语句和我们在Navicat里面执行一样;

就是使用statement去操作sql语句;

代码语言:javascript
复制
public class jdbctest02 {

//    我要连接哪个数据库
    private static String dbUrl="jdbc:mysql://localhost:3306/eshop";
//    数据库的用户名
    private static String username = "root";
//    数据库的密码
    private static String password = "123456";
//    使用哪个驱动进行连接数据库
    private static String jdbcName = "com.mysql.jdbc.Driver";

    public static void main(String[] args) {
        try {
//            当前项目加载驱动
            Class.forName(jdbcName);
            System.out.println("加载成功");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            System.out.println("加载失败");
        }
        Connection connection =null;
        Statement statement =null;
        try {





//            DriverManager 是驱动包里面的类,使用这个类里面的各种各样的方法进行操作数据库
            connection = DriverManager.getConnection(dbUrl, username, password);
            statement = connection.createStatement();
            String sql = "select *  from product";
            boolean execute = statement.execute(sql);
            System.out.println(execute);



        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            try {
                statement.close();
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

    }
}

10 数据库连接池

10.1 概念

10.2 DataSource

这个是一个接口,java的jdk提供的,所以我们想要创建一个数据库连接池,就得自己写一个类,实现这个接口;

或者直接自己写一个类

代码语言:javascript
复制
package com.jing.utils;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.Properties;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 *
 *
 *
 */
public class DataSourcePool {
    /**
     * 最大连接数
     */
    private static final int COUNT = 10;
    /**
     * 存放数据库
     */
    private static final LinkedList<Connection> connections = new LinkedList<Connection>();
    /**
     * 创建锁
     */
    private static final ReentrantLock lock = new ReentrantLock();
    private static final Condition notEmpty = lock.newCondition();
    private static final Condition notFull = lock.newCondition();
    /**
     * 数据库连接
     */
    private static String URL;
    /**
     * 用户名
     */
    private static String USER_NAME;
    /**
     * 密码
     */
    private static String PASS_WORD;
    /**
     * 驱动类型
     */
    private static String DRIVER_CLASS_NAME;
    /**
     * 存放属性信息
     */
    private static Properties properties = new Properties();

    /**
     * 初始化信息
     */
    static {
        InputStream is = DataSourcePool.class.getResourceAsStream("JDBC.properties");
        try {
            properties.load(is);
            URL = (String) properties.get("url");
            USER_NAME = (String) properties.get("userName");
            PASS_WORD = (String) properties.get("passWord");
            DRIVER_CLASS_NAME = (String) properties.get("driver");
            //加载驱动
            Class.forName(DRIVER_CLASS_NAME);
            Connection connection = null;
            for (int i = 0; i < 10; i++) {
                connection = DriverManager.getConnection(URL, USER_NAME, PASS_WORD);
                connections.add(connection);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取Connection
     */
    public static Connection getConnection() {
        final ReentrantLock reentrantLock = lock;
        reentrantLock.lock();
        try {
            //如果没有连接了,则等待着新放入的连接
            if (connections.isEmpty()) {
                notEmpty.await();
            }
            Connection connection = connections.removeFirst();
            notFull.signalAll();
            return connection;
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            reentrantLock.unlock();
        }
        return null;
    }

    /**
     * 释放连接
     *
     * @param connection
     */
    public static void release(Connection connection) {
        final ReentrantLock reentrantLock = lock;
        reentrantLock.lock();
        try {
            if (connections.size() == COUNT) {
                notFull.await();
            }
            if (connection == null || connection.isClosed()) {
                connections.add(DriverManager.getConnection(URL, USER_NAME, PASS_WORD));
                notEmpty.signalAll();
                return;
            }
            //恢复默认值
            if (connection.getAutoCommit() == false) {
                connection.setAutoCommit(true);
            }
            connections.add(connection);
            notEmpty.signalAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            reentrantLock.unlock();
        }
    }

}

11 自定义jdbc框架

之后我们使用的mybatis,就是封装了jdbc,把之前我们使用jdbc的语句封装了一下,因为我们就是要一个sql语句块,那些获取连接对象,关闭连接对象,都是公共的,我们不想操作,所以我们也要进行封装,可以这样说,这个自定义的jdbc的框架,就是mybatis框架的简化版;

11.1 需求

11.2 数据库源信息

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-05-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 目录
  • 1 jdbc概念
  • 2 jdbc原理
  • 3 jdbc加载驱动代码
    • 3.1 看源码
      • 3.2 为什么不需要我们自己注册
      • 4 类对象介绍
        • 4.1 DriverManager
          • 4.2 Connection
            • 4.3 statement
              • 4.4 ResultSet
              • 5 JDBC 工具类
              • 6 解决sql注入问题
              • 7 JDBC 管理事务
              • 8 jdbc 获取数据库连接对象connection
              • 9 使用statement接口实现crud
              • 10 数据库连接池
                • 10.1 概念
                  • 10.2 DataSource
                  • 11 自定义jdbc框架
                    • 11.1 需求
                      • 11.2 数据库源信息
                      相关产品与服务
                      云数据库 SQL Server
                      腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档