JDBC学习笔记(三)高级篇

news2024/12/24 9:02:48

一、JDBC 优化及工具类封装

1.1 现有问题

1.2 JDBC 工具类封装 V1.0

resources/db.properties配置文件:

driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql:///atguigu
username=root
password=123456
initialSize=10
maxActive=20

工具类代码:

package com.atguigu.advanced.senior.util;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

/**
 * JDBC工具类(V1.0)
 *      1.维护一个连接池对象
 *      2.对外提供在连接池中获取连接的方法
 *      3.对外提供回收连接的方法
 *    【注意】:工具类仅对外提供共性的功能代码,所以方法均为静态方法!
 */
public class JDBCUtil {

    //创建连接池引用,因为要提供给当前项目的全局使用,所以创建为静态的
    private static DataSource dataSource;

    //在项目启动时,即创建连接池对象,赋值给 dataSource
    static {
        try {
            Properties properties = new Properties();
            InputStream inputStream = JDBCUtil.class.getClassLoader().getResourceAsStream("db.properties");

            properties.load(inputStream);
            dataSource = DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    //对外提供在连接池中获取连接的方法
    public static Connection getConnection(){
        try {
            return dataSource.getConnection();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    //对外提供回收连接的方法
    public static void release(Connection connection){
        try {
            connection.close();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
}

测试代码:

package com.atguigu.advanced.senior;

import com.atguigu.advanced.senior.util.JDBCUtil;
import org.junit.Test;

import java.sql.Connection;

public class JDBCUtilTest {

    @Test
    public void testGetConnection() {
        Connection connection = JDBCUtil.getConnection();
        System.out.println(connection);

        //CRUD

        JDBCUtil.release(connection);
    }
}

1.3 ThreadLocal (本地线程)

问题:

同一用户线程多次操作获取了多个连接,造成连接资源的浪费

怎么取?

怎么存?

怎么移除?

  • 在进行对象跨层传递的时候,使用ThreadLocal可以避免多次传递,打破层次间的约束
  • 线程间数据隔离
  • 进行事务操作,用于存储线程事务信息
  • 数据库连接, Session 会话管理

 

  1. ThreadLocal对象.get:获取ThreadLocal中当前线程共享变量的值
  2. ThreadLocal对象.set:设置ThreadLocal中当前线程共享变量的值
  3. ThreadLocal对象.remove:移除ThreadLocal中当前线程共享变量的值。

1.4 JDBC 工具类封装 V2.0

package com.atguigu.advanced.senior.util;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

/**
 * JDBC工具类(V2.0)
 *      1.维护一个连接池对象,维护了一个线程绑定变量的ThreadLocal对象
 *      2.对外提供在ThreadLocal中获取连接的方法
 *      3.对外提供回收连接的方法,回收过程中,将要回收的连接从ThreadLocal中移除!
 *    【注意】:工具类仅对外提供共性的功能代码,所以方法均为静态方法!
 *    【注意】:使用ThreadLocal就是为了一个线程在多次数据库操作过程中,使用的是同一个连接!
 */
public class JDBCUtilV2 {
    //创建连接池引用,因为要提供给当前项目的全局使用,所以创建为静态的
    private static DataSource dataSource;

    private static ThreadLocal<Connection> threadLocal = new ThreadLocal<>();

    //在项目启动时,即创建连接池对象,赋值给 dataSource
    static {
        try {
            Properties properties = new Properties();
            InputStream inputStream = JDBCUtil.class.getClassLoader().getResourceAsStream("db.properties");

            properties.load(inputStream);
            dataSource = DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    //对外提供在连接池中获取连接的方法
    public static Connection getConnection(){
        try {
            //在ThreadLocal中获取Connection
            Connection connection = threadLocal.get();
            //threadLoacl里没有存储Connection,也就是第一次获取
            if(connection == null){
                connection = dataSource.getConnection();
                threadLocal.set(connection);
            }
            return connection;
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    //对外提供回收连接的方法
    public static void release(Connection connection){
        try {
            connection = threadLocal.get();
            if (connection != null){
                //从threadLocal中移除当前已经存储的Connection对象
                threadLocal.remove();
                //将Connection对象归还给连接池
                connection.close();
            }
            connection.close();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

}

测试代码

@Test
    public void testJDBCV2(){
        /*
        JDBCUtil 获取连接
         */
        Connection connection1 = JDBCUtil.getConnection();
        Connection connection2 = JDBCUtil.getConnection();
        Connection connection3 = JDBCUtil.getConnection();

        System.out.println(connection1);
        System.out.println(connection1);
        System.out.println(connection1);

        System.out.println("================================");

        /*
        JDBCUtilV2 获取连接
         */
        Connection connectionA = JDBCUtilV2.getConnection();
        Connection connectionB = JDBCUtilV2.getConnection();
        Connection connectionC = JDBCUtilV2.getConnection();

        System.out.println(connectionA);
        System.out.println(connectionB);
        System.out.println(connectionC);

    }

二、DAO封装及BaseDAO 工具类

2.1 DAO 概念

1、DAO:Data Access Object,数据访问对象。

2、Java 是面向对象语言,数据在 Java 中通常以对象的形式存在。一张表对应一个实体类,一张表的操作对应一个 DAO 对象。

3、在 Java 操作数据库时,我们会将对同一张表的增删改查操作统一维护起来,维护的这个类就是 DAO 层。

4、DAO 层只关注对数据库的操作,供业务层 Service 调用,将职责划分清楚!

EmployeeDao.java

package com.atguigu.advanced.senior.dao;

import com.atguigu.advanced.senior.pojo.Employee;

import java.util.List;

/**
 * EmployeeDao 这个类对应的是 t_emp 这张表的增删改查的操作
 */
public interface EmployeeDao {

    /**
     * 数据库对应的查询所有的操作
     * @return 表中所有的数据
     */
    List<Employee> selectAll();

    /**
     * 数据库对应的根据empId查询单个员工数据操作
     * @param empId
     * @return 一个员工对象(一行数据)
     */
    Employee selectByEmpId(Integer empId);

    /**
     * 数据库对应的新增一条员工数据
     * @param employee ORM思想中的一个员工对象
     * @return 受影响的行数
     */
    int insert(Employee employee);

    /**
     * 数据库对应的修改一条员工数据
     * @param employee ORM思想中的一个员工对象
     * @return 受影响的行数
     */
    int update(Employee employee);

    /**
     * 数据库对应的根据empId删除一条员工数据
     * @param empId 主键列
     * @return 受影响的行数
     */
    int delete(Integer empId);
}

EmployeeDaoImpl.java

package com.atguigu.advanced.senior.dao.impl;

import com.atguigu.advanced.senior.dao.EmployeeDao;
import com.atguigu.advanced.senior.pojo.Employee;

import java.util.List;

public class EmployeeDaoImpl implements EmployeeDao {
    @Override
    public List<Employee> selectAll() {
        //1.注册驱动

        //2.获取连接

        //3.预编译SQL语句

        //4.为占位符赋值,执行SQL,接受返回结果

        //5.处理结果

        //6.释放资源

        return null;
    }

    @Override
    public Employee selectByEmpId(Integer empId) {
        return null;
    }

    @Override
    public int insert(Employee employee) {
        return 0;
    }

    @Override
    public int update(Employee employee) {
        return 0;
    }

    @Override
    public int delete(Integer empId) {
        return 0;
    }
}

2.2 BaseDAO 概念

基本上每一个数据表都应该有一个对应的 DAO 接口及其实现类,发现对所有表的操作(增、删、改、查)代码重复度很高,所以可以抽取公共代码,给这些 DAO 的实现类可以抽取一个公共的父类,复用增删改查的基本操作,我们称为 BaseDAO。

2.3 BaseDAO 搭建

2.4 BaseDAO 的应用

三、事务

3.1 事务回顾

3.2 JDBC 中事务实现

3.3 JDBC 事务代码实现

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

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

相关文章

代码随想录算法训练营第二十八天|93.复原IP地址 ,78.子集 ,90.子集II

93. 复原 IP 地址 - 力扣&#xff08;LeetCode&#xff09; class Solution {ArrayList<String> results new ArrayList<>();public List<String> restoreIpAddresses(String s) {if(s.length() > 12){return new ArrayList<>();}char[] ipChars …

f4pga环境搭建教程

f4pga环境搭建教程 背景介绍 FOSS Flows For FPGA (F4PGA) project&#xff0c;是一套开源的FPGA工具链&#xff0c;号称the GCC of FPGAs&#xff0c;作用是将写的硬件描述语言&#xff08;verilog或VHDL&#xff09;转化为可以在FPGA上运行的可执行文件&#xff08;bit文件…

Python实现PPT表格的编写包含新建修改插图(收藏备用)

自动创建一个ppt文件并创建好表格 代码要用到pptx库 pip install python-pptx 创建含有表格的ppt文件代码&#xff1a; from pptx import Presentation from pptx.util import Inches# 创建一个PPT对象 ppt Presentation()# 添加一个幻灯片 slide ppt.slides.add_slide(p…

原美团项目管理专业通道执行主席边国华受邀为第十三届中国PMO大会演讲嘉宾

全国PMO专业人士年度盛会 峰项标&#xff08;北京&#xff09;管理咨询有限公司常务副总裁、原美团项目管理专业通道执行主席边国华先生受邀为PMO评论主办的2024第十三届中国PMO大会演讲嘉宾&#xff0c;演讲议题为“从组织级项目管理能力的评价角度看企业实践”。大会将于6月2…

Python读取字节数组

读取和处理bytearray中的值 # 输出&#xff1a;Combined 16-bit value: 1234 python-can发送和接收CAN报文 import can # 创建一个CAN总线对象&#xff08;这取决于你的硬件和驱动程序&#xff09; bus can.interface.Bus(channelcan0, bustypesocketcan) # 定义一个CAN…

django 内置 JSON 字段 使用场景

Django 内置的 JSON 字段&#xff08;JSONField&#xff09;是在 Django 3.1 版本中引入的&#xff0c;用于处理 JSON 格式的数据。JSONField 允许在数据库表中存储和查询 JSON 数据&#xff0c;并且在与 Python 代码交互时自动转换为合适的 Python 数据类型。以下是一些常见的…

成都欣丰洪泰文化传媒有限公司好不好?

在数字经济的浪潮中&#xff0c;电商行业以其独特的魅力和无限的发展潜力&#xff0c;吸引了越来越多的企业和个人投身其中。作为电商服务领域的佼佼者&#xff0c;成都欣丰洪泰文化传媒有限公司凭借专业的团队、优质的服务和创新的理念&#xff0c;不断引领电商新风尚&#xf…

INT202 例题

算法复杂度 O(n)&#xff1a;表示算法的渐进上界。如果一个算法的运行时间是O(n)&#xff0c;那么它的运行时间最多与输入规模n成正比。换句话说&#xff0c;当输入规模n增加时&#xff0c;算法的运行时间不会超过某个常数倍的n。比如&#xff0c;如果一个算法的时间复杂度是O(…

AndroidStudio使用高德地图API获取手机定位

一、高德地图API申请 首先去高德注册开发者账号 下面这两个选项&#xff0c;也是我们项目成功的关键 1.1怎么获取SHA1指纹密码 ①使用AS自带的签名文件 你的用户文件下面会有一个.android文件夹,进入文件夹,在这个路径下打开cmd 如果.android下面没有签名文件参考创建文章 …

【管理咨询宝藏124】通过BLM打通前端业务与财务的双轨制设计方案

本报告首发于公号“管理咨询宝藏”&#xff0c;如需阅读完整版报告内容&#xff0c;请查阅公号“管理咨询宝藏”。 【管理咨询宝藏124】通过BLM打通前端业务与财务的双轨制设计方案 【格式】PDF版本 【关键词】BLM、组织架构设计、流程优化 【核心观点】 - 运用“拉通业务财务…

【原创】springboot+mysql大学生综合素质测评管理系统设计与实现

个人主页&#xff1a;程序猿小小杨 个人简介&#xff1a;从事开发多年&#xff0c;Java、Php、Python、前端开发均有涉猎 博客内容&#xff1a;Java项目实战、项目演示、技术分享 文末有作者名片&#xff0c;希望和大家一起共同进步&#xff0c;你只管努力&#xff0c;剩下的交…

【python】成功解决“ValueError: Expected 2D array, got 1D array instead”错误的全面指南

成功解决“ValueError: Expected 2D array, got 1D array instead”错误的全面指南 一、引言 在Python的数据分析和机器学习领域&#xff0c;尤其是使用NumPy、Pandas、scikit-learn等库时&#xff0c;经常会遇到各种类型错误。其中&#xff0c;“ValueError: Expected 2D arr…

MP-SPDZ的学习与运用

目录 MP-SPDZ 的介绍主要功能典型应用场景 MP-SPDZ 的安装实验环境准备环境安装MP-SPDZ 下载和编译 MP-SPDZ 的使用测试程序第三方求和三方计算测试冒泡排序比较运算函数语法详解——Sint语法详解——Array基于AES电路实现OPRFORAM隐私集合求交实现两台虚拟机之间进行MPC简单实…

视觉SLAM十四讲:从理论到实践(Chapter8:视觉里程计2)

前言 学习笔记&#xff0c;仅供学习&#xff0c;不做商用&#xff0c;如有侵权&#xff0c;联系我删除即可 一、目标 1.理解光流法跟踪特征点的原理。 2.理解直接法是如何估计相机位姿的。 3.实现多层直接法的计算。 特征点法存在缺陷&#xff1a; 二、光流(Optical Flow) …

SEO之关键词扩展(二)

初创企业搭建网站的朋友看1号文章&#xff1b;想学习云计算&#xff0c;怎么入门看2号文章谢谢支持&#xff1a; 1、我给不会敲代码又想搭建网站的人建议 2、新手上云 &#xff08;接上一篇。。。&#xff09; 5、各种形式的变体 1.同义词 假设核心关键词是酒店&#xff0c;…

Python版《消消乐》,附源码

曾经风靡一时的消消乐&#xff0c;至今坐在地铁上都可以看到很多人依然在玩&#xff0c;想当年我也是大军中的一员&#xff0c;那家伙&#xff0c;吃饭都在玩&#xff0c;进入到高级的那种胜利感还是很爽的&#xff0c;连续消&#xff0c;无限消&#xff0c;哈哈&#xff0c;现…

Kotlin中的StateFlow和SharedFlow有什么区别?

本文首发于公众号“AntDream”&#xff0c;欢迎微信搜索“AntDream”或扫描文章底部二维码关注&#xff0c;和我一起每天进步一点点 在Kotlin的协程库kotlinx.coroutines中&#xff0c;StateFlow和SharedFlow是两种用于处理事件流的API&#xff0c;它们有相似之处&#xff0c;但…

MySQL中获取时间的方法

大家好&#xff0c;在MySQL数据库开发中&#xff0c;获取时间是一个常见的需求。MySQL提供了多种方法来获取当前日期、时间和时间戳&#xff0c;并且可以对时间进行格式化、计算和转换。 以下是一些常用的MySQL时间函数及其示例&#xff1a; 1、NOW()&#xff1a;用于获取当前…

GPT-4与GPT-4O的区别详解:面向小白用户

1. 模型介绍 在人工智能的语言模型领域&#xff0c;OpenAI的GPT-4和GPT-4O是最新的成员。这两个模型虽然来源于相同的基础技术&#xff0c;但在功能和应用上有着明显的区别。 GPT-4&#xff1a;这是一个通用型语言模型&#xff0c;可以理解和生成自然语言。无论是写作、对话还…

MySQL 关键特性一:插入缓冲、双写缓冲

前言 ​ 本文主要介绍 mysql 的几大特性之几&#xff0c;如&#xff1a;双写缓冲和插入缓存。 双写缓冲 基本概念 ​ 双写缓冲&#xff08;doublewrite buffer&#xff09;是MySQL/InnoDB中用于支持原子页面更新的一种机制。在传统的数据库系统中&#xff0c;为了保证数据的…