J DBC相关

news2025/1/10 23:42:34

  • JDBC基础
    • 什么是JDBC
    • 入门程序
    • 功能类
    • 工具类
    • SQL注入攻击
      • 原理
      • PreparedStatement的介绍
  • 数据库连接池
    • 原理
    • 自定义连接池
    • 归还连接
  • JDBC框架
    • 自定义JDBC框架

JDBC基础

什么是JDBC

用于执行SQL语句的java API,实现不同关系型数据库的连接

入门程序

  1. 导入jar包

  2. 注册驱动

  3. 获取连接

  4. 获取执行者对象

  5. 执行sql语句,并接收返回结果

  6. 处理结果

  7. 释放资源

功能类

DriverManager:驱动管理对象

注册驱动(告诉程序该使用哪一个数据库驱动)
获取数据库连接(获取到数据库的连接并返回连接对象)

Connection:数据库连接对象

获取执行者对象
管理事务
释放资源

Statement:执行sql语句的对象

执行DML语句
执行DQL语句
释放资源

ResultSet:结果集对象

判断结果集中是否还有数据
获取结果集中的数据
释放资源

工具类

工具类的抽取:
配置文件(在src下创建config.properties)

driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/db14
username=root
password=itheima

工具类

/*
    JDBC工具类
 */
public class JDBCUtils {
    //1.私有构造方法
    private JDBCUtils(){};

    //2.声明配置信息变量
    private static String driverClass;
    private static String url;
    private static String username;
    private static String password;
    private static Connection con;

