JDBC处理批量数据提高效率

news2024/12/24 7:35:38

文章目录

  • 0 说明
  • 1 如何使用jdbc操作数据库
    • 1.1 加载数据库驱动
    • 1.2 建立数据库连接
    • 1.3 创建Statement或者PreparedStatement用来执行SQL
    • 1.4 开始执行SQL语句
    • 1.5 处理结果集
    • 1.6 关闭连接
    • 1.7 完整代码
  • 2 批量操作数据库
  • 3 如何打印SQL语句
  • 4 jdbc常用开源类库
  • 5 获取自增id
  • 6 获取数据源信息几种方式
    • 6.1 通过@Value获取yml信息
    • 6.2 通过SqlSessionFactory获取
  • 7 结果集获取几种方式

1 JDBC实现往MySQL插入百万级数据
2 详解JDBC(Java Database connect)

0 说明

JDBCJava 数据库连接)是 Java 语言中用来连接和操作关系型数据库的 API。使用 JDBC,我们可以通过编写 Java 代码来访问各种数据库,包括 MySQLOracleSQL Server 等。
JDBC 是基于 Java 的标准接口,它提供了一组接口和类,可以让 Java 应用程序与各个数据库进行交互。JDBC 的工作原理如下:

1.、加载数据库驱动程序

在使用 JDBC 前,需要先加载相应的数据库驱动程序,不同的数据库使用的驱动程序不同。通常情况下,我们需要将驱动程序的 jar 文件添加到项目的类路径中,并在代码中使用 Class.forName() 方法来加载驱动程序。

2、连接数据库

使用 DriverManager 类来连接数据库,该类提供了一组方法来获取数据库连接。连接字符串通常由以下三部分组成:协议、主机名和数据库名称。

3、执行 SQL 语句

连接成功后,就可以通过 Connection 对象创建 Statement 或 PreparedStatement 对象,用于执行 SQL 语句。Statement 支持静态 SQL 语句,而 PreparedStatement 支持动态 SQL 语句。执行 SQL 语句后,可以通过 ResultSet 对象获取查询结果。

4.、关闭连接

完成数据库操作后,必须关闭 Connection、Statement 和 ResultSet 对象,释放资源。

1 如何使用jdbc操作数据库

1.1 加载数据库驱动

在代码中使用 Class.forName() 方法加载数据库驱动程序。


Class.forName("com.mysql.cj.jdbc.Driver");

1.2 建立数据库连接

使用 DriverManager 类的 getConnection() 方法,传入连接字符串、用户名和密码等参数来获取数据库连接。


private String url = "jdbc:mysql://localhost:3306/school";
private String user = "root";
private String password = "root";

Connection conn = DriverManager.getConnection(url, user, password);

1.3 创建Statement或者PreparedStatement用来执行SQL

使用 Connection 对象的 createStatement() 或 prepareStatement() 方法创建 Statement 或 PreparedStatement 对象,用于执行 SQL 语句。


String sql = "select * from user limit 1";
PreparedStatement preparedStatement = connection.prepareStatement(sql);

1.4 开始执行SQL语句

使用 Statement 或 PreparedStatement 对象的 executeQuery() 或 executeUpdate() 方法执行 SQL 语句,返回 ResultSet 或更新的行数。


String sql = "select * from user limit 1";
ResultSet rs = preparedStatement .executeQuery(sql);
int count = preparedStatement .executeUpdate();

1.5 处理结果集

使用 ResultSet 对象的 getXXX() 方法获取查询结果,例如 getInt()、getString() 等方法。

while (rs.next()) {
    int id = rs.getInt("id");
    String name = rs.getString("name");
    int age = rs.getInt("age");
}

1.6 关闭连接

使用 Connection、Statement 和 ResultSet 对象的 close() 方法关闭连接,释放资源。

	rs.close();
	stmt.close();
	conn.close();

