JDBC概述三(批处理+事务操作+数据库连接池)

一(批处理)

1.1 批处理简介

批处理,简而言之就是一次性执行多条SQL语句,在一定程度上可以提升执行SQL语句的速率。批处理可以通过使用Java的Statement和PreparedStatement来完成,因为这两个语句提供了用于处理批处理的方法。

1.2 批处理的3个方法

1.void addBatch(String sql):将需要执行的SQL语句添加到批处理中。

2.int [] executeBatch();执行批处理。

3.clearBatch();清空批处理。  

分别使用Statement和PreparedStatement执行批处理: 

package batch.transaction;

import com.yxp.util.DBUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Arrays;

/**
 * 批处理:本质就是执行多条SQL语句
 * 步骤1.添加进批处理addBath()
 * 步骤2.执行批处理executeBatch()
 * 步骤3.清空批处理clearBatch()
 */
public class Batch {
    static Connection con= null;
    public static void main(String[] args) throws SQLException {
        /**
         * 使用封装思想,更加贴近面向对象设计,代码的可读性更高
         */
        //PreparedStatement执行批处理
        System.out.println("PreparedStatement执行批处理:");
        ps(con);
        System.out.println("-------------------------------");
        //Statement执行批处理
        System.out.println("Statement执行批处理:");
        st(con);
        }
    private static void st(Connection con) throws SQLException {
        //1.获得连接
        con=DBUtils.getConnection();
        //2.获得语句处理对象
        Statement s=con.createStatement();
        for (int i =1; i <=2000 ; i++) {
            //3.写sql语句
            String sql_Statement="insert into t1_batch(name)values ('"+i+"')";
            //4.将sql语句放入批处理对象中
            s.addBatch(sql_Statement);
        }
        //5.执行批处理
        int[] arr1=s.executeBatch();
        //6.清空批处理
        s.clearBatch();
        System.out.println(arr1.length);
        System.out.println(Arrays.toString(arr1));
    }
    private static void ps(Connection con) throws SQLException {
        //1.获得连接
        con= DBUtils.getConnection();
        //2.写sql语句
        String sql_preparedStatement="insert into t1_batch (name)values (?)";
        //3.获得语句处理对象
            PreparedStatement ps=con.prepareStatement(sql_preparedStatement);
            long time1=System.currentTimeMillis();
            for (int i = 1; i <=2000 ; i++) {
                //4.参数赋值
                ps.setString(1,i+"_");
                //5.添加进批处理
                ps.addBatch();
                if(i%500==0){//每添加500个才执行一次,防止内存溢出
                    //6.执行批处理
                    ps.executeBatch();
                    //每执行一次批处理就清空一次
                    ps.clearBatch();
                }
            }
            //此段仍然不能丢失,剩余的可能不是500整数的需要单独处理
            int[] arr=ps.executeBatch();//一条sql语句更新处理以后,返回一个int数据,批处理他返回的是一个int[]
            //7.清空批处理
            ps.clearBatch();
        long time2=System.currentTimeMillis();
        System.out.println("共花费:"+(time2-time1)+"毫秒");
        System.out.println(Arrays.toString(arr));
    }
    }


 二(事务操作)

2.1 事务的简介

事务指逻辑上的一组操作,组成这组操作的各个单元,要么全部成功,要么全部失败。在不同的环境中,都可以有事务。对应在数据库中,就是数据库事务。(访问并可能操作各种数据项的一个数据库操作序列)。 事务由事务开始(begin transaction)和事务结束(end transaction)之间执行的全体操作组成。

事务结束有两种,事务中的步骤全部成功执行时,提交事务。如果其中一个失败,那么将会发生回滚操作,并且撤销之前的所有操作。也就是说,事务内的语句,要么全部执行成功,要么全部执行失败。

2.2 事务四大特征ACID

2.2.1. 原子性(Atomicity)

原子性是指事务是一个不可分割的工作单位,整个事务中的所有操作要么全部提交成功,要么全部失败回滚,对于一个事务来说,不可能只执行其中的一部分操作。

2.2.2 一致性(Consistency) 

一致性是指事务必须使数据库从一个一致性状态变换到另一个一致性状态。也就是说事务前后数据的完整性必须保持一致。

2.2.3 隔离性(Isolation) 

隔离性是指一个事务的执行不能有其他事务的干扰,事务的内部操作和使用数据对其他的并发事务是隔离的,互不干扰。

