1 使用JDBC进行批处理

  • 当需要向数据库发送一批SQL语句的时候,应该避免向数据库一条条的发送执行,而应该采用JDBC的批处理机制,以提高执行效率。
  • 实现批处理的方式一:

    • Statement.addBatch(sql)
    • 执行批处理SQL语句:
      • executeBatch()方法:执行批处理命令。
      • clearBatch()方法:清理批处理命令。
    • 优点:可以向数据库发送多条不同的SQL语句。
    • 缺点:
      • ①SQL语句没有预编译。
      • ②当向数据库发送多条SQL语句相同,但仅仅参数不同的SQL语句的时候,需要重复写很多条SQL语句。 
  • 示例:实现批处理的方式一

    • SQL  
CREATE TABLE `user` (
  `id` ) NOT NULL AUTO_INCREMENT,
  `name` ) DEFAULT NULL,
  `password` ) DEFAULT NULL,
  `email` ) DEFAULT NULL,
  `birthday` date DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE DEFAULT CHARSET=utf8;
    • jdbc.properties  
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/jdbc
jdbc.user=root
jdbc.password=root
    • JDDCUtil.java  
package util;

import java.io.FileInputStream;
import java.io.IOException;
import java.sql.*;
import java.util.Properties;

/**
 * 2017/11/9
 * 说明:用来获取JDBC连接和释放资源的工具类
 */
public class JDBCUtil {
    private JDBCUtil(){}

    /**
     * 获取数据库的连接
     * @return
     * @throws IOException
     * @throws SQLException
     * @throws ClassNotFoundException
     */
    public static Connection getConnection() throws IOException, SQLException, ClassNotFoundException {
        Connection conn = null;
        //获取类路径下jdbc.properties的实际路径
        String jdbcPropertiesPath = JDBCUtil.class.getClassLoader().getResource("").getPath()+"jdbc.properties";
        //创建Properties对象
        Properties properties = new Properties();
        //将jdbc.properties文件加载进Properties对象
        properties.load(new FileInputStream(jdbcPropertiesPath));
        String driver = properties.getProperty("jdbc.driver");
        String url =  properties.getProperty("jdbc.url");
        String user = properties.getProperty("jdbc.user");
        String password = properties.getProperty("jdbc.password");

        //加载驱动
        Class.forName(driver);
        //获取连接
        conn = DriverManager.getConnection(url,user,password);
        return conn;
    }

