栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

JDBC(2)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

JDBC(2)

一、事务

 

1.1 基本介绍

1. JDBC程序中当一个Connection对象创建时,默认情况下是自动提交事务:每次执行一个SQL语句时,如果执行成功,就会向数据库自动提交,而不能回滚。

2. JDBC程序中为了让多个SQL语句作为一个整体执行,需要使用事务

3. 调用Connection的setAutoCommit(false)可以取消自动提交事务

4. 在所有的SQL语句都成功执行后,调用Connection的 commit();方法提交事务

5. 在其中某个操作失败或者出现异常时,调用Connection的 rollback();方法回滚事务

package com.learn.jdbc.transaction_;

import com.learn.jdbc.utils.JDBCUtils;
import org.junit.jupiter.api.Test;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;


public class Transaction_ {
    //没有使用事务
    @Test
    public void noTransaction() {

        //操作转账的业务
        //1.得到连接
        Connection connection = null;

        //2.组织一个sql
        String sql1 = "update account set balance = balance - 100 where id = 1";
        String sql2 = "update account set balance = balance + 100 where id = 2";
        PreparedStatement preparedStatement = null;
        //3.创建PreparedStatement对象
        try {
            connection = JDBCUtils.getConnection();//在默认情况下,connection是默认自动提交
            preparedStatement = connection.prepareStatement(sql1);
            preparedStatement.executeUpdate();//执行第一条sql

            int i = 1 / 0;
            preparedStatement = connection.prepareStatement(sql2);
            preparedStatement.executeUpdate();//执行第二条sql

        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //关闭资源
            JDBCUtils.close(null, preparedStatement, connection);
        }
    }

    @Test
    //用事务来解决
    public void userTransaction() {
        //操作转账的业务
        //1.得到连接
        Connection connection = null;

        //2.组织一个sql
        String sql1 = "update account set balance = balance - 100 where id = 1";
        String sql2 = "update account set balance = balance + 100 where id = 2";
        PreparedStatement preparedStatement = null;
        //3.创建PreparedStatement对象
        try {
            connection = JDBCUtils.getConnection();//在默认情况下,connection是默认自动提交
            //将connection设置为不自动提交
            connection.setAutoCommit(false);
            preparedStatement = connection.prepareStatement(sql1);
            preparedStatement.executeUpdate();//执行第一条sql

            //int i = 1 / 0;
            preparedStatement = connection.prepareStatement(sql2);
            preparedStatement.executeUpdate();//执行第二条sql

            //在这里提交事务
            connection.commit();

        } catch (SQLException e) {
            //这里可以进行回滚,即撤销执行sql
            System.out.println("执行发生了异常,撤销执行的sql");
            try {
                connection.rollback();//默认回滚到事务开始的状态
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
            e.printStackTrace();
        }finally {
            //关闭资源
            JDBCUtils.close(null, preparedStatement, connection);
        }
    }


}
二、批处理 2.1 基本介绍

1. 当需要成批插入或者更新记录时,,可以采用Java的批量更新机制,这一机制允许多条语句一次性提交给数据库批量处理。通常情况下比单独提交处理更有效率。

2. JDBC的批量处理语句包括下面方法:

        ① addBatch():添加需要批量处理的SQL语句或参数

        ② executeBatch():执行批量处理语句

        ③ clearBatch():清空批处理包的语句

3. JDBC连接Mysql时,如需使用批处理功能,请在url中加参数 ?rewriteBatchedStatements=true

4. 批处理往往和PreparedStatement一起搭配使用,可以既减少编译次数,又减少运行次数,效率大大提高

package com.learn.jdbc.batch_;

import com.learn.jdbc.utils.JDBCUtils;
import org.junit.jupiter.api.Test;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;


public class Batch_ {

    //传统方法, 添加5000条数据到admin2表
    @Test
    public void noBatch() throws SQLException {

        Connection connection = JDBCUtils.getConnection();
        String sql = "insert into admin2 values(null, ?, ?)";
        PreparedStatement preparedStatement = connection.prepareStatement(sql);

        System.out.println("开始执行...");
        long start = System.currentTimeMillis();
        for (int i = 0; i < 5000; i++) {
            preparedStatement.setString(1, "jack" + i);
            preparedStatement.setString(2, "666");
            preparedStatement.executeUpdate();
        }
        long end = System.currentTimeMillis();
        System.out.println("传统方式 耗时= " + (end - start));//2298
        //关闭连接
        JDBCUtils.close(null, preparedStatement, connection);
    }

    @Test
    //使用批量处理添加方式
    public void batch() throws SQLException {
        Connection connection = JDBCUtils.getConnection();
        String sql = "insert into admin2 values(null, ?, ?)";
        PreparedStatement preparedStatement = connection.prepareStatement(sql);

        System.out.println("开始执行...");
        long start = System.currentTimeMillis();
        for (int i = 0; i < 5000; i++) {
            preparedStatement.setString(1, "jack" + i);
            preparedStatement.setString(2, "666");
            //将sql语句加入到批处理包中
            preparedStatement.addBatch();
            //当有1000条记录时再批量执行
            if((i + 1) % 1000 == 0){ //满1000条sql
                preparedStatement.executeBatch();
                //满了以后再清空
                preparedStatement.clearBatch();
            }
        }
        long end = System.currentTimeMillis();
        System.out.println("批处理方式 耗时= " + (end - start));//55
        //关闭连接
        JDBCUtils.close(null, preparedStatement, connection);
    }
}
三、数据库连接池 3.1 传统获取Connection问题分析

1. 传统的JDBC数据库连接使用DriverManager来获取,每次向数据库建立连接的时候都要将Connection加载到内存中,再验证IP地址,用户名和密码(0.05s~1s时间)。需要数据库连接的时候,就向数据库要求一个,频繁的进行数据库连接操作将占用很多的系统资源,容易造成服务器崩溃。

2. 每一次数据库连接,使用完后都得断开,如果程序出现异常而未能关闭,将导致数据库内存泄漏,最终将导致重启数据库

3. 传统获取连接的方式,不能控制创建的连接数量,如连接过多,也可能导致内存泄漏,MySQL崩溃

4. 解决传统开发中的数据库连接问题,可以采用数据库连接池技术(connection pool)

3.2 数据库连接池基本介绍

1. 预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕之后再放回去

2. 数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个

3. 当应用程序向连接池请求的连接数超过最大连接数量时,这些请求将被加入到等待队列中

3.3 数据库连接池种类

1. JDBC的数据库连接池使用 javax.sql.DataSource来表示,DataSource只是一个接口,该接口通常由第三方提供[提供.jar]

2. C3P0数据库连接池,速度相对较慢,但稳定性不错(hibernate,spring)

3. DBCP数据库连接池,速度相对C3P0较快,但不稳定

4. Proxool数据库连接池,有监控连接池状态的功能,稳定性较C3P0差一点

5. BoneCP数据库连接池,速度快

6. Druid(德鲁伊)是阿里提供的数据库连接池,集DBCP、C3P0、Proxool优点于一身的数据库连接池

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/886231.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号