    //3.静态代码块中实现加载配置文件和注册驱动
    static{
        try{
            //通过类加载器返回配置文件的字节流
            InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("config.properties");

            //创建Properties集合,加载流对象的信息
            Properties prop = new Properties();
            prop.load(is);

            //获取信息为变量赋值
            driverClass = prop.getProperty("driverClass");
            url = prop.getProperty("url");
            username = prop.getProperty("username");
            password = prop.getProperty("password");

            //注册驱动
            Class.forName(driverClass);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //4.获取数据库连接的方法
    public static Connection getConnection() {
        try {
            con = DriverManager.getConnection(url,username,password);
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return con;
    }

    //5.释放资源的方法
    public static void close(Connection con, Statement stat, ResultSet rs) {
        if(con != null) {
            try {
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

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

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

    public static void close(Connection con, Statement stat) {
        close(con,stat,null);
    }
}

SQL注入攻击

原理

Statement对象在执行sql语句时,将一部分内容当做查询条件来执行了

PreparedStatement的介绍

  • 预编译sql语句的执行者对象。在执行sql语句之前,将sql语句进行提前编译。明确sql语句的格式后,就不会改变了。剩余的内容都会认为是参数!参数使用?作为占位符
  • 为参数赋值的方法:setXxx(参数1,参数2);
    • 参数1:?的位置编号(编号从1开始)
    • 参数2:?的实际参数
  • 执行sql语句的方法
    • 执行insert、update、delete语句:int executeUpdate();
    • 执行select语句:ResultSet executeQuery();

数据库连接池

原理

在这里插入图片描述

自定义连接池

java.sql.DataSource接口:数据源(数据库连接池)。java官方提供的数据库连接池规范(接口)

  • 获取数据库连接对象:Connection getConnection();
/*
	自定义连接池类
*/
public class MyDataSource implements DataSource{
    //定义集合容器,用于保存多个数据库连接对象
    private static List<Connection> pool = Collections.synchronizedList(new ArrayList<Connection>());

    //静态代码块,生成10个数据库连接保存到集合中
    static {
        for (int i = 0; i < 10; i++) {
            Connection con = JDBCUtils.getConnection();
            pool.add(con);
        }
    }

    //返回连接池的大小
    public int getSize() {
        return pool.size();
    }

    //从池中返回一个数据库连接
    @Override
    public Connection getConnection() {
        if(pool.size() > 0) {
            //从池中获取数据库连接
            return pool.remove(0);
        }else {
            throw new RuntimeException("连接数量已用尽");
        }
    }

    @Override
    public Connection getConnection(String username, String password) throws SQLException {
        return null;
    }

    @Override
    public <T> T unwrap(Class<T> iface) throws SQLException {
        return null;
    }

    @Override
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        return false;
    }

    @Override
    public PrintWriter getLogWriter() throws SQLException {
        return null;
    }

    @Override
    public void setLogWriter(PrintWriter out) throws SQLException {

    }

    @Override
    public void setLoginTimeout(int seconds) throws SQLException {

    }

    @Override
    public int getLoginTimeout() throws SQLException {
        return 0;
    }

    @Override
    public Logger getParentLogger() throws SQLFeatureNotSupportedException {
        return null;
    }
}

归还连接

继承(无法解决)

  • 通过打印连接对象,发现DriverManager获取的连接实现类是JDBC4Connection。
  • 自定义一个类,继承JDBC4Connection这个类,重写close()方法。
/*
    自定义Connection类
 */
public class MyConnection1 extends JDBC4Connection {
    //声明连接对象和连接池集合对象
    private Connection con;
    private List<Connection> pool;

    //通过构造方法给成员变量赋值
    public MyConnection1(String hostToConnectTo, int portToConnectTo, Properties info, String databaseToConnectTo, String url,Connection con,List<Connection> pool) throws SQLException {
        super(hostToConnectTo, portToConnectTo, info, databaseToConnectTo, url);
        this.con = con;
        this.pool = pool;
    }

    //重写close()方法,将连接归还给池中
    @Override
    public void close() throws SQLException {
        pool.add(con);
    }
}

虽然自定义了一个子类,完成了归还连接的操作。但是DriverManager获取的还是JDBC4Connection这个对象,并不是我们的子类对象。而我们又不能整体去修改驱动包中类的功能!

适配器设计模式

  • 有很多个需要实现的方法的时候,就可以使用适配器设计模式。提供一个适配器类,实现Connection接口,将所有功能进行实现(除了close方法)。自定义连接类只需要继承这个适配器类,重写需要改进的close()方法即可!

动态代理

  • 经过适配器模式的改进,自定义连接类中的方法已经很简洁了。剩余所有的方法已经抽取到了适配器类中。但是适配器这个类还是自己编写的,也比较麻烦!所以使用动态代理的方式来改进。

JDBC框架

  • 抽取出一个JDBC模板类,来封装一些方法(update、query),专门帮我们执行增删改查的sql语句!
  • 将之前那些重复的操作,都抽取到模板类中的方法里。就能大大简化我们的使用步骤!

自定义JDBC框架

数据库的源信息

DataBaseMetaData(了解):数据库的源信息
ResultSetMetaData:结果集的源信息

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/146347.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux驱动开发基础__gpio子系统重要概念

目录 1 引入 2 在设备树中指定引脚 3 在驱动代码中调用GPIO子系统 4 sysfs 中的访问方法 1 引入 要操作 GPIO 引脚&#xff0c;先把所用引脚配置为 GPIO 功能&#xff0c;这通过 Pinctrl 子系统来实现。 然后就可以根据设置引脚方向(输入还是输出)、读值──获得电平状…

Windows Docker Desktop开放API端口2375用于远程调用

Windows Docker Desktop开放API端口2375用于远程调用问题解决开启IP Helper服务开启Docker配置开放2375端口端口映射找到需要暴露的IP执行端口映射命令Windows防火墙关闭防火墙添加防火墙规则测试问题 Windows Docker Desktop为了安全&#xff0c;默认设置中只有localhost:237…

入门的葡萄酒知识

葡萄酒的分类&#xff08;根据制造方法&#xff09; 静态葡萄酒 红葡萄酒 Red Wine&#xff0c;白葡萄酒 White Wine&#xff0c;玫瑰红/桃红/粉红葡萄Rose Wine。 气泡&#xff08;起泡&#xff09;葡萄酒 有气泡的葡萄酒&#xff0c;分香槟Champagne及气泡葡萄酒两类。只有在…

Servlet(上)

Servlet组件(上) 学习目标 了解Web资源的概念了解为什么需要Servlet掌握Servlet是什么掌握Servlet的HelloWorld掌握Servlet的执行原理掌握Servlet的生命周期和生命周期方法掌握ServletConfig的使用掌握Servlet的体系结构掌握Servlet的映射路径的编写方式掌握创建Servlet最常用…

机器学习简单介绍

机器学习简介 定义 机器学习是人工智能(AI)和计算机科学的一个分支&#xff0c;专注于使用数据和算法来模仿人类的学习方式&#xff0c;逐步提高其准确性。 简单来说&#xff0c;是一种运用数学公式来对问题进行最优化求解的方法 分类 一般来说将&#xff1a;机器学习分为…

睿联技术在创业板过会:收入依赖摄像机单机,计划募资11亿元

2023年1月6日&#xff0c;深圳证券交易所披露的信息显示&#xff0c;深圳市睿联技术股份有限公司&#xff08;下称“睿联技术”&#xff09;获得创业板上市委员会审议通过。据贝多财经了解&#xff0c;睿联技术的上市申请于2022年6月2日获得创业板受理。 本次冲刺创业板上市&am…

Unity 3D 地形系统概述|| Unity 3D 创建地形

在三维游戏世界中&#xff0c;通常会将丰富多彩的游戏元素融合在一起&#xff0c;比如游戏中起伏的地形、郁郁葱葱的树木、蔚蓝的天空、、凶恶的猛兽等&#xff0c;营造出身临其境的游戏沉浸感&#xff0c;让玩家置身游戏世界&#xff0c;忘记现实。 地形作为游戏场景中必不可…

Git 基本概念

一、git 官网 https://git-scm.com/ 二、git 数据传输命令 三、基本操作 1、命令整理 命令说明git init初始化 git 库git config获取和设置存储库或全局配置项git status显示工作树状态git add将文件内容添加到index(暂存区)git commit将index(暂存区)修改提交到本地仓库gi…

你知道微服务架构中的“发件箱模式”吗

前言 微服务架构如今非常的流行&#xff0c;这个架构下可能经常会遇到“双写”的场景。双写是指您的应用程序需要在两个不同的系统中更改数据的情况&#xff0c;比如它需要将数据存储在数据库中并向消息队列发送事件。您需要保证这两个操作都会成功。如果两个操作之一失败&…

数据结构与算法—稀疏数组

稀疏数组 稀疏数组与二维数组 当一个数组中大部分元素都是0&#xff0c;或者为同一个值的数组时&#xff0c;可以使用稀疏数组来保存该数组。 二维数组转成稀疏数组&#xff1a; 从图中可以看出&#xff1a; 稀疏数组的行、列、值的 &#xff08;1&#xff09;[0]行&#x…

linux下软硬链接到底是什么?

文章目录前言硬链接软链接前言 在了解软硬链接之前&#xff0c;可以先来了解一下磁盘以及inode到底是什么 Linux文件管理—磁盘上文件如何管理&#xff08;inode&#xff09; 硬链接 什么是硬链接 在Linux下&#xff0c;系统标识文件的唯一方式就是inode号&#xff0c;而对…

【初阶数据结构】——双“指针”求解数组常见问题

文章目录前言题目1&#xff1a;移除元素思路1&#xff1a;暴力求解思路2&#xff1a;时间换空间思路3&#xff1a;双指针原地删除&#xff08;解法2的再优化&#xff09;思路分析代码实现题目2&#xff1a;删除有序数组中的重复项思路&#xff1a;双指针代码实现题目3&#xff…

【JavaScript】BOM 学习总结

基础知识&#xff1a; 获取浏览器窗口的尺寸&#xff1a; innerHeight&#xff1a;获取高度 innerWidth&#xff1a;获取宽度 跳转与刷新 location.href location.reload() body><button id"btn">跳转到下一个页面</button><button id"btn…

Java实现文件操作

目录 一、文件概述 二、常见文件操作 1、获取文件路径 2、判断文件存在以及判断类型 3、文件的创建与删除 4、展示文件夹的文件 5、创建文件夹 三、用数据流来读取文件内容 1、操作字节流文件 a、读取字节流文件 b、写字节流文件 2、操作字符流对象 a、读取…

C++ · 入门 · 03 | 函数重载

啊我摔倒了..有没有人扶我起来学习.... 目录前言函数重载1.1 函数重载概念1.2 函数重载的意义1.3 C支持函数重载的原理--名字修饰(name Mangling)1.4 返回值不同能否构成函数重载?前言 自然语言中&#xff0c;一个词可以有多重含义&#xff0c;人们可以通过上下文来判断该词真…

小米 2021 秋招面试总结

岗位:嵌入式软件工程师(相机驱动岗) 面试时间: 40 分钟 薪资: 28w+ 面试过程 面试官上来先来了一段他自己的自我介绍,流程还是比较规范的。 1、请进行一个简单的自我介绍(2分钟) 2、C语言全局变量可否定义在头文件中? 回答:不能,并且这不是一个好的习惯。 3…

【自学C++】C++输出cout

C输出cout C输出cout教程 在 C 语言 中我们需要输出一个 变量&#xff0c;可以使用 printf。printf 函数 在输出时&#xff0c;我们必须要指定输出的数据类型对应的格式化符&#xff0c;挺不方便。 在 C 中&#xff0c;我们要输出变量&#xff0c;直接使用 std 命名空间中的…

国科大抢课避坑+选课指南+教务系统操作

博客园&#xff1a; https://www.cnblogs.com/phoenixash/p/13669461.html 9月12日12&#xff1a;30&#xff0c;本菜鸡终于经历了国科大传说中的抢课大战&#xff0c;虽然自己之前准备的较多&#xff0c;但还是在抢课的时候掉进了不少坑里&#xff0c;趁现在还记忆犹新&#x…

【pandas】教程:10-文本数据的操作

Pandas 文本数据的操作 本节使用的数据为 data/titanic.csv&#xff0c;链接为 pandas案例和教程所使用的数据-机器学习文档类资源-CSDN文库 读入数据 import pandas as pd titanic pd.read_csv("data/titanic.csv")PassengerId Survived Pclass \ 0 …

指针进阶(2)

Tips 1. 2. 3. 碰到地址就等价于指针变量&#xff0c;里面存放着该地址的指针变量 4. 数组指针是存放数组的地址&#xff0c;指向的是一个数组&#xff1b;函数指针存放的是函数的地址&#xff0c;指向的是一个函数。 5. 地址就是指针&#xff0c;地址就是指针 6. 数…