    /**
     * 释放资源
     * @param conn
     * @param stmt
     * @param rs
     */
    public static void close(Connection conn, Statement stmt, ResultSet rs){
        if(conn != null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(stmt != null){
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(rs != null){
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

    }

}
    • DemoTest.java  
package test;

import org.junit.jupiter.api.Test;
import util.JDBCUtil;

import java.sql.Connection;
import java.sql.Statement;
import java.util.Arrays;

/**
 * 2017/11/9
 * 说明:
 */
public class DemoTest {

    @Test
    public void demo1(){
        Connection conn = null;
        Statement stmt = null;
        try {
            conn = JDBCUtil.getConnection();
            stmt = conn.createStatement();
            stmt.addBatch("insert into user values (null,'hehe','hehe','hehe@qq.com','2012-05-12')");
            stmt.addBatch("delete from user where id = 5");
            int[] is = stmt.executeBatch();
            System.out.println(Arrays.toString(is));

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            JDBCUtil.close(conn,stmt,null);
        }

    }

}
  • 实现批处理的方式二:

    • PreparedStatement.addBatch();
    • 需要注意内存问题。
    • 优点:发送的是预编译的SQL语句,执行效率高。
    • 缺点:只能应用在相同的SQL语句,但参数不同的批处理中,因此此种形式的批处理经常用于在同一个表中批量插入数据, 或批量更新表的数据。
package test;

import org.junit.jupiter.api.Test;
import util.JDBCUtil;

import java.sql.Connection;
import java.util.Date;
import java.sql.PreparedStatement;
import java.sql.Statement;
import java.util.Arrays;

/**
 * 2017/11/9
 * 说明:
 */
public class DemoTest {

    @Test
    public void demo2(){
        Connection conn = null;
        PreparedStatement pstmt = null;
        try {
            conn = JDBCUtil.getConnection();
            pstmt = conn.prepareStatement("insert into user VALUES (null,?,?,?,?)");
            for(int x =0;x<10000;x++){
               pstmt.setString(1,x+"name");
                pstmt.setString(2,x+"password");
                pstmt.setString(3,x+"email");
                pstmt.setDate(4,new java.sql.Date(new Date().getTime()));
                pstmt.addBatch();
                if(x % 1000 == 0){
                    pstmt.executeBatch();
                    pstmt.clearBatch();;
                }

            }
            pstmt.executeBatch();
            JDBCUtil.close(conn,pstmt,null);

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            JDBCUtil.close(conn,pstmt,null);
        }
    }

}

2 事务

2.1 事务的概述

  • 事务:事务是指逻辑上的一组操作,组成这组操作的各个单元,要么全部成功,要么全部失败。
  • 以MySQL为例:(默认情况下,MySQL的事务是默认开启的)
  • 开启事务的命令:
start transaction
  • 回滚事务:
rollback
  • 提交事务:
commit
  • JDBC使用事务:
  • 当jdbc程序向数据库获得一个Connection对象的时候,默认情况下Connection对象会自动向数据库提交发送的SQL。如果想关闭这种默认的提交方式,让多条SQL在同一个事务中执行,可以使用下列的语句:
  • 开启事务
void setAutoCommit(boolean autoCommit) throws SQLException
  • 回滚事务
void rollback() throws SQLException
  • 提交事务
void commit() throws SQLException

2.2 事务的特性(ACID)

  • 原子性:处于事务中的多条语句是不可分割的。
  • 一致性:事务必须使得数据库从一个一致性状态变换到另一个一致性状态。比如::转账前,A+B=10000元;转账后,A+B=10000元。
  • 隔离性:多线程并发,一个事务不能被其它线程中的事务所打扰。
  • 持久性:事务一旦提交,就永久保存起来。

2.3 事务的隔离级别

  • 多个线程开启各自的事务操作数据库中的数据的时候,数据库系统要负责隔离操作,以保证各个线程在获取数据时候的准确性。
  • 如果不考虑事务的隔离性,那么可能会引起如下的问题:
    • ①脏读:一个线程中的事务读取了另一个线程中没有提交的数据。
    • ②不可重复读:一个线程中的事务读取了另一个线程中已经提交的update的数据。
    • ③虚读(幻读):一个线程中的事务读取了另外一个线程中已经提交的insert的数据。  
  • 要避免上面的现象,可以通过更改事务的隔离级别来避免:
    • read uncommitted:脏读、不可重复读、虚读有可能发生。
    • read committed:避免脏读的发生,不可重复读和虚读有可能发生。
    • repeatable read:避免脏读和不可重复读的发生,虚读有可能发生。
    • serializable:避免脏读、不可重复读和虚读。  
  • 事务的隔离级别越大,效率越低。
  • MySQL中查询当前的隔离级别:
select @@tx_isolation;
  • MySQL中设置当前的事务的隔离级别:
set transaction isolation level 级别;

3 模拟百度分页显示效果

  • https://github.com/xuweiweiwoaini/pagination.git

JDBC (二)的更多相关文章

  1. JAVA基础-JDBC二(常用的开源工具)

    一.连接池 在实际的开发应用中,我们常常会对数据库进行大量的高并发的访问,而最原始的连接和操作方式并不能满足这种大量的访问,程序员为了追求更方便.更快捷.更科学安全的开发.第三方的工具类和Dao层的框 ...

  2. JDBC二查询(web基础学习笔记八)

    一.建立数据库 --创建news表空间 CREATE TABLESPACE tbs_news DATAFILE 'F:\ORACLE\news.dbf' SIZE 10M AUTOEXTEND ON; ...

  3. JDBC二部曲之_入门

    JDBC 1 什么是JDBC? JDBC(Java DataBase Connectivity),即Java数据库连接!也就是说,Java程序员可以使用JDBC API来操作数据库. 最早JDBC是J ...

  4. java JDBC (二) 防止注入/参数化

    package cn.sasa.demo2; import java.sql.Connection; import java.sql.DriverManager; import java.sql.Pr ...

  5. java基础之JDBC二:原生代码基础应用

    JDBC的基础应用CURD: 增删改 public void noQuery() { Connection conn = null; Statement stat = null; try { //注册 ...

  6. JDBC二部曲之_事物、连接池

    事务 事务概述 事务的四大特性(ACID) 事务的四大特性是: l  原子性(Atomicity):事务中所有操作是不可再分割的原子单位.事务中所有操作要么全部执行成功,要么全部执行失败. l  一致 ...

  7. JDBC(二)

    ##  详解JDBC各个对象 1.DriverManager对象:驱动管理对象 *  功能: 1.注册驱动:告诉程序该使用哪个数据jar包 static  void  registerDriver(D ...

  8. mysql的jdbc入门学习小结

    转自:专注JavaWeb开发 http://www.javaweb1024.com/data/MySQL/2015/04/25/618.html 一.jdbc基本概念jdbc : Java Datab ...

  9. Java基础 JDBC

    一,前言 数据库是开发中必不可少的一个工具,那么java如何操作数据库呢,那就是我们的JDBC了,接下来我们将会好好聊一下这个JDBC. 二,JDBC 2.1 JDBC概述 JDBC(Java Dat ...

  10. JDBC(3):PreparedStatement对象介绍

    一,PreparedStatement介绍 PreperedStatement是Statement的子类,它的实例对象可以通过Connection.preparedStatement()方法获得,相对 ...

随机推荐

  1. python实现简单函数发生器

    最近学校又抽风把我自动化系的苦逼童鞋留下做课设,简直无聊到爆的-->用VB实现函数发生器,(语言不限制) 大伙不知从哪搞来的MATLAB版本,于是几十个人就在这基础上修修改改蒙混过关了,可我实在 ...

  2. Java源码解读(一) 8种基本类型对应的封装类型

    说起源码其实第一个要看的应该是我们的父类Object,这里就不对它进行描述了大家各自对其进行阅读即可. 一.八种基本类型 接下来介绍我们的八种基本类型(这个大家都知道吧):char.byte.shor ...

  3. 一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](五)

    前言 Hi,大家好,我是Rector 时间飞逝,一个星期又过去了,今天还是星期五,Rector在图享网继续跟大家分享系列文本:一步一步创建ASP.NET MVC5程序[Repository+Autof ...

  4. Spring学习日志之Spring MVC启动配置

    对DispatcherServlet进行配置 Spring MVC的配置实际上就是对DispatcherServlet的配置 public class DispatcherServletConfig ...

  5. [国嵌攻略][106][Linux内存管理子系统]

    内存管理子系统 1.虚拟地址与物理地址的映射 2.物理内存的分配 Linux虚拟地址空间分布 设备最后访问的一定是物理地址,但Linux系统中使用的都是虚拟地址.虚拟地址简单的来说就是程序中使用的地址 ...

  6. [国嵌笔记][017][Makefile工程管理]

    Makefile的用途 1.make能够使整个程序的编译.链接只需一个命令就可以完成 2.make的工作主要依赖于Makefile的文件.Makefile文件描述了整个程序的编译.链接等规则,使之自动 ...

  7. js object 常用方法总结

    Object.assign(target,source1,source2,...) 该方法主要用于对象的合并,将源对象source的所有可枚举属性合并到目标对象target上,此方法只拷贝源对象的自身 ...

  8. hbase性能优化总结

    hbase性能优化总结 1. 表的设计 1.1 Pre-Creating Regions 默认情况下,在创建HBase表的时候会自动创建一个region分区,当导入数据的时候,所有的HBase客户端都 ...

  9. 通过Xshell如何从Linux服务器下载文件(亲测可行)

    到网上下载lrzsz安装包,这里以lrzsz-0.12.20.tar.gz为例 2 打开终端 cd 到安装包所在目录 tar zxvf lrzsz-0.12.20.tar.gz 解压安装包 3 进入解 ...

  10. Rootkit 核心技术——利用 nt!_MDL(内存描述符链表)突破 SSDT(系统服务描述符表)的只读访问限制 Part I

    -------------------------------------------------------- 在 rootkit 与恶意软件开发中有一项基本需求,那就是 hook Windows ...