2.2.4 持久性(Durability) 

持久性是指一个事务一旦提交,对数据库中数据的改变就是永久性的。此时即使数据库发生故障,修改的数据也不会丢失。接下来其他的操作不会对已经提交了的事务产生影响。
 

模拟转账操作

package batch.transaction;

import com.yxp.util.DBUtils;

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

/**
 * 事务4大特性:ACID
 * 1.原子性Atomicity
 * 2.一致性Consistency
 * 3.隔离性Isolation
 * 4、持久性Duration
 */
//模拟转账操作
public class Transaaction {
    static Connection con= null;
    static PreparedStatement ps=null;

    public static void main(String[] args) {
        transferaccounts(1,2,10000);
    }

    /**
     *
     * @param from 从谁的账户转
     * @param to   转给谁
     * @param money 转多少
     */
    private static void transferaccounts(int from, int to,double money) {
            //1.获得连接
        con= DBUtils.getConnection();
            //2.写sql语句
        String  sql1="update t1_icbc set money=money-? where id=? ";
        String  sql2="update t1_icbc set money=money+? where id=? ";
            //3.获得语句处理对象
        try {
            PreparedStatement ps1=con.prepareStatement(sql1);
            PreparedStatement ps2=con.prepareStatement(sql2);
            //4.参数赋值
            ps1.setDouble(1,money);
            ps1.setInt(2,from);
            ps2.setDouble(1,money);
            ps2.setInt(2,to);
            //如果需要回滚,需要设置事务手动提交
            con.setAutoCommit(false);
            //5.执行sql
            int res1=ps1.executeUpdate();
            /**
             * 模拟一个异常,程序结束
             */
            int a=4/0;
            int res2=ps2.executeUpdate();
            //判定:当二者都执行成功了
            if(res1==1&&res2==1){
                con.commit();//提交事务
            }
        } catch (Exception throwables) {
            throwables.printStackTrace();
            //数据要回滚,本身sql是默认自动提交事务的,无法回滚
            //异常被捕获,说明之前提交的数据需要回滚
            try {
                System.out.println("哎呀,转账失败……");
                con.rollback();//事务回滚
            } catch (SQLException e) {
                e.printStackTrace();
            }finally {
                //由于数据库现在被设置手动提交,为了防止影响后续操作,运行以后一定需要将提交方式设置为自动
                try {
                    con.setAutoCommit(true);
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}

转账前,哈儿有30000元,狗蛋儿有20000元,当哈儿给狗蛋转账10000元后,哈儿就变成20000元,狗蛋儿就有30000元。

1.脏读 

脏读是指在一个事务处理过程里读取了另一个未提交的事务中的数据。比如在事务 A 修改数据之后提交数据之前,这时另一个事务 B 来读取数据,如果不加控制,事务 B 读取到 A 修改过数据,之后 A 又对数据做了修改再提交,则 B 读到的数据是脏数据,此过程称为脏读。

2.不可重复读 


不可重复读是指在数据库访问中,一个事务范围内多次查询却返回了不同的数据值。这是由于在查询间隔中,其他事务修改并提交而引起的。比如事务 T1 读取某一数据,事务 T2 读取并修改了该数据,T1 为了对读取值进行检验而再次读取该数据,便得到了不同的结果。

3. 幻读

幻读是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,比如这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。比如事务 A 在按查询条件读取某个范围的记录时,事务 B 又在该范围内插入了新的满足条件的记录,当事务 A 再次按条件查询记录时,会产生新的满足条件的记录。
 

SQL的四个隔离级别


1.未提交读(Read Uncommitted)

一个事务能够读取到别的事务中没有提交的更新数据。事务中的修改,即使没有提交,其他事务也可以看得到。在这种隔离级别下有可能发生脏读,不可重复读和幻读。

2.提交读(Read Committed)

事务中的修改只有提交以后才能被其它事务看到。在这种隔离级别下解决了脏读,但是有可能发生不可重复读和幻读。

3.可重复读(Repeated Read)

保证了在同一事务中先后执行的多次查询将返回同一结果,看到的每行的记录的结果是一致的,不受其他事务的影响。但是这种级别下有可能发生幻读。

4.可串行化(Serializable)

不允许事务并发执行,强制事务串行执行。就是在读取的每一行数据上都加上了锁,读写相互都会阻塞,所以效率很低下。这种隔离级别最高,是最安全的,但是性能最低,不会出现脏读,不可重复读,幻读。

三(数据库连接池)

3.1 数据库连接池简介

简而言之,就是一个容器内有多个数据库连接,当程序需要操作数据库的时候直接从池中取出连接,使用完之后再还回去,和线程池一个道理。连接池必须实现javax.sql.DataSource 接口,连接池里面维护的是一个DataSource的数据源。

3.2 使用数据库连接池的好处

(1)节省资源,如果每次访问数据库都创建新的连接,创建和销毁都浪费系统资源

(2)响应性更好,省去了创建的时间。

(3)统一的进行数据库管理,超时机制,减少JVM垃圾,减少数据库的过载。

3.3 常见的数据库连接池对象

1.DBCP2(DataBase Connection Pool 2)

数据库连接池,从Tomcat 5.5开始,Tomcat 内置了DBCP的数据源实现,所以可以非常方便地配置DBCP数据源.

2. C3P0

hibernate工作组进行维护,自动回收空闲连接。

3.德鲁伊 Druid

阿里巴巴的国产数据库连接池,能够提供强大的监控和扩展功能。

3.4 数据库连接池的常见参数配置

1、driverClassName 使用的JDBC驱动的完整有效的Java类名,如连接 mysql:com.mysql.cj.jdbc.Driver

2、url  数据库的连接地址。如 jdbc:mysql://127.0.0.1:3306/mydatabase

3、username 数据库的用户名,如 root

4、password 数据库的用户密码

5、initialSize 连接池创建的时候,自动创建的数据库连接数量(初始化连接数量),建议 10-50足够

6、maxIdle 最大空闲连接:连接池中允许保持空闲状态的最大连接数量,超过的空闲连接将被释放,如果设置为负数表示不限制,建议设置和 与initialSize相同,减少释放和创建的性能损耗。

7、minIdle  最小空闲连接:连接池中容许保持空闲状态的最小连接数量,低于这个数量将创建新的连接,如果设置为0则不创建

8、maxActive 最大同时激活的连接数量。

9、maxWait 如果连接池中没有可用的连接,最大的等待时间,超时则没有可用连接,单位毫秒,设置-1时表示无限等待,建议设置为100毫秒

10、testxxx  在对连接进行操作时,是否检测连接的有效性,如 testOnBorrow 在申请连接的时候会先检测连接的有效性,执行validationQuery ,建议线上的把此配置设置为false,因为会影响性能。

11、validationQuery 检查池中的连接是否仍可用的 SQL 语句,drui会连接到数据库执行该SQL, 如果正常返回,则表示连接可用,否则表示连接不可用,建议 select 1 from dual
 

3.5 如何使用Druid

1.导入druid jar包

3.5.2  使用数据库连接池与数据库获得连接

配置文件:druid.properties

driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/wyy?serverTimezone=UTC&characterEncoding=utf8&useUnicode=true&useSSL=false&allowPublicKeyRetrieval=true
username=root
password=123456
#初始化连接数量
initialSize=5
#最大的活动连接
maxActive=10
#最大的等待时间
maxWait=6000
package druid;

import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

public class DruidUtil {
 //连接池里面维护的是一个DataSource的数据源
 private static DataSource dataSource;
 static {
  Properties p=new Properties();
  try {
   InputStream is=new FileInputStream("D:\\javaEE\\VIP07_1\\jdbc\\src\\druid\\druid.properties");
   //使用配置文件对象读取字节流
   p.load(is);
   //数据源赋值
   dataSource= DruidDataSourceFactory.createDataSource(p);
  } catch (FileNotFoundException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
/**
 * 获得连接对象
 */
public static Connection getCon(){
 Connection conn=null;
 try {
  conn=dataSource.getConnection();
 } catch (SQLException e) {
  e.printStackTrace();
 }
 return conn;
}
 /**
  * 关闭链接
  */
 public static void close(Connection conn, Statement ps, ResultSet rs){
  if(rs!=null){
   try {
    rs.close();
   } catch (SQLException e) {
    e.printStackTrace();
   }
  }
  if(ps!=null){
   try {
    ps.close();
   } catch (SQLException e) {
    e.printStackTrace();
   }
  }
  if(conn!=null){
   try {
    conn.close();
   } catch (SQLException e) {
    e.printStackTrace();
   }
  }
 }

 public static void main(String[] args) {
  System.out.println(getCon());
 }
}

经测试,使用数据库连接池来与数据库获得连接,同样连接成功。

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

BGP策略实验

实验要求&#xff1a; 1、使用PreVa1策略&#xff0c;确保R4通过R2到达192.168.10.0/24 2、使用AS_Path策略&#xff0c;确保R4通过R3到达192.168.11.0/24 3、配置MED策略&#xff0c;确保R4通过R3到达192.168.12.0/24 4、使用Local Preference策略&#xff0c;确保R1通过R2到…

公司新招了个腾讯拿38K的人,让我见识到了什么才是测试天花板···

5年测试&#xff0c;应该是能达到资深测试的水准&#xff0c;即不仅能熟练地开发业务&#xff0c;而且还能熟悉项目开发&#xff0c;测试&#xff0c;调试和发布的流程&#xff0c;而且还应该能全面掌握数据库等方面的技能&#xff0c;如果技能再高些的话&#xff0c;甚至熟悉分…

【失业即将到来?】AI时代会带来失业潮吗?

文章目录前言一、全面拥抱AIGC二、AI正在取代这类行业总结前言 兄弟姐妹们啊&#xff0c;AI时代&#xff0c;说抛弃就抛弃&#xff0c;真的要失业了。 一、全面拥抱AIGC 蓝色光标全面暂停外包&#xff1f; 一份文件截图显示&#xff0c;中国知名4A广告公司&#xff0c;蓝色光…

【GPT4】微软 GPT-4 测试报告(5)与外界环境的交互能力

欢迎关注【youcans的AGI学习笔记】原创作品 微软 GPT-4 测试报告&#xff08;1&#xff09;总体介绍 微软 GPT-4 测试报告&#xff08;2&#xff09;多模态与跨学科能力 微软 GPT-4 测试报告&#xff08;3&#xff09;编程能力 微软 GPT-4 测试报告&#xff08;4&#xff09;数…

基于AI分词模型,构建一个简陋的Web应用

文章目录前言1. 效果展示2. 应用设计3. 实现3.1. lac分词模型的服务化部署3.2 使用Flask构建app4. 小结前言 内容纯属个人经验&#xff0c;若有不当或错误之处&#xff0c;还请见谅&#xff0c;欢迎指出。 文中大致介绍了&#xff0c;如何快捷地使用PaddleHub服务化部署一个简…

九龙证券|昨夜,大涨!蔚来5.99%,小鹏15.22%,理想6.39%

当地时间周一&#xff0c;美股三大指数低开高走&#xff0c;尾盘小幅收涨。盘面上&#xff0c;银行股、航空股遍及上涨。 展望本周&#xff0c;包括美联储理事沃勒、鲍曼等官员将迎来下月会议沉默期前的最终说话&#xff0c;投资者需关注其对经济和货币政策前景的看法。此外&am…

如何在TikTok视频描述中提高用户参与度

鑫优尚电子商务&#xff1a;TikTok视频描述&#xff08;包括话题标签&#xff09;有150个字符的限制&#xff0c;因此卖家需要合理撰写出有趣且有实际意义的视频描述。可尝试将描述保持在140个字符以内&#xff0c;将最重要的信息放在前面&#xff0c;并通过多次修改文案以排除…

甘特图控件DHTMLX Gantt入门使用教程【引入】:dhtmlxGantt与ASP.NET Core(上)

DHTMLX Gantt是用于跨浏览器和跨平台应用程序的功能齐全的Gantt图表。可满足项目管理应用程序的大部分开发需求&#xff0c;具备完善的甘特图图表库&#xff0c;功能强大&#xff0c;价格便宜&#xff0c;提供丰富而灵活的JavaScript API接口&#xff0c;与各种服务器端技术&am…

【获奖案例巡展】科技向善之星——中航电梯5G+大数据管理平台

为表彰使用大数据、人工智能等基础软件为企业、行业或世界做出杰出贡献和巨大创新的标杆项目&#xff0c;星环科技自2021年推出了“新科技 星力量” 星环科技科技实践案例评选活动&#xff0c;旨在为各行业提供更多的优秀产品案例&#xff0c;彰显技术改变世界的力量&#xff0…

会话跟踪技术

目录 Cookie基本使用 Cookie原理 Cookie使用细节 Session基本使用 Session原理 Session使用细节 案例 用户登录注册案例 用户注册功能 保存用户信息到数据库 验证码-展示 验证码-校验 会话跟踪技术的概述 会话:用户打开浏览器&#xff0c;访问web服务器的资源&…

ssm框架之SpringMVC:浅聊获得参数以及获得请求头参数

前面聊过了SpringMVC&#xff0c;以及通过实例演示了SpringMVC如何搭建&#xff0c;如果对环境搭建不太了解的话&#xff0c;可以看一下前面的文章&#xff08;下面演示的例子&#xff0c;环境都是通过上面的例子进行演示的&#xff09;&#xff1a;传送阵 在使用javaweb项目原…

图解PMP项目管理马斯洛需求层次理论在公司管理中的应用!

马斯洛的需求层次结构是心理学中的激励理论&#xff0c;包括人类需求的五级模型&#xff0c;通常被描绘成金字塔内的等级。 从层次结构的底部向上&#xff0c;需求分别为&#xff1a;生理&#xff08;食物和衣服&#xff09;&#xff0c;安全&#xff08;工作保障&#xff09;…

stm32下载代码到单片机上需要调节BOOT为什么模式

一、BOOT模式选择图解 二、BOOT模式介绍 所谓启动&#xff0c;一般来说就是指下好程序后&#xff0c;重启芯片时&#xff0c;SYSCLK的第4个上升沿&#xff0c;BOOT引脚的值将被锁存。用户可以通过设置BOOT1和BOOT0引脚的状态&#xff0c;来选择在复位后的启动模式。 A. Mai…

MongoDB 聚合管道中使用数组表达式运算符合并数组($concatArrays)

数组表达式运算符主要用于文档中数组的操作&#xff0c;接上一篇&#xff1a;MongoDB 聚合管道中使用数组表达式运算符&#xff08;$slice截取数组&#xff09;https://blog.csdn.net/m1729339749/article/details/130130328本篇我们主要介绍数组表达式运算符中用于合并数组的操…

LMKD分享

背景 Android是一个多任务系统&#xff0c;可以同时运行多个程序&#xff0c;一般来说&#xff0c;启动运行一个程序是有一定的时间开销的&#xff0c;因此为了加快运行速度&#xff0c;当你退出一个程序时&#xff0c;Android并不会立即杀掉它&#xff0c;这样下次再运行该程…

【论文阅读】3D-LaneNet

【论文阅读】3D-LaneNet 主要要做的事情就是 lane detection。这里提一下 BEV&#xff08;Bird‘s Eye View&#xff09; 感知算法&#xff0c;为了将 2D 图像映射到 3D 空间中&#xff0c;能够更准确的检测物体位置&#xff0c;需要 BEV 感知的结果。后续还会继续了解这方面内…

企业数据安全能力建设思路

在现代社会&#xff0c;企业数据安全已经成为一个非常重要的话题。企业数据安全能力的建设是每个企业都必须面对和解决的问题。企业数据安全能力建设思路包括以下几个方面&#xff1a; 1. 建立完善的安全管理制度 企业要建立完善的安全管理制度&#xff0c;包括信息安全政策、…

注册claude AI账号 slack工作区账号

Claude 是建立在 slack工作区的一个AI人工助手&#xff0c;更像是将chatgpt集成到了会议模式&#xff0c;一个账号实际上拥有了你的会议室和你的AI助手&#xff0c;你可以让你的朋友和同事进入你的房间体验。 Claude是不是openai的产物&#xff1f;目前还不知道&#xff0c;不…

phpstudy本地环境搭建图文教程

作者&#xff1a;Eason_LYC 悲观者预言失败&#xff0c;十言九中。 乐观者创造奇迹&#xff0c;一次即可。 一个人的价值&#xff0c;在于他所拥有的。可以不学无术&#xff0c;但不能一无所有&#xff01; 技术领域&#xff1a;WEB安全、网络攻防 关注WEB安全、网络攻防。我的…

价值迭代求解马尔可夫决策过程

Value Iteration Algorithm 其算法思想是: 在每一个状态s下&#xff0c; 之迭代算法流程如下&#xff1a; 初始化状态价值state value&#xff0c;即对每个状态的价值都赋一个初始值&#xff0c;一般是0 计算每一个状态-动作对的 动作价值函数&#xff0c;通常通过创建一个二维…