SpringBoot中封装jdbc工具类

2023-05-16

背景

现在的数据层的开发,大多会使用如MyBatis或JPA之类的开发工具。这些开发工具给我们的开发过程中带来了极大的便利。
但是在一些极端的场景下往往原生的jdbc方式操作数据库更灵活,性能更高。由于部分场景下MyBatis或JPA之类无法满足我的需求,所以我打算自己封装一套查数据库的工具类。

具体实现

pom.xml

我们会用到fastjson,druid,mysql所以pom.xml增加依赖如下:

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.62</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.9</version>
</dependency>
<!-- Mysql驱动包 -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

cn/ycmit/jdbcutil/util/JdbcUtil.java

以下是核心代码部分

package cn.ycmit.jdbcutil.util;

import cn.ycmit.jdbcutil.domain.DataSource;
import cn.ycmit.jdbcutil.dto.ResponseDto;
import com.alibaba.druid.pool.DruidPooledConnection;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

@Slf4j
public class JdbcUtil {
    /**
     * 执行sql并返回结果
     *
     * @param datasource      数据源连接
     * @param sql             语句
     */
    public static ResponseDto executeSql(DataSource datasource, String sql) {
        return executeSql(datasource,sql,new ArrayList<Object>());
    }

    /**
     * 执行sql并返回结果
     *
     * @param datasource      数据源连接
     * @param sql             语句
     * @param jdbcParamValues
     */
    public static ResponseDto executeSql(DataSource datasource, String sql, List<Object> jdbcParamValues) {
        log.debug(sql);
        log.debug(JSON.toJSONString(jdbcParamValues));
        DruidPooledConnection connection = null;
        try {
            connection = PoolManager.getPooledConnection(datasource);
            PreparedStatement statement = connection.prepareStatement(sql);
            for (int i = 1; i <= jdbcParamValues.size(); i++) {
                statement.setObject(i, jdbcParamValues.get(i - 1));
            }
            boolean hasResultSet = statement.execute();
            if (hasResultSet) {
                ResultSet rs = statement.getResultSet();
                int columnCount = rs.getMetaData().getColumnCount();
                List<String> columns = new ArrayList<>();
                for (int i = 1; i <= columnCount; i++) {
                    String columnName = rs.getMetaData().getColumnLabel(i);
                    columns.add(columnName);
                }
                List<JSONObject> list = new ArrayList<>();
                while (rs.next()) {
                    JSONObject jo = new JSONObject();
                    columns.stream().forEach(t -> {
                        try {
                            Object value = rs.getObject(t);
                            jo.put(t, value);

                        } catch (SQLException e) {
                            e.printStackTrace();
                        }
                    });
                    list.add(jo);
                }
                return ResponseDto.apiSuccess(list);
            } else {
                int updateCount = statement.getUpdateCount();
                return ResponseDto.apiSuccess("sql修改数据行数:" + updateCount);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseDto.fail(e.getMessage());
        } finally {
            try {
                if (connection != null) {
                    connection.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

PoolManager

jdbcutil/src/main/java/cn/ycmit/jdbcutil/util/PoolManager.java
代码如下:

package cn.ycmit.jdbcutil.util;

import cn.ycmit.jdbcutil.domain.DataSource;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidPooledConnection;
import lombok.extern.slf4j.Slf4j;

import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


/**
 * 数据库连接池工具类
 */
@Slf4j
public class PoolManager {

    private static Lock lock = new ReentrantLock();

    private static Lock deleteLock = new ReentrantLock();

    //所有数据源的连接池存在map里
    static Map<String, DruidDataSource> map = new HashMap<>();

    public static DruidDataSource getJdbcConnectionPool(DataSource ds) {
        if (map.containsKey(ds.getId())) {
            return map.get(ds.getId());
        } else {
            lock.lock();
            try {
                log.info(Thread.currentThread().getName() + "获取锁");
                if (!map.containsKey(ds.getId())) {
                    DruidDataSource druidDataSource = new DruidDataSource();
                    druidDataSource.setName(ds.getName());
                    druidDataSource.setUrl(ds.getUrl());
                    druidDataSource.setUsername(ds.getUsername());
                    druidDataSource.setPassword(ds.getPassword());
                    druidDataSource.setDriverClassName(ds.getDriver());
                    druidDataSource.setConnectionErrorRetryAttempts(3);       //失败后重连次数
                    druidDataSource.setBreakAfterAcquireFailure(true);

                    map.put(ds.getId(), druidDataSource);
                    log.info("创建Druid连接池成功:{}", ds.getName());
                }
                return map.get(ds.getId());
            } catch (Exception e) {
                return null;
            } finally {
                lock.unlock();
            }
        }
    }

    //删除数据库连接池
    public static void removeJdbcConnectionPool(String id) {
        deleteLock.lock();
        try {
            DruidDataSource druidDataSource = map.get(id);
            if (druidDataSource != null) {
                druidDataSource.close();
                map.remove(id);
            }
        } catch (Exception e) {
            log.error(e.toString());
        } finally {
            deleteLock.unlock();
        }

    }

    public static DruidPooledConnection getPooledConnection(DataSource ds) throws SQLException {
        DruidDataSource pool = PoolManager.getJdbcConnectionPool(ds);
        DruidPooledConnection connection = pool.getConnection();
//        log.info("获取连接成功");
        return connection;
    }
}

ResponseDto

jdbcutil/src/main/java/cn/ycmit/jdbcutil/dto/ResponseDto.java
代码如下:

package cn.ycmit.jdbcutil.dto;

import lombok.Data;
/**
 * 返回值包装类
 */
@Data
public class ResponseDto {
    String msg;
    Object data;
    boolean success;
    public static ResponseDto apiSuccess(Object data) {
        ResponseDto dto = new ResponseDto();
        dto.setData(data);
        dto.setSuccess(true);
        dto.setMsg("接口访问成功");
        return dto;
    }

    public static ResponseDto successWithMsg(String msg) {
        ResponseDto dto = new ResponseDto();
        dto.setData(null);
        dto.setSuccess(true);
        dto.setMsg(msg);
        return dto;
    }

    public static ResponseDto successWithData(Object data) {
        ResponseDto dto = new ResponseDto();
        dto.setData(data);
        dto.setSuccess(true);
        return dto;
    }

    public static ResponseDto fail(String msg) {
        ResponseDto dto = new ResponseDto();
        dto.setSuccess(false);
        dto.setMsg(msg);
        return dto;
    }
}

DataSource.java

jdbcutil/src/main/java/cn/ycmit/jdbcutil/domain/DataSource.java
代码如下:

package cn.ycmit.jdbcutil.domain;

import lombok.Data;

/**
 * 数据源实体类
 *
 */
@Data
public class DataSource {
    String id;
    String name;
    String url;
    String username;
    String password;
    String driver;
}

JdbcDemoController

jdbcutil/src/main/java/cn/ycmit/jdbcutil/controller/JdbcDemoController.java

package cn.ycmit.jdbcutil.controller;

import cn.ycmit.jdbcutil.domain.DataSource;
import cn.ycmit.jdbcutil.dto.ResponseDto;
import cn.ycmit.jdbcutil.util.JdbcUtil;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

@RestController
public class JdbcDemoController {
    public static DataSource ds = new DataSource();
    static {
        //配置数据源
        ds.setId("1");
        ds.setName("mysql");
        ds.setUrl("jdbc:mysql://172.16.184.23:3307/dbapi?useSSL=false&characterEncoding=UTF-8&serverTimezone=GMT%2B8");
        ds.setUsername("root");
        ds.setPassword("itkey123456");
        ds.setDriver("com.mysql.cj.jdbc.Driver");
    }

    /**
     * 查询测试
     * @return
     */
    @RequestMapping("/api/list")
    public ResponseDto queryList()
    {
        String sql = "show tables";
        ResponseDto responseDto = JdbcUtil.executeSql(ds,sql);
        return responseDto;
    }
}

效果测试

在这里插入图片描述

源码下载

https://download.csdn.net/download/lxyoucan/85094574

参考

https://github.com/freakchick/DBApi

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SpringBoot中封装jdbc工具类 的相关文章

  • Android Emulator安卓模拟器去黑边

    安卓模拟器默认会有一个黑边 xff0c 让它看起来像个手机 但是看久了总感觉太占地方了 去掉黑边 重启完成以后 xff0c 效果如下 xff1a
  • 【视频】iOS开发允许http请求

    APP开发中有时会对接一些比较老的项目 xff0c 老的项目还有一些在使用http的 iOS应用默认情况下不允许请求http xff0c 怎么能让其允许呢 xff1f 视频讲解 https www bilibili com video BV
  • The run destination iPhone 13 is not valid for Running the scheme

    报错信息 The run destination iPhone 13 is not valid for Running the scheme apexedu 原因分析 后来我发现我的项目中的TARGETS中少了一个项目 xff0c 不清楚是
  • xcode Archive菜单是灰色的解决办法

    想把iOS应用打包上传到App Store发现这个菜单是灰色的 原因 后来发现 xff0c 因为我当前的运行环境是iOS模拟器 解决办法 运行设备修改成Any iOS Device arm64 xff0c 菜单就可以正常使用了 参考 htt
  • iterm2(zsh)粘贴慢解决办法

    我在macOS环境中使用的是iterm2终端 xff0c 每次在粘贴大量命令的时间 xff0c 明显感觉粘贴速度慢 就感觉粘贴也是一个字一个字粘贴的 在命令过长时由为明显 本以为是iterm2的原因 xff0c 后来发现原来是因为zsh的原
  • MAME打开ROM报错解决办法

    问 olds100 34 西游释厄传 特别版 版本 100 第 1 套 34 运行报错如何解决 xff1f 答 经过我的研究olds100 zip这个游戏是一个特别版本 它依赖两个文件才可以正常运行 分别是 xff1a olds zip x
  • 【新建Spring Boot项目】Connect to 127.0.0.1:1087 [/127.0.0.1] failed: Connection refused

    背景 我在新建微服务项目的时候 xff0c 使用gradle报错Connect to 127 0 0 1 1087 127 0 0 1 failed Connection refused 然后我检查了一下IDEA的代理设置 xff0c 没有
  • 命令行搜索神器fzf

    文件搜索神器fzf xff0c 名气很大 xff0c 很快 xff0c 很强大 fzf 是一个通用的命令行模糊查找器 它是一个交互式 Unix 命令行过滤器 xff0c 可用于任何列表 xff1b 文件 命令历史 进程 主机名 书签 git
  • docker中搭建nacos集群笔记

    最近在学习nacos xff0c 在本地搭建nacos集群环境 因为电脑配置低 xff0c 所以没有使用vmware虚拟机 xff0c 而是用docker中搭建的 仅是简单的笔记供自己复习查看 nacos相关配置 数据源配置 vim con
  • nginx: [emerg] could not build server_names_hash

    报错信息 nginx emerg could not build server names hash you should increase server names hash bucket size 32 nginx configurat
  • Netty核心源码分析(二),Netty的Server端接收请求过程源码分析

    文章目录 系列文章目录一 连接请求接受过程源码分析1 事件的值2 processSelectedKeys获取事件 xff08 1 xff09 doReadMessages方法 xff08 2 xff09 pipeline的fireChann
  • HAProxy学习笔记

    最近在学习微服务架构 xff0c 里面有用到HAProxy xff0c 记录一下学习笔记 官方网站是 xff1a https www haproxy org 下载安装 推荐使用源码安装 xff0c 因为我用的ubuntu 20 04中本身自
  • 如果在ubuntu上安装mysql client

    ubuntu安装mysql客户端 MySQL 是流行的开源关系数据库管理系统 与服务器交互的程序称为 MySQL 客户端 您可以使用的最基本的客户端是命令行工具 xff0c 通常称为 MySQL 客户端 要在 Ubuntu 20 04 上安
  • neovim内置lsp实现Java语言补全

    文章目录 通用方式自动化配置Java LSP手动配置JDK版本选择配置解压jdt language server配置环境变量 我的配置分享 neovim使用nvim jdtls搭建Java IDE 通用方式自动化配置Java LSP 可以使
  • neovim使用nvim-jdtls搭建Java IDE

    nvim jdtls简介 Neovim for eclipse jdt ls 中内置 LSP 支持的扩展 Neovim gt 61 0 6 0 中对eclipse jdt ls的内置语言服务器协议支持的扩展 该项目遵循KISS 原则 xff
  • 【视频】零基础neovim搭建Java IDE

    文章目录 视频教程系统环境准备工作文件下载安装neovim 0 6以上版本 下载解压jdt language server安装JDK11安装curl git neovim配置插件安装配置nvim cmp配置LuaSnip配置nvim jdt
  • React Native Webview安全问题解决办法

    威胁描述 威胁描述 根据CVE披露的WebView远程代码执行漏洞信息 xff08 CVE 2012 663 CVE 2014 7224 xff09 xff0c Android系统中存在一共三个有远程代码执行漏洞的隐藏接口 分别是位于and
  • Linux sed命令使用笔记

    sed 通常用于过滤文本 xff0c 即它接受文本输入 xff0c 对其执行一些操作 xff08 或一组操作 xff09 xff0c 然后输出修改后的文本 sed 通常用于使用模式匹配或替换文件中多次出现的字符串来提取文件的一部分 Linu
  • vim代码运行插件vim-quickrun

    插件安装 这里以packer为例 packer插件管理器安装方法 修改 config nvim lua plugins lua文件 xff0c 并增加如下内容 xff1a span class token comment 彩虹括号 span
  • 【视频】RuoYi开发实战-搭建开发环境

    文章目录 简介B站视频特点RuoYi VueRuoYi环境准备JDK安装dockermysql安装redis 6 2安装 下载源码数据库初始化Redis配置数据源配置Logback报错解决测试后端是否启动成功前端运行 简介 RuoYi 使用

随机推荐

  • macOS 安装mysql client命令行工具

    下载MySQL Workbench MySQL Community Downloads https dev mysql com downloads workbench 安装 设置环境变量 编辑 zshrc 增加以下内容 xff1a span
  • Netty核心源码分析(三)业务请求执行关键——ChannelPipeline、ChannelHandler、ChannelHandlerContext源码分析

    文章目录 系列文章目录一 ChannelPipeline ChannelHandler ChannelHandlerContext1 三者关系 二 ChannelPipeline源码分析1 ChannelPipeline接口设计2 Chan
  • alpine linux中安装docker

    简介 Small Simple Secure Alpine Linux is a security oriented lightweight Linux distribution based on musl libc and busybox
  • 命令行mysql 中文乱码解决

    现象 在IDEA中查询 xff0c 中文显示正常 IDEA中的jdbc连接字符串是 xff1a jdbc mysql 172 16 184 13 3306 ry vue useUnicode span class token operato
  • alpine linux中docker mysql踩坑记录

    写在前头 xff0c 本文只是记录这个坑 xff0c 目前没有找到解决办法 研究了一天了 xff0c 也没有解决 环境 我使用vmware安装了alpine linux 安装过程见 xff1a vmware安装alpine linux ht
  • [精简]RuoYi开发实战-搭建开发环境

    文章目录 简介说明RuoYi环境准备JDK安装dockermysql安装redis 6 2安装 下载源码数据库初始化Redis配置数据源配置Logback报错解决测试后端是否启动成功前端运行 简介 RuoYi 使用若依快速构建web应用程序
  • CentOS Stream8 与CentOS7有什么区别?

    工作中一直在用CentOS7和CentOS6 本来想抽空尝试一下CentOS8玩一玩 结果CentOS8已经走完了生命周期 一直好奇Centos Linux 和 CentOS Stream有什么区别 xff0c 今天就来安装一下 CentO
  • RuoYi若依实战-代码生成

    代码生成 使用admin登录管理后台 xff0c 菜单路径如下 xff1a 首页 系统工具 代码生成 建表 span class token comment auto generated definition span span class
  • CentOS stream 8同步时间

    虚拟机中的CentOS stream8挂起以后 xff0c 重新打开系统时间依然是之前的时间 会导致一些操作无效了 CentOS7中可以使用ntpdate同步时间 xff0c 在CentOS stream 8中发现已经无法成功安装此软件了
  • RuoYi开发实战- PostMan请求接口

    最近在学习若依这个开源项目 xff0c 在调试接口时遇到一个小坎 默认的情况下接口是无法直接请求的 xff0c 请求会报以下的错误 xff1a span class token punctuation span span class tok
  • RuoYi若依代码生成+一键部署

    若依代码生成器很强大的 xff0c 可以让我们写增删改查的效率大增 但是我在用的过程中总感觉还不够爽快 我想根据自己的想法改造一下 若依代码生成的基本操作如下 xff1a https www bilibili com video BV1ba
  • 若依yml配置文件读取方法学习

    SpringBoot的yml配置用了好多年了 xff0c 若依的方式让我眼前一亮 这些做确实挺好用的 generator yml RuoYi Vue ruoyi generator src main resources generator
  • Netty核心源码分析(四)心跳检测源码分析

    文章目录 系列文章目录一 心跳检测案例二 源码分析1 Netty心跳的三个Handler2 IdleStateHandler源码 xff08 1 xff09 四个关键属性 xff08 2 xff09 handlerAdded方法 xff08
  • mybatis执行sql脚本

    最近在学习若依这个开源项目 xff1a https gitee com y project RuoYi Vue 默认的代码生成模块用起来总感觉别扭 xff0c 比如说 xff0c 每次生成的代码还要单独的手动执行一下SQL语句 我就在想能不
  • 解决@Autowired IDEA编译Could not autowire. No beans of ‘xxxx‘ type found.

    现象 最近在学习若依开发框架 xff0c 发现若依的一些代码在IDEA中有报错显示 xff0c 但是实际上是可以正常编译的 虽然不影响实际开发 xff0c 对于强迫证程序员来说看到这两个erro真的难受 原因分析 IDEA 可以理解 Spr
  • 若依框架登录去除验证码

    若依框架自带的登录功能还是挺好用的 但是在开发过程中经过因在编写代码或者编写设计文档登录会话到期重新登录 重新登录就会出现验证码 xff0c 一天如果要输入10次验证码也会浪费不少时间 验证码这个功能在生产环境非常有必要 xff0c 但是在
  • IDEA若依框架新建模块

    创建新的module 项目上鼠标右键 选择Maven项目 Parent选ruoyi 点击Finish 编辑RuoYi Vue Wisdom ruoyi wisdom pom xml 在 lt artifactId gt ruoyi wisd
  • SpringBoot拦截指定路径统一处理

    最近在做一个有趣的项目 xff0c 做一个API生成小工具 可以对简单的API路径进行配置SQL自动生成API 简单来讲 xff1a URI对应sql api userselect from user api user addresssel
  • vim代码注释生成插件neogen

    更好的注释生成器 支持多种语言和注释约定 项目地址 xff1a https github com danymat neogen 注意事项 nvim版本以大于等于NVIM v0 6 1不然会有报错 插件安装 插件的运行需要依赖nvim tre
  • SpringBoot中封装jdbc工具类

    背景 现在的数据层的开发 xff0c 大多会使用如MyBatis或JPA之类的开发工具 这些开发工具给我们的开发过程中带来了极大的便利 但是在一些极端的场景下往往原生的jdbc方式操作数据库更灵活 xff0c 性能更高 由于部分场景下MyB