1.7 完整代码

    @Test
    public void t10() {
        String url = "jdbc:mysql://localhost:3306/school";
        String user = "root";
        String password = "root";
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            log.error("error msg:【{}】", e);
            throw new IllegalArgumentException(e);
        }
        try {
            Connection conn = DriverManager.getConnection(url, user, password);
            String sql = "select * from user limit 10";
            PreparedStatement preparedStatement = conn.prepareStatement(sql);
            ResultSet resultSet = preparedStatement.executeQuery(sql);
            int id = 0;
            String userName = null, sex = null, address = null;
            java.sql.Date birthday = null;
            while (resultSet.next()) {
                id = resultSet.getInt(1);
                userName = resultSet.getString(2);
                birthday = resultSet.getDate(3);
                sex = resultSet.getString(4);
                address = resultSet.getString(5);
                log.info("结果集:id-【{}】,userName-【{}】,birthday-【{}】,sex-【{}】,address-【{}】", id, userName, birthday, sex, address);
            }
            conn.close();
            preparedStatement.close();
            resultSet.close();
        } catch (SQLException e) {
            log.error("error msg:【{}】", e);
            throw new IllegalArgumentException(e);
        }

    }

在这里插入图片描述

2 批量操作数据库

说明1:url拼接 rewriteBatchedStatements=true
说明2:事务关闭自动提交,手动提交事务

    connection.setAutoCommit(false);
    connection.commit();

说明3:executeBatch();批量执行

    String url = "jdbc:mysql://localhost:3306/school?rewriteBatchedStatements=true";
    String user = "root";
    String password = "root";
    private void jdbcSave(List<User> cachedList) {
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            connection = DriverManager.getConnection(url, user, password);
            String sql = "insert into user(user_name,birthday,sex,address) values (?,?,?,?)";
            preparedStatement = connection.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS);
            connection.setAutoCommit(false);
            for (User item : cachedList) {
                preparedStatement.setString(1, item.getUserName());
                preparedStatement.setDate(2, new Date(item.getBirthday().getTime()));
                preparedStatement.setString(3, item.getSex());
                preparedStatement.setString(4, item.getAddress());
                preparedStatement.addBatch();
            }
            preparedStatement.executeBatch();
            connection.commit();
        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        } finally {
            if (preparedStatement != null) {
                try {
                    preparedStatement.close();
                } catch (SQLException e) {
                    log.error("error msg:[{}]", e);
                    throw new RuntimeException(e);
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (SQLException e) {
                    log.error("error msg:[{}]", e);
                }
            }
        }
    }

3 如何打印SQL语句

/**
     * @param sql           原始SQL
     * @param parameterList 参数列表
     * @return              返回SQL
     * @description         jdbc打印执行SQL
     */
    private static String showFinalSql(String sql, List<Object> parameterList) {
        //1 如果没有参数,说明是不是动态SQL语句
        int paramCount = 0;
        if (CollectionUtils.isNotEmpty(parameterList)) {
            paramCount = parameterList.size();
        }
        if (paramCount < 1) {
            return sql;
        }

        //2 如果有参数,则是动态SQL语句
        StringBuilder returnSql = new StringBuilder();
        String[] subSql = sql.split("\\?");
        for (int i = 0; i < paramCount; i++) {
            Object item = parameterList.get(i);
            if (item instanceof Integer) {
                returnSql.append(subSql[i]).append(" ").append(item).append(" ");
            } else if (item instanceof Date) {
                String formatStr = DateFormatUtils.format((Date) (item), "yyyy-MM-dd HH:mm:ss");
                returnSql.append(subSql[i]).append("'").append(formatStr).append("'");
            } else {
                returnSql.append(subSql[i]).append("'").append(item).append("'");
            }
        }

        if (subSql.length > parameterList.size()) {
            returnSql.append(subSql[subSql.length - 1]);
        }
        return returnSql.toString();
    }

核心代码,打印日志使用slf4j


// 组装入参数据
List<Object> list = Arrays.asList(item.getUserName(), new java.sql.Date(item.getBirthday().getTime()), item.getSex(), item.getAddress());
// 调用自定义方法打印SQL
showFinalSql(sql,list);

private void jdbcSave(List<User> cachedList) {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        Connection connection = sqlSession.getConnection();
        PreparedStatement preparedStatement = null;
        sqlSessionFactory.getConfiguration();
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            String sql = "insert into user(user_name,birthday,sex,address) values (?,?,?,?)";
            preparedStatement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
            connection.setAutoCommit(false);
            for (User item : cachedList) {
                preparedStatement.setString(1, item.getUserName());
                preparedStatement.setDate(2, new java.sql.Date(item.getBirthday().getTime()));
                preparedStatement.setString(3, item.getSex());
                preparedStatement.setString(4, item.getAddress());
                preparedStatement.addBatch();
                List<Object> list = Arrays.asList(item.getUserName(), new java.sql.Date(item.getBirthday().getTime()), item.getSex(), item.getAddress());
                showFinalSql(sql,list);
            }
            preparedStatement.executeBatch();
            connection.commit();
        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        } finally {
            if (preparedStatement != null) {
                try {
                    preparedStatement.close();
                } catch (SQLException e) {
                    log.error("error msg:[{}]", e);
                    throw new RuntimeException(e);
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (SQLException e) {
                    log.error("error msg:[{}]", e);
                }
            }
        }

    }

在这里插入图片描述

4 jdbc常用开源类库

https://www.cnblogs.com/fnz0/p/5858546.html

5 获取自增id

在这里插入图片描述

 //Statement.RETURN_GENERATED_KEYS:获取自动增加的id号
// 数据库表设置自增,整形
private void jdbcSave(List<User> cachedList) {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        Connection connection = sqlSession.getConnection();
        PreparedStatement preparedStatement = null;
        sqlSessionFactory.getConfiguration();
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            // connection = DriverManager.getConnection(url, user, password);
            String sql = "insert into user(user_name,birthday,sex,address) values (?,?,?,?)";
            // List<String> strs = objs.stream().map(obj-> (String) obj).collect(Collectors.toList());
            // getPreparedSQL(sql,(List<Object>) cachedList);
            preparedStatement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
            connection.setAutoCommit(false);
            for (User item : cachedList) {
                preparedStatement.setString(1, item.getUserName());
                preparedStatement.setDate(2, new java.sql.Date(item.getBirthday().getTime()));
                preparedStatement.setString(3, item.getSex());
                preparedStatement.setString(4, item.getAddress());
                preparedStatement.addBatch();
                List<Object> list = Arrays.asList(item.getUserName(), new java.sql.Date(item.getBirthday().getTime()), item.getSex(), item.getAddress());
                showFinalSql(sql,list);
            }
            preparedStatement.executeBatch();
            log.info("结果集SQL打印1:【{}】",preparedStatement.toString());
            connection.commit();
        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        } finally {
            if (preparedStatement != null) {
                try {
                    preparedStatement.close();
                } catch (SQLException e) {
                    log.error("error msg:[{}]", e);
                    throw new RuntimeException(e);
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (SQLException e) {
                    log.error("error msg:[{}]", e);
                }
            }
        }
    }

6 获取数据源信息几种方式

6.1 通过@Value获取yml信息

注意:需要在spring环境下才可以使用@Value,否则沟通构造方法传入参数

     @Value("${spring.datasource.url}")
     private String url;

     @Value("${spring.datasource.username}")
     private String user;

     @Value("${spring.datasource.password}")
     private String password;

6.2 通过SqlSessionFactory获取

    @Autowired
    private SqlSessionFactory sqlSessionFactory;

    核心代码
     SqlSession sqlSession = sqlSessionFactory.openSession();
     Connection connection = sqlSession.getConnection();

在这里插入图片描述

7 结果集获取几种方式

根据索引位置获取字段信息

  String sql = "select id,name,age,email from gk_user limit 1";
  while (resultSet.next()) {
                id = resultSet.getInt(1);
                name = resultSet.getString(2);
                age = resultSet.getInt(3);
                email = resultSet.getString(4);
            }
  log.info("打印结果集:[id:{},name:{},age:{},email:{}]", id, name, age, email);

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

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

相关文章

【CSS】网格布局(简单布局、网格合并、网格嵌套)

文章目录 CSS网格布局&#xff08;Grid Layout&#xff09;1. 简单布局2. 网格合并3. 网格嵌套4. 总结 CSS网格布局&#xff08;Grid Layout&#xff09; CSS网格布局&#xff08;Grid Layout&#xff09;是一种强大且灵活的CSS布局系统&#xff0c;允许开发者以网格形式组织和…

快乐的马里奥(广搜入门)

题面 题目描述 马里奥是一个快乐的油漆工人&#xff0c;这天他接到了一个油漆任务&#xff0c;要求马里奥把一个 n 行 m 列的矩阵每一格都用油漆标记一个数字&#xff0c;标记的顺序按照广度优先搜索的方式进行&#xff0c;也就是他会按照如下方式标记&#xff1a; 1、首先标记…

基于springboot+vue的房屋租赁系统(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战 主要内容&#xff1a;毕业设计(Javaweb项目|小程序等)、简历模板、学习资料、面试题库、技术咨询 文末联系获取 项目介绍…

云原生之使用Docker部署homarr个人导航页

云原生之使用Docker部署homarr个人导航页 一、homarr介绍1.1 homarr简介1.2 homer特点 二、本地环境介绍2.1 本地环境规划2.2 本次实践介绍 三、本地环境检查3.1 检查Docker服务状态3.2 检查Docker版本3.3 检查docker compose 版本 四、下载homarr镜像五、部署homarr导航页5.1 …

彩虹云商城搭建完整教程 完整的学习资料

彩虹云商城搭建完整教程 完整的学习资料提供给大家学习 随着电子商务的快速发展&#xff0c;越来越多的企业开始意识到开设一个自己的电子商城对于销售和品牌推广的重要性。然而&#xff0c;选择一家合适的网站搭建平台和正确地构建一个商城网站并不是一件容易的事情。本文将为…

塔矢行洋对战藤原佐为,谁才是最接近神之一手的人

大家好, 我是嘉宾, 今天我们来盘点一下古今第一高手对局 &#xff0c;塔矢行洋对战藤原佐为&#xff0c;谁才是最接近神之一手的人&#xff0c; 在所有设定都点击好之后, 塔矢行洋下出了自己的第一步 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 佐…

C语言内嵌汇编

反编译&#xff08;二进制文件或者so库&#xff09; objdump --help objdump -M intel -j .text -ld -C -S out > out.txt #显示源代码同时显示行号, 代码段反汇编-M intel 英特尔语法-M x86-64-C:将C符号名逆向解析-S 反汇编的同时&#xff0c;将反汇编代码和源代码交替显…

C++利用mutex和thread实现一个死锁

程序 #include<iostream> #include<mutex> #include<thread> using namespace std; mutex mtx1; mutex mtx2; void A(){mtx1.lock();cout<<"a:mtx1"<<endl;this_thread::sleep_for(chrono::milliseconds(1000));mtx2.lock();cout<…

《Java-SE-第三十一章》之网络编程

前言 在你立足处深挖下去,就会有泉水涌出!别管蒙昧者们叫嚷:“下边永远是地狱!” 博客主页&#xff1a;KC老衲爱尼姑的博客主页 博主的github&#xff0c;平常所写代码皆在于此 共勉&#xff1a;talk is cheap, show me the code 作者是爪哇岛的新手&#xff0c;水平很有限&…

右值引用与移动语义与完美转发

右值引用 右值 什么是右值&#xff0c;没有地址临时数据的我们称之为右值 我们无法对10、aa、字符串取地址的值我们称之为右值。因为他们是临时数据&#xff0c;并不保存再内存中&#xff0c;所以我们右值没有地址&#xff0c;也无法被赋值&#xff08;除const外&#xff0c;左…

【Elasticsearch】学好Elasticsearch系列-分词器

本文已收录至Github&#xff0c;推荐阅读 &#x1f449; Java随想录 先看后赞&#xff0c;养成习惯。 点赞收藏&#xff0c;人生辉煌。 文章目录 规范化&#xff1a;normalization字符过滤器&#xff1a;character filterHTML Strip Character FilterMapping Character FilterP…

IMV6.0

一、背景 经历了多个版本&#xff0c;基础内容在前面&#xff0c;可以使用之前的基础环境&#xff1a; v1&#xff1a; https://blog.csdn.net/wtt234/article/details/132139454 v2&#xff1a; https://blog.csdn.net/wtt234/article/details/132144907 v3&#xff1a; https…

vue实现pdf预览功能

背景&#xff1a;材料上传之后点击预览实现在浏览器上预览的效果 效果如下&#xff1a; 实现代码如下&#xff1a; //预览和下载操作 <el-table-column fixed"right" label"操作" width"210"><template #default"scope">…

JAVA Android 正则表达式

正则表达式 正则表达式是对字符串执行模式匹配的技术。 正则表达式匹配流程 private void RegTheory() {// 正则表达式String content "1998年12月8日&#xff0c;第二代Java平台的企业版J2EE发布。1999年6月&#xff0c;Sun公司发布了第二代Java平台(简称为Java2) &qu…

每次执行@Test方法前都执行一次DB初始化(SpringBoot Test + JUnit5环境)

引言 在执行单元测试时&#xff0c;可以使用诸如H2内存数据库替代线上的Mysql数据库等&#xff0c;如此在执行单元测试时就能尽可能模拟真实环境的SQL执行&#xff0c;同时也无需依赖线上数据库&#xff0c;增加了测试用例执行环境的可移植性。而使用H2数据库时&#xff0c;通…

Node.js |(二)Node.js API:fs模块 | 尚硅谷2023版Node.js零基础视频教程

学习视频&#xff1a;尚硅谷2023版Node.js零基础视频教程&#xff0c;nodejs新手到高手 文章目录 &#x1f4da;文件写入&#x1f407;writeFile 异步写入&#x1f407;writeFileSync 同步写入&#x1f407;appendFile / appendFileSync 追加写入&#x1f407;createWriteStrea…

点成分享丨qPCR仪的原理与使用——以Novacyt产品为例

近年来&#xff0c;PCR检测在多种领域发挥着巨大的作用。短时高效和即时监测都成为了PCR仪发展的方向。作为世界领先的制造商之一&#xff0c;Novacyt公司为来自全球多个国家和行业的用户提供了优质的qPCR仪。 MyGo Mini S qPCR仪是一种紧凑型的实时qPCR仪&#xff0c;非常适合…

【算法|双指针系列No.1】leetcode283. 移动零

个人主页&#xff1a;平行线也会相交 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 平行线也会相交 原创 收录于专栏【手撕算法系列专栏】【LeetCode】 &#x1f354;本专栏旨在提高自己算法能力的同时&#xff0c;记录一下自己的学习过程&#xff0c;希望…

c++进阶--二叉搜索树

目录 前言 一、二叉搜索树 1.二叉搜索树概念 2.二叉搜索树操作 二、二叉搜索树实现 0.定义一个节点 1.定义一棵树 2.增删改查 2.1.查找 2.2.插入 2.3.删除 2.3.1非递归删除法 a.只有左孩子 -- 删除14 b.只有右孩子-- 删除10 c.有左右孩子--删除8 2.3.2递归删除…

【论文总结】Chatting with GPT-3 for Zero-Shot Human-Like Mobile Automated GUI Testing

与GPT-3对话进行零尝试人类化移动自动化GUI测试 摘要&#xff1a; 移动应用在人们的日常生活中变得不可或缺&#xff0c;而自动化图形用户界面&#xff08;Graphical User Interface&#xff0c;GUI&#xff09;测试广泛用于应用程序质量保证。对于自动化GUI测试&#xff0c;越…