精华内容
下载资源
问答
  • jdbc批处理

    2019-02-16 13:31:30
    顾名思义,批处理就是对某一对象进行批量处理,而在jdbc中,批处理具体指的是一次性执行多条SQL语句,允许多条语句一次性提交给数据库批量处理。 为什么使用批处理 一个词,效率,使用批处理比单个执行SQL语句效率...

    批处理

    • 什么是批处理
      顾名思义,批处理就是对某一对象进行批量处理,而在jdbc中,批处理具体指的是一次性执行多条SQL语句,允许多条语句一次性提交给数据库批量处理。

    • 为什么使用批处理
      一个词,效率,使用批处理比单个执行SQL语句效率要高

    • 在JDBC中如何使用

    addBatch(SQL);添加需要处理的SQL语句
    executeBatch();执行批处理
    
    • 数据库支持情况
      MySQL默认情况下是不支持批处理的
      但从5.1.13开始添加了一个rewriteBatchStatement的参数
      如何添加
      在加载驱动时设置该参数
    public static String url = "jdbc:mysql://localhost:3306/jdbc_test?rewriteBatchedStatements=true";
    

    我们用数据来说话,来比较一下批处理的效率
    在这里插入图片描述
    记住这个数字 55950
    然后我们来看批处理的时间

    在这里插入图片描述
    203,嗯嗯,this is why we play

    展开全文
  • Today we will look into JDBC Batch insert and update examples in MySQL and Oracle databases. Sometimes we need to run bulk queries of a similar kind for a database. For example, loading data from CSV ...

    Today we will look into JDBC Batch insert and update examples in MySQL and Oracle databases. Sometimes we need to run bulk queries of a similar kind for a database. For example, loading data from CSV files to relational database tables.

    今天,我们将研究MySQL和MySQL数据库中的JDBC Batch插入和更新示例。 有时我们需要对数据库运行类似类型的批量查询。 例如,将数据从CSV文件加载到关系数据库表。

    As we know that we have option to use Statement or PreparedStatement to execute queries. Apart from that JDBC provides Batch Processing feature through which we can execute the bulk of queries in one go for a database.

    众所周知,我们可以选择使用StatementPreparedStatement来执行查询。 除此之外, JDBC提供了批处理功能,通过该功能,我们可以一次性执行数据库的大量查询。

    JDBC批处理 (JDBC Batch)

    JDBC batch statements are processed through Statement and PreparedStatement addBatch() and executeBatch() methods. This tutorial is aimed to provide details about JDBC Batch insert example for MySQL and Oracle database.

    JDBC批处理语句通过Statement和PreparedStatement addBatch()executeBatch()方法进行处理。 本教程旨在提供有关MySQL和Oracle数据库的JDBC Batch插入示例的详细信息。

    We will look into different programs so we have a project with the structure as below image.

    我们将研究不同的程序,因此我们有一个结构如下图的项目。

    Notice that I have MySQL and Oracle DB JDBC Driver jars in the project build path so that we can run our application across MySQL and Oracle DB both.

    注意,我在项目构建路径中有MySQL和Oracle DB JDBC Driver jar,以便我们可以在MySQL和Oracle DB两者上运行我们的应用程序。

    Let’s first create a simple table for our test programs. We will run the bulk of JDBC insert queries and look at the performance with different approaches.

    让我们首先为我们的测试程序创建一个简单的表。 我们将运行大量的JDBC插入查询,并使用不同的方法查看性能。

    --Oracle DB
    CREATE TABLE Employee (
      empId NUMBER NOT NULL,
      name varchar2(10) DEFAULT NULL,
      PRIMARY KEY (empId)
    );
    
    --MySQL DB
    CREATE TABLE `Employee` (
      `empId` int(10) unsigned NOT NULL,
      `name` varchar(10) DEFAULT NULL,
      PRIMARY KEY (`empId`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

    We will read the Database configuration details from the property file so that switching from one database to another is quick and easy.

    我们将从属性文件中读取数据库配置详细信息,以便快速而轻松地从一个数据库切换到另一个数据库。

    db.properties

    db.properties

    #mysql DB properties
    DB_DRIVER_CLASS=com.mysql.jdbc.Driver
    DB_URL=jdbc:mysql://localhost:3306/UserDB
    #DB_URL=jdbc:mysql://localhost:3306/UserDB?rewriteBatchedStatements=true
    DB_USERNAME=pankaj
    DB_PASSWORD=pankaj123
    
    #Oracle DB Properties
    #DB_DRIVER_CLASS=oracle.jdbc.driver.OracleDriver
    #DB_URL=jdbc:oracle:thin:@localhost:1871:UserDB
    #DB_USERNAME=scott
    #DB_PASSWORD=tiger

    Before we move into actual JDBC batch insert example to insert bulk data into the Employee table, let’s write a simple utility class to get the database connection.

    在进入实际的JDBC批处理插入示例以将批量数据插入Employee表之前,让我们编写一个简单的实用程序类来获取数据库连接。

    DBConnection.java

    DBConnection.java

    package com.journaldev.jdbc.batch;
    
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    import java.util.Properties;
    
    public class DBConnection {
    
    	public static Connection getConnection() {
    		Properties props = new Properties();
    		FileInputStream fis = null;
    		Connection con = null;
    		try {
    			fis = new FileInputStream("db.properties");
    			props.load(fis);
    
    			// load the Driver Class
    			Class.forName(props.getProperty("DB_DRIVER_CLASS"));
    
    			// create the connection now
    			con = DriverManager.getConnection(props.getProperty("DB_URL"),
    					props.getProperty("DB_USERNAME"),
    					props.getProperty("DB_PASSWORD"));
    		} catch (IOException e) {
    			e.printStackTrace();
    		} catch (ClassNotFoundException e) {
    			e.printStackTrace();
    		} catch (SQLException e) {
    			e.printStackTrace();
    		}
    		return con;
    	}
    }

    Now let’s look at the different approach we can take for JDBC batch insert example.

    现在让我们看一下可以为JDBC批处理插入示例使用的不同方法。

    1. Use Statement to execute one query at a time.

      JDBCStatement.java

      package com.journaldev.jdbc.batch;
      
      import java.sql.Connection;
      import java.sql.SQLException;
      import java.sql.Statement;
      
      public class JDBCStatement {
      
      	public static void main(String[] args) {
      		
      		Connection con = null;
      		Statement stmt = null;
      		
      		try {
      			con = DBConnection.getConnection();
      			stmt = con.createStatement();
      			
      			long start = System.currentTimeMillis();
      			for(int i =0; i<10000;i++){
      				String query = "insert into Employee values ("+i+",'Name"+i+"')";
      				stmt.execute(query);
      			}
      			System.out.println("Time Taken="+(System.currentTimeMillis()-start));
      			
      		} catch (SQLException e) {
      			e.printStackTrace();
      		}finally{
      			try {
      				stmt.close();
      				con.close();
      			} catch (SQLException e) {
      				e.printStackTrace();
      			}
      		}
      	}
      
      }

      使用Statement一次执行一个查询。

      JDBCStatement.java

    2. Use PreparedStatement to execute one query at a time.

      JDBCPreparedStatement.java

      package com.journaldev.jdbc.batch;
      
      import java.sql.Connection;
      import java.sql.PreparedStatement;
      import java.sql.SQLException;
      
      public class JDBCPreparedStatement {
      
      	public static void main(String[] args) {
      		
      		Connection con = null;
      		PreparedStatement ps = null;
      		String query = "insert into Employee (empId, name) values (?,?)";
      		try {
      			con = DBConnection.getConnection();
      			ps = con.prepareStatement(query);
      			
      			long start = System.currentTimeMillis();
      			for(int i =0; i<10000;i++){
      				ps.setInt(1, i);
      				ps.setString(2, "Name"+i);
      				ps.executeUpdate();
      			}
      			System.out.println("Time Taken="+(System.currentTimeMillis()-start));
      			
      		} catch (SQLException e) {
      			e.printStackTrace();
      		}finally{
      			try {
      				ps.close();
      				con.close();
      			} catch (SQLException e) {
      				e.printStackTrace();
      			}
      		}
      	}
      
      }

      This approach is similar to using Statement but PreparedStatement provides performance benefits and avoids SQL injection attacks.

      JDBCPreparedStatement.java

      这种方法类似于使用Statement,但是PreparedStatement提供了性能优势并避免了SQL注入攻击。

    3. Using Statement Batch API for bulk processing.

      JDBCStatementBatch.java

      package com.journaldev.jdbc.batch;
      
      import java.sql.Connection;
      import java.sql.SQLException;
      import java.sql.Statement;
      
      public class JDBCStatementBatch {
      
      	public static void main(String[] args) {
      		
      		Connection con = null;
      		Statement stmt = null;
      		
      		try {
      			con = DBConnection.getConnection();
      			stmt = con.createStatement();
      			
      			long start = System.currentTimeMillis();
      			for(int i =0; i<10000;i++){
      				String query = "insert into Employee values ("+i+",'Name"+i+"')";
      				stmt.addBatch(query);
      				
      				//execute and commit batch of 1000 queries
      				if(i%1000 ==0) stmt.executeBatch();
      			}
      			//commit remaining queries in the batch
      			stmt.executeBatch();
      			
      			System.out.println("Time Taken="+(System.currentTimeMillis()-start));
      			
      		} catch (SQLException e) {
      			e.printStackTrace();
      		}finally{
      			try {
      				stmt.close();
      				con.close();
      			} catch (SQLException e) {
      				e.printStackTrace();
      			}
      		}
      	}
      
      }

      We are processing 10,000 records with a batch size of 1000 records. Once the batch size reaches, we are executing it and continue processing remaining queries.

      JDBCStatementBatch.java

      我们正在处理10,000条记录,批量大小为1000条记录。 达到批处理大小后,我们将执行它并继续处理剩余的查询。

    4. Using PreparedStatement Batch Processing API for bulk queries.

      JDBCPreparedStatementBatch.java

      package com.journaldev.jdbc.batch;
      
      import java.sql.Connection;
      import java.sql.PreparedStatement;
      import java.sql.SQLException;
      
      public class JDBCPreparedStatementBatch {
      
      	public static void main(String[] args) {
      		
      		Connection con = null;
      		PreparedStatement ps = null;
      		String query = "insert into Employee (empId, name) values (?,?)";
      		try {
      			con = DBConnection.getConnection();
      			ps = con.prepareStatement(query);
      			
      			long start = System.currentTimeMillis();
      			for(int i =0; i<10000;i++){
      				ps.setInt(1, i);
      				ps.setString(2, "Name"+i);
      				
      				ps.addBatch();
      				
      				if(i%1000 == 0) ps.executeBatch();
      			}
      			ps.executeBatch();
      			
      			System.out.println("Time Taken="+(System.currentTimeMillis()-start));
      			
      		} catch (SQLException e) {
      			e.printStackTrace();
      		}finally{
      			try {
      				ps.close();
      				con.close();
      			} catch (SQLException e) {
      				e.printStackTrace();
      			}
      		}
      	}
      
      }

      使用PreparedStatement批处理API进行批量查询。

      JDBCPreparedStatementBatch.java

    Let’s see how our programs work with MySQL database, I have executed them separately multiple times and below table contains the results.

    让我们看看我们的程序如何与MySQL数据库一起使用,我已经分别执行了多次,下表包含结果。

    MySQL DBStatementPreparedStatementStatement BatchPreparedStatement Batch
    Time Taken (ms)8256813071297019
    MySQL数据库 声明 准备声明 报表批处理 PreparedStatement批处理
    所需时间(毫秒) 8256 8130 7129 7019

    When I looked at the response time, I was not sure whether it’s right because I was expecting some good response time improvements with Batch Processing. So I looked online for some explanation and found out that by default MySQL batch processing works in a similar way like running without batch.

    当我查看响应时间时,我不确定是否正确,因为我期望批处理可以改善一些响应时间。 因此,我在网上寻找了一些解释,并发现默认情况下,MySQL批处理的工作方式类似于无批处理。

    To get the actual benefits of Batch Processing in MySQL, we need to pass rewriteBatchedStatements as TRUE while creating the DB connection. Look at the MySQL URL above in db.properties file for this.

    为了获得MySQL中批处理的实际好处,我们需要在创建数据库连接时将rewriteBatchedStatements传递为TRUE。 在db.properties文件中查看上面MySQL URL。

    With rewriteBatchedStatements as true, below table provides the response time for the same programs.

    rewriteBatchedStatementstrue ,下表提供了相同程序的响应时间。

    MySQL DBStatementPreparedStatementStatement BatchPreparedStatement Batch
    Time Taken (ms)567655703716394
    MySQL数据库 声明 准备声明 报表批处理 PreparedStatement批处理
    所需时间(毫秒) 5676 5570 3716 394

    As you can see that PreparedStatement Batch Processing is very fast when rewriteBatchedStatements is true. So if you have a lot of batch processing involved, you should use this feature for faster processing.

    如您所见,rewriteBatchedStatements为true时,PreparedStatement批处理非常快。 因此,如果涉及大量批处理,则应使用此功能来加快处理速度。

    Oracle批处理插入 (Oracle Batch Insert)

    When I executed above programs for Oracle database, the results were in line with MySQL processing results and PreparedStatement Batch processing was much faster than any other approach.

    当我针对Oracle数据库执行上述程序时,结果与MySQL处理结果一致,并且PreparedStatement Batch处理比任何其他方法都快得多。

    JDBC批处理异常 (JDBC Batch Processing Exceptions)

    Let’s see how batch programs behave in case one of the queries throw exceptions.

    让我们看看在查询之一抛出异常的情况下批处理程序的行为。

    JDBCBatchExceptions.java

    JDBCBatchExceptions.java

    package com.journaldev.jdbc.batch;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    import java.util.Arrays;
    
    public class JDBCBatchExceptions {
    
    	public static void main(String[] args) {
    		
    		Connection con = null;
    		PreparedStatement ps = null;
    		String query = "insert into Employee (empId, name) values (?,?)";
    		try {
    			con = DBConnection.getConnection();
    			
    			ps = con.prepareStatement(query);
    			
    			String name1 = "Pankaj";
    			String name2="Pankaj Kumar"; //longer than column length
    			String name3="Kumar";
    			
    			ps.setInt(1, 1);
    			ps.setString(2, name1);
    			ps.addBatch();
    			
    			ps.setInt(1, 2);
    			ps.setString(2, name2);
    			ps.addBatch();
    			
    			ps.setInt(1, 3);
    			ps.setString(2, name3);
    			ps.addBatch();
    			
    			int[] results = ps.executeBatch();
    			
    			System.out.println(Arrays.toString(results));
    			
    		} catch (SQLException e) {
    			e.printStackTrace();
    		}finally{
    			try {
    				ps.close();
    				con.close();
    			} catch (SQLException e) {
    				e.printStackTrace();
    			}
    		}
    	}
    
    }

    When I executed the above program for MySQL database, I got below exception and none of the records were inserted in the table.

    当我为MySQL数据库执行上述程序时,出现以下异常,并且没有任何记录插入表中。

    com.mysql.jdbc.MysqlDataTruncation: Data truncation: Data too long for column 'name' at row 2
    	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2939)
    	at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1623)
    	at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1715)
    	at com.mysql.jdbc.Connection.execSQL(Connection.java:3249)
    	at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1268)
    	at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1541)
    	at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1455)
    	at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1440)
    	at com.mysql.jdbc.PreparedStatement.executeBatchedInserts(PreparedStatement.java:1008)
    	at com.mysql.jdbc.PreparedStatement.executeBatch(PreparedStatement.java:908)
    	at com.journaldev.jdbc.batch.JDBCBatchExceptions.main(JDBCBatchExceptions.java:37)

    When executed the same program for Oracle database, I got below exception.

    当对Oracle数据库执行相同的程序时,出现以下异常。

    java.sql.BatchUpdateException: ORA-12899: value too large for column "SCOTT"."EMPLOYEE"."NAME" (actual: 12, maximum: 10)
    
    	at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:10070)
    	at oracle.jdbc.driver.OracleStatementWrapper.executeBatch(OracleStatementWrapper.java:213)
    	at com.journaldev.jdbc.batch.JDBCBatchExceptions.main(JDBCBatchExceptions.java:38)

    But the rows before exception were inserted into the database successfully. Although the exception clearly says what the error is but it doesn’t tell us which query is causing the issue. So either we validate the data before adding them for batch processing or we should use JDBC Transaction Management to make sure all or none of the records are getting inserted in case of exceptions.

    但是异常之前的行已成功插入数据库。 尽管该异常清楚地说明了错误是什么,但它并没有告诉我们哪个查询引起了该问题。 因此,要么在添加数据进行批处理之前验证数据,要么使用JDBC事务管理以确保在发生异常的情况下插入所有记录或不插入任何记录。

    Same program with JDBC transaction management looks like below.

    带有JDBC事务管理的相同程序如下所示。

    JDBCBatchExceptions.java

    JDBCBatchExceptions.java

    package com.journaldev.jdbc.batch;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    import java.util.Arrays;
    
    public class JDBCBatchExceptions {
    
    	public static void main(String[] args) {
    		
    		Connection con = null;
    		PreparedStatement ps = null;
    		String query = "insert into Employee (empId, name) values (?,?)";
    		try {
    			con = DBConnection.getConnection();
    			con.setAutoCommit(false);
    			
    			ps = con.prepareStatement(query);
    			
    			String name1 = "Pankaj";
    			String name2="Pankaj Kumar"; //longer than column length
    			String name3="Kumar";
    			
    			ps.setInt(1, 1);
    			ps.setString(2, name1);
    			ps.addBatch();
    			
    			ps.setInt(1, 2);
    			ps.setString(2, name2);
    			ps.addBatch();
    			
    			ps.setInt(1, 3);
    			ps.setString(2, name3);
    			ps.addBatch();
    			
    			int[] results = ps.executeBatch();
    			
    			con.commit();
    			System.out.println(Arrays.toString(results));
    			
    		} catch (SQLException e) {
    			e.printStackTrace();
    			try {
    				con.rollback();
    			} catch (SQLException e1) {
    				e1.printStackTrace();
    			}
    		}finally{
    			try {
    				ps.close();
    				con.close();
    			} catch (SQLException e) {
    				e.printStackTrace();
    			}
    		}
    	}
    
    }

    As you can see that I am rolling back the transaction if any SQL exception comes. If the batch processing is successful, I am explicitly committing the transaction.

    如您所见,如果出现任何SQL异常,我将回滚事务。 如果批处理成功,则我将明确提交事务。

    摘要 (Summary)

    That’s all for JDBC Batch insert update example, make sure to experiment with your data to get the optimal value of batch size for bulk queries. One of the limitations of JDBC batch processing is that we can’t execute different type of queries in the batch.

    这就是JDBC批处理插入更新示例的全部内容,请确保对您的数据进行试验以获得批量查询的最佳批处理大小值。 JDBC批处理的局限性之一是我们不能在批处理中执行不同类型的查询。

    GitHub Repository. GitHub Repository下载JDBC示例项目。

    翻译自: https://www.journaldev.com/2494/jdbc-batch-insert-update-mysql-oracle

    展开全文
  • JDBC批处理和事务

    2019-08-23 20:53:51
    JDBC批处理和事务 第一节 JDBC批处理 批量处理允许将相关的SQL语句分组到批处理中,并通过对数据库的一次调用提交它们。 当需要一次向数据库发送多个SQL语句时,可以减少连接数据库的开销,从而提高性能。 1.1 ...

    JDBC批处理和事务

    第一节 JDBC批处理

    批量处理允许将相关的SQL语句分组到批处理中,并通过对数据库的一次调用提交它们。

    当需要一次向数据库发送多个SQL语句时,可以减少连接数据库的开销,从而提高性能。

    1.1 Statement批处理

    以下是使用语句对象的批处理的典型步骤

    • 1 注册驱动获取连接
    • 2 使用*createStatement()*方法创建Statement对象。
    • 3 使用*setAutoCommit()*将auto-commit设置为false 。(可选)
    • 4 使用*addBatch()*方法在创建的语句对象上添加您喜欢的SQL语句到批处理中。
    • 5 在创建的语句对象上使用*executeBatch()*方法执行所有SQL语句。
    • 6 使用*commit()*方法提交所有更改。(可选)
    • 7 释放资源
    // Create statement object
    Statement stmt = conn.createStatement();
    
    // Set auto-commit to false
    conn.setAutoCommit(false);
    
    // Create SQL statement
    String SQL = "INSERT INTO Employees (id, first, last, age) " +
                 "VALUES(200,'Zia', 'Ali', 30)";
    // Add above SQL statement in the batch.
    stmt.addBatch(SQL);
    
    // Create one more SQL statement
    String SQL = "INSERT INTO Employees (id, first, last, age) " +
                 "VALUES(201,'Raj', 'Kumar', 35)";
    // Add above SQL statement in the batch.
    stmt.addBatch(SQL);
    
    // Create one more SQL statement
    String SQL = "UPDATE Employees SET age = 35 " +
                 "WHERE id = 100";
    // Add above SQL statement in the batch.
    stmt.addBatch(SQL);
    
    // Create an int[] to hold returned values
    int[] count = stmt.executeBatch();
    
    //Explicitly commit statements to apply changes
    conn.commit();
    
    1.2 PrepareStatement批处理
    1. 使用占位符创建SQL语句。
    2. 使用prepareStatement() 方法创建PrepareStatement对象。
    3. 使用*setAutoCommit()*将auto-commit设置为false 。(可选)
    4. 使用*addBatch()*方法在创建的语句对象上添加您喜欢的SQL语句到批处理中。
    5. 在创建的语句对象上使用*executeBatch()*方法执行所有SQL语句。
    6. 最后,使用*commit()*方法提交所有更改。(可选)
    // Create SQL statement
    String SQL = "INSERT INTO Employees (id, first, last, age) " +
                 "VALUES(?, ?, ?, ?)";
    
    // Create PrepareStatement object
    PreparedStatemen pstmt = conn.prepareStatement(SQL);
    
    //Set auto-commit to false
    conn.setAutoCommit(false);
    
    // Set the variables
    pstmt.setInt( 1, 400 );
    pstmt.setString( 2, "Pappu" );
    pstmt.setString( 3, "Singh" );
    pstmt.setInt( 4, 33 );
    // Add it to the batch
    pstmt.addBatch();
    
    // Set the variables
    pstmt.setInt( 1, 401 );
    pstmt.setString( 2, "Pawan" );
    pstmt.setString( 3, "Singh" );
    pstmt.setInt( 4, 31 );
    // Add it to the batch
    pstmt.addBatch();
    
    //add more batches
    
    //Create an int[] to hold returned values
    int[] count = stmt.executeBatch();
    
    //Explicitly commit statements to apply changes
    conn.commit();
    
    Statment批处理和PrepareStatment批处理区别:
    (1)Statment批处理可以添加不同Sql语句,而PrepareStatment只能添加一种sql语句
    (2)PrepareStatment效率比Statment高,而且更安全。
    

    第二节 JDBC操作二进制

    PreparedStatement对象可以使用输入和输出流来提供参数数据。这使您可以将整个文件放入可以保存大值的数据库列,例如Text和BLOB数据类型。

    有以下方法可用于流式传输数据 -

    • **setAsciiStream():**此方法用于提供大的ASCII值。
    • **setCharacterStream():**此方法用于提供大型UNICODE值。
    • **setBinaryStream():**此方法用于提供较大的二进制值。

    setXXXStream()方法除了参数占位符之外还需要额外的参数,文件大小。

    考虑我们要将XML文件XML_Data.xml上传到数据库表中。这是XML文件的内容 -

    <?xml version="1.0" encoding="UTF-8"?>
    <Employee>
      <id>100</id>
      <first></first>
      <last>无极</last>
      <Salary>10000</Salary>
      <Dob>18-08-1978</Dob>
    </Employee>
    
    // Import required packages
    import java.sql.*;
    import java.io.*;
    import java.util.*;
    
    public class JDBCExample {
       // JDBC driver name and database URL
       static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";  
       static final String DB_URL = "jdbc:mysql://localhost:3306/EMP";
    
       //  Database credentials
       static final String USER = "username";
       static final String PASS = "password";
       
       public static void main(String[] args) {
       Connection conn = null;
       PreparedStatement pstmt = null;
       Statement stmt = null;
       ResultSet rs = null;
       try{
          // Register JDBC driver
          Class.forName("com.mysql.jdbc.Driver");
          // Open a connection
          System.out.println("Connecting to database...");
          conn = DriverManager.getConnection(DB_URL,USER,PASS);
    
          //Create a Statement object and build table
          stmt = conn.createStatement();
          createXMLTable(stmt);
    
          //Open a FileInputStream
          File f = new File("XML_Data.xml");
          long fileLength = f.length();
          FileInputStream fis = new FileInputStream(f);
    
          //Create PreparedStatement and stream data
          String SQL = "INSERT INTO XML_Data VALUES (?,?)";
          pstmt = conn.prepareStatement(SQL);
          pstmt.setInt(1,100);
          pstmt.setAsciiStream(2,fis,(int)fileLength);
          pstmt.execute();
    
          //Close input stream
          fis.close();
    
          // Do a query to get the row
          SQL = "SELECT Data FROM XML_Data WHERE id=100";
          rs = stmt.executeQuery (SQL);
          // Get the first row
          if (rs.next ()){
             //Retrieve data from input stream
             InputStream xmlInputStream = rs.getAsciiStream (1);
             int c;
             ByteArrayOutputStream bos = new ByteArrayOutputStream();
             while (( c = xmlInputStream.read ()) != -1)
                bos.write(c);
             //Print results
             System.out.println(bos.toString());
          }
          // Clean-up environment
          rs.close();
          stmt.close();
          pstmt.close();
          conn.close();
       }catch(SQLException se){
          //Handle errors for JDBC
          se.printStackTrace();
       }catch(Exception e){
          //Handle errors for Class.forName
          e.printStackTrace();
       }finally{
          //finally block used to close resources
          try{
             if(stmt!=null)
                stmt.close();
          }catch(SQLException se2){
          }// nothing we can do
          try{
             if(pstmt!=null)
                pstmt.close();
          }catch(SQLException se2){
          }// nothing we can do
          try{
             if(conn!=null)
                conn.close();
          }catch(SQLException se){
             se.printStackTrace();
          }//end finally try
       }//end try
       System.out.println("Goodbye!");
    }//end main
    
    public static void createXMLTable(Statement stmt) 
       throws SQLException{
       System.out.println("Creating XML_Data table..." );
       //Create SQL Statement
       String streamingDataSql = "CREATE TABLE XML_Data " +
                                 "(id INTEGER, Data TEXT)";
       //Drop table first if it exists.
       try{
          stmt.executeUpdate("DROP TABLE IF EXISTS XML_Data");
          //Build table.
       	  stmt.executeUpdate(streamingDataSql);
       }catch(SQLException se){
       }// do nothing
      
    }//end createXMLTable
    }//end JDBCExample
    

    案例:把图片放入数据库

    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.InputStream;
    import java.lang.ProcessBuilder.Redirect;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    
    /**
     * 把图片放入数据库
     *
     */
    public class Demo4 {
    	public static void main(String[] args) throws Exception{
    		//write();
    		read();
    	}
    	public static void write() throws Exception{
    		Class.forName("com.mysql.jdbc.Driver");
    		String url="jdbc:mysql://localhost:3306/school";
    		Connection conn=DriverManager.getConnection(url, "root", "root");
    		PreparedStatement pstat=conn.prepareStatement("insert into bigdata2(id,img) values(?,?)");
    		FileInputStream fis=new FileInputStream("d:\\图片\\003.jpg");
    		pstat.setInt(1, 1);
    		pstat.setBinaryStream(2, fis);
    		int count=pstat.executeUpdate();
    		System.out.println(count);
    		pstat.close();
    		conn.close();
    	}
    	public static void read() throws Exception{
    		Class.forName("com.mysql.jdbc.Driver");
    		String url="jdbc:mysql://localhost:3306/school";
    		Connection conn=DriverManager.getConnection(url, "root", "root");
    		PreparedStatement pstat=conn.prepareStatement("select * from bigdata2 where id=1");
    	
    		ResultSet rs=pstat.executeQuery();
    		if(rs.next()) {
    			int id=rs.getInt("id");
    			System.out.println(id);
    			//处理图片
    			InputStream is=rs.getBinaryStream("img");
    			FileOutputStream fos=new FileOutputStream("d:\\haha.jpg");
    			byte[] buf=new byte[1024];
    			int len=0;
    			while((len=is.read(buf))!=-1) {
    				fos.write(buf,0,len);
    			}
    			fos.close();
    			is.close();
    			
    		}
    		rs.close();
    		pstat.close();
    		conn.close();
    		System.out.println("读取完成");
    	}
    }
    

    第三节 数据库事务

    3.1 事务概述

    ​ 一组要么同时执行成功,要么同时失败的SQL语句。是数据库操作的一个不能分割执行单元。

    ​ 数据库事务(Database Transaction) ,是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。 事务处理可以确保除非事务性单元内的所有操作都成功完成,否则不会永久更新面向数据的资源。通过将一组相关操作组合为一个要么全部成功要么全部失败的单元,可以简化错误恢复并使应用程序更加可靠。一个逻辑工作单元要成为事务,必须满足所谓的ACID(原子性、一致性、隔离性和持久性)属性。事务是数据库运行中的逻辑工作单位,由DBMS中的事务管理子系统负责事务的处理。

    事务开始于

    • 连接到数据库上,并执行一条DML语句insert、update或delete
    • 前一个事务结束后,又输入了另一条DML语句

    事务结束于

    • 执行commit或rollback语句。
    • 执行一条DDL语句,例如create table语句,在这种情况下,会自动执行commit语句。
    • 执行一条DDL语句,例如grant语句,在这种情况下,会自动执行commit。
    • 断开与数据库的连接
    • 执行了一条DML语句,该语句却失败了,在这种情况中,会为这个无效的DML语句执行rollback语句。
    3.2 事务的四大特点

    (ACID)

    • Atomicity(原子性)

    表示一个事务内的所有操作是一个整体,要么全部成功,要么全部失败

    • Consistency(一致性)

    表示一个事务内有一个操作失败时,所有的更改过的数据都必须回滚到修改前状态

    • Isolation(隔离性)

    事务查看数据时数据所处的状态,要么是另一并发事务修改它之前的状态,要么是另一事务修改它之后的状态,事务不会查看中间状态的数据。

    • Durability(持久性)

    持久性事务完成之后,它对于系统的影响是永久性的。

    案例演示

    
    CREATE TABLE account(
    	id INT PRIMARY KEY,
    	NAME VARCHAR(20) NOT NULL,
    	money DOUBLE(10,2)
    )
      
      
    public static void main(String[] args) {
    		Connection connection=null;
    		PreparedStatement pstat1=null;
    		PreparedStatement pstat2=null;
    		
    		//1注册驱动
    		try {
    			Class.forName("com.mysql.jdbc.Driver");
    			//2获取连接
    			connection=DriverManager.getConnection("jdbc:mysql://localhost:3306/school", "root", "root");
    			//3创建命令
    			//3.1开启事务 ,设置事务自动提交为false
    			connection.setAutoCommit(false);
    			pstat1=connection.prepareStatement("update account set money=money-1000 where name='张莎强'");
    			pstat1.executeUpdate();
    			//int c=10/0;
    			pstat2=connection.prepareStatement("update account set money=money+1000 where name='小苍'");
    			pstat2.executeUpdate();
    			
    			System.out.println("转账成功...");
    			//3.2提交事务
    			connection.commit();
    			
    		} catch (Exception e) {
    			System.out.println("出现异常");
    			try {
    				connection.rollback();//出现问题,要回滚(撤销事务做过的修改)
    				connection.commit();//可加也不不加
    			} catch (SQLException e1) {
    				// TODO Auto-generated catch block
    				e1.printStackTrace();
    			}
    		}finally {
    			if(pstat1!=null){
    				try {
    					pstat1.close();
    				} catch (SQLException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    			}
    			if(pstat2!=null){
    				try {
    					pstat2.close();
    				} catch (SQLException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    			}
    			if(connection!=null){
    				try {
    					connection.close();
    				} catch (SQLException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    			}
    		}
    	}
    

    Mysql支持的事务语句

    #开启事务
    START TRANSACTION;     # connection.setAutoCommit(false);
    UPDATE account SET money=money-1000 WHERE id=1;
    UPDATE account SET money=money+1000 WHERE id=2;
    #提交事务
    COMMIT;#connection.commit();
    #回滚
    ROLLBACK; #connection.rollback();
    
    3.3 事务隔离级别

    SQL标准定义了4类隔离级别,包括了一些具体规则,用来限定事务内外的哪些改变是可见的,哪些是不可见的。低级别的隔离级一般支持更高的并发处理,并拥有更低的系统开销。

    Read Uncommitted(读取未提交内容)

    ​ 在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少。读取未提交的数据,也被称之为脏读(Dirty Read)。

    Read Committed(读取提交内容)

    ​ 这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)。它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。这种隔离级别出现不可重复读(Nonrepeatable Read)问题,因为同一事务的其他实例在该实例处理其间可能会有新的commit,所以同一select可能返回不同结果。

    **Repeatable Read **可重读

    ​ 这是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。不过理论上,这会导致另一个棘手的问题:幻读(Phantom Read)。简单的说,幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻读” 行。InnoDB和Falcon存储引擎通过多版本并发控制(MVCC,Multiversion Concurrency Control)机制解决了该问题。

    Serializable 可串行化
    ​ 这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。效率最低的。

    ​ 这四种隔离级别采取不同的锁类型来实现,若读取的是同一个数据的话,就容易发生问题。

    例如:

    ​   脏读(Drity Read):某个事务已更新一份数据未提交前,另一个事务在此时读取了同一份数据,由于某些原因,前一个RollBack了操作,则后一个事务所读取的数据就会是不正确的。

    ​ 演示案例:

    #修改事务的隔离级别:
    SET [SESSION|GLOBAL] TRANSACTION ISOLATION LEVEL [READ UNCOMMITTED|READ COMMITTED|REPEATABLE READ|SERIALIZABLE]
    #查看事务隔离级别
    SELECT @@tx_isolation;
    
    

    ​   不可重复读(Non-repeatable read):在一个事务的两次查询之中数据不一致,这可能是两次查询过程中间插入了一个事务更新的原有的数据。

    ​ 演示案例:

    # A方 买 本伟
    SELECT @@tx_isolation;
    START TRANSACTION;
    UPDATE account SET money=money-2000 WHERE id=1;
    UPDATE account SET money=money+2000 WHERE id=2;
    COMMIT;
    ROLLBACK;
    
    START TRANSACTION;
    UPDATE account SET money=money+1000 WHERE id=2;
    COMMIT;
    
    
    
    
    
    # B方  卖  郑帅
    #(修改隔离级别)
    SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
    #查看隔离级别
    SELECT @@tx_isolation;
    SELECT *FROM account;
    #发货
    #修改隔离级别
    SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
    SELECT *FROM account;
    
    #不可重复读
    
    START TRANSACTION;
    	SELECT SUM(money) FROM account;
    	SELECT SUM(money) FROM account;
    	SELECT SUM(money) FROM account;
    COMMIT;	
    
    #再次修改隔离级别
    
    SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
    
    
    START TRANSACTION;
    	SELECT SUM(money) FROM account;
    	SELECT SUM(money) FROM account;
    	SELECT SUM(money) FROM account;
    COMMIT;	
    
    
    

    ​   幻读(Phantom Read):在一个事务的两次查询中数据笔数不一致,例如有一个事务查询了几列(Row)数据,而另一个事务却在此时插入了新的几列数据,先前的事务在接下来的查询中,就会发现有几列数据是它先前所没有的。但是InnoDB存储引擎通过多版本并发控制机制解决了该问题。

    3.4 JDBC中事务应用

    JDBC连接默认处于自动提交模式,则每个SQL语句在完成后都会提交到数据库。

    事务使您能够控制是否和何时更改应用于数据库。它将单个SQL语句或一组SQL语句视为一个逻辑单元,如果任何语句失败,则整个事务将失败。

    要启用手动事务支持,而不是JDBC驱动程序默认使用的自动提交模式,请使用Connection对象的**setAutoCommit()**方法。如果将boolean false传递给setAutoCommit(),则关闭自动提交。我们可以传递一个布尔值true来重新打开它。

    3.4.1 事务的提交和回滚

    完成更改后,我们要提交更改,然后在连接对象上调用**commit()**方法,如下所示:

    conn.commit( );
    

    否则,要使用连接名为conn的数据库回滚更新,请使用以下代码 -

    conn.rollback( );
    
    try{
       //开启事务
       conn.setAutoCommit(false);
       Statement stmt = conn.createStatement();
       
       String SQL = "INSERT INTO Employees  " +
                    "VALUES (106, 20, 'Rita', 'Tez')";
       stmt.executeUpdate(SQL);  
       //有可能出现异常
       String SQL = "INSERT IN Employees  " +
                    "VALUES (107, 22, 'Sita', 'Singh')";
       stmt.executeUpdate(SQL);
       // 没有错误提交
       conn.commit();
    }catch(SQLException se){
       //出现错误回滚
       conn.rollback();
       conn.commit();
    }
    
    3.4.2 Savepoint

    新的JDBC 3.0 Savepoint接口为您提供了额外的事务控制。

    设置保存点时,可以在事务中定义逻辑回滚点。如果通过保存点发生错误,则可以使用回滚方法来撤消所有更改或仅保存在保存点之后所做的更改。

    Connection对象有两种新的方法来帮助您管理保存点 -

    • **setSavepoint(String savepointName):**定义新的保存点。它还返回一个Savepoint对象。
    • **releaseSavepoint(Savepoint savepointName):**删除保存点。请注意,它需要一个Savepoint对象作为参数。此对象通常是由setSavepoint()方法生成的保存点。
    public static void main(String[] args) {
    		Connection conn = null;
    		Statement stmt = null;
    		Savepoint savepoint1 = null;
    		try {
    			Class.forName("com.mysql.jdbc.Driver");
    			conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/school", "root", "root");
    			// Assume a valid connection object conn
    			conn.setAutoCommit(false);
    			stmt = conn.createStatement();
    
    			// set a Savepoint
    			String SQL = "INSERT INTO Employees " + "VALUES (106, 20, 'Rita', 'Tez');";
    			stmt.executeUpdate(SQL);
    			savepoint1 = conn.setSavepoint("Savepoint1");
    			// Submit a malformed SQL statement that breaks
    			SQL = "INSERT IN Employees " + "VALUES (107, 22, 'Sita', 'Tez')";
    			stmt.executeUpdate(SQL);
    			// If there is no error, commit the changes.
    			conn.commit();
    			System.out.println("执行成功");
    
    		} catch (Exception se) {
    			// If there is any error.
    			try {
    				se.printStackTrace();
    				conn.rollback(savepoint1);
    				conn.commit();
    				System.out.println("回滚");
    			} catch (SQLException e) {
    				// TODO Auto-generated catch block
    				e.printStackTrace();
    			}
    		}
    	}
    
    展开全文
  • JDBC批处理

    2020-10-12 16:15:37
    JDBC批处理 说明: ​ 当需要成批插入或者更新记录时,可以采用Java的批量更新机制, 这一机制允许多条语句一次性提交给数据库批量处理。通常情况下比单独提交处理更有效率 批处理语句涉及的三个方法: addBatch...

    JDBC批处理

    说明:

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

    批处理语句涉及的三个方法:

    • addBatch(String):添加需要批量处理的SQL语句或是参数
    • executeBatch():执行批量处理语句
    • clearBatch():情况缓存的数据

    测试代码

    package com.imooc.jdbc.sample;
    
    import com.imooc.jdbc.goodapp.common.DBUtils;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    import java.util.Date;
    
    /**
     * @author CubeMonkey
     * @create 2020-10-12 13:03
     */
    public class BatchSample {
        private static void tc1(){
            Connection conn = null;
            PreparedStatement pstmt = null;
            try {
                long startTime = new Date().getTime();
                conn = DBUtils.getConnection();
                conn.setAutoCommit(false);//关闭自动提交
                String sql = "insert into employee(eno, ename, salary, dname) values(?, ?, ?, ?)";
                for (int i = 100000; i < 200000; i++){
    //                if (i == 1005){
    //                    throw new RuntimeException("插入失败");
    //                }
                    pstmt = conn.prepareStatement(sql);
                    pstmt.setInt(1, i);
                    pstmt.setString(2, "员工"+i);
                    pstmt.setFloat(3, 4000f);
                    pstmt.setString(4, "市场部");
                    pstmt.executeUpdate();
                }
                conn.commit();//提交数据
                long endTime = new Date().getTime();
                System.out.println("tc1()执行时长:"+(endTime-startTime));
            } catch (Exception e) {
                e.printStackTrace();
                try {
                    if (conn != null && conn.isClosed() == false){
                        conn.rollback();//回滚数据
                    }
                } catch (SQLException ex) {
                    ex.printStackTrace();
                }
            } finally {
                DBUtils.closeConnection(null, pstmt, conn);
            }
        }
        //使用批处理若干数据
        private static void tc2(){
            Connection conn = null;
            PreparedStatement pstmt = null;
            try {
                long startTime = new Date().getTime();
                conn = DBUtils.getConnection();
                conn.setAutoCommit(false);//关闭自动提交
                String sql = "insert into employee(eno, ename, salary, dname) values(?, ?, ?, ?)";
                pstmt = conn.prepareStatement(sql);
                for (int i = 200000; i < 300000; i++){
                    pstmt.setInt(1, i);
                    pstmt.setString(2, "员工"+i);
                    pstmt.setFloat(3, 4000f);
                    pstmt.setString(4, "市场部");
    //                pstmt.executeUpdate();
                    pstmt.addBatch();//将参数加入批处理任务
                }
                pstmt.executeBatch();//执行批处理任务
                conn.commit();//提交数据
                long endTime = new Date().getTime();
                System.out.println("tc2()执行时长:"+(endTime-startTime));
            } catch (Exception e) {
                e.printStackTrace();
                try {
                    if (conn != null && conn.isClosed() == false){
                        conn.rollback();//回滚数据
                    }
                } catch (SQLException ex) {
                    ex.printStackTrace();
                }
            } finally {
                DBUtils.closeConnection(null, pstmt, conn);
            }
        }
        public static void main(String[] args) {
            tc1();
            tc2();
        }
    }
    
    

    测试结果:

    在这里插入图片描述

    展开全文
  • JDBC批处理实践

    2018-06-09 13:11:41
     String url = "jdbc:mysql://59.110.237.95:3306/xxbd?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior\\=convertToNull" + "&rewriteBatchedStatements=true";  String user = "xxx";  String ...
  • 任何人都可以告诉我我做错了什么我在mysql中执行350个插件并且它需要40秒.这是代码long t0 = System.currentTimeMillis();Connection con = connectionProvider.getConnection();PreparedStatement s = con.prepare...
  • 各种jdbc批处理效率比较

    千次阅读 2019-03-15 11:01:50
    花了一天的时间试验了一下各种jdbc批处理,一共测试了4种10万条数据本地mysql插入: 1.原装jdbc PreparedStatement addBatch();耗时(7.7秒) 2.原装jdbc Statement addBatch(sql); 耗时(9.2秒) 3.原装...
  • JDBC 批处理

    2018-04-23 10:30:55
    )[-]使用Statement完成批处理使用Statement完成批处理范例采用StatementaddBatchsql方式实现批处理的优缺点使用PreparedStatement完成批处理使用PreparedStatement完成批处理范例采用PreparedStatementaddBatch方式...
  • JDBC批处理与事务处理

    2018-10-19 20:47:36
    一、JDBC批处理  原始数据库信息 --addBatch();向PreparedStatement的对象中添加一组参数 --clearParameters();立即清除当前的参数(interface :PreparedStatementz中的方法) --clearBatch();清除Statement...
  • Java的JDBC批处理

    2021-04-08 09:28:02
    代码示例:import java.sql.*;public class preparedAdd {public static void main(String[] args)throws Exception {//第一个例子:Connection con=null;...new com.mysql.jdbc.Driver();con=DriverMa...
  • JDBC批处理Select语句

    2016-05-10 15:50:08
    JDBC批处理Select语句注:为了更好理解本文,请结合原文阅读 在网络上开销最昂贵的资源就是客户端与服务器往返的请求与响应,JDBC中类似的一种情况就是对数据库的调用,如果你在做数据插入、更新、删除操作,你可以...
  • JDBC 批处理语句

    2021-12-07 14:06:49
    JDBC 批处理 批处理允许将相关的SQL语句分组到批处理中,并通过对数据库的一次调用提交它们。 当一次访问数据库可以提交多个SQL 语句的时候,能够很大程度减轻连接数据库的开销,从而提高性能。 那么如何实现使用...
  • 今天学习的Java JDBC批处理插入数据操作,我们将看到我们如何可以使用像Statement和PreparedStatement JDBC API来批量在任何数据库中插入数据。此外,我们将努力探索一些场景,如在内存不足时正常运行,以及如何优化...
  • jdbc 批处理

    2017-08-01 17:30:50
    踩过的一些小坑,避免以后再犯……1.addBatch() 批处理只能操作insert 、delete、update等语句,无法对select 查询语句进行 批处理2.使用preparedstatement对sql语句进行预编译时,可以把sql的参数写成?,如:...
  • 让我们看看如何使用JDBC API在Java中执行批量插入。虽然你可能已经知道,但我会尽力解释基础到复杂的场景。 在此笔记里,我们将看到我们如何可以使用像Statement和PreparedStatement JDBC API来批量在任何数据库中...
  • JDBC批处理操作

    2021-02-27 21:54:59
    JDBC的批处理操作1 什么是JDBC批处理JDBC批处理,意思是我们可以执行一批(组)SQL操作。批处理可以使数据库执行性能更快。java.sql.Statement和java.sql.PreparedStatement接口都提供了用于批处理的方法。2 JDBC...
  • 每次执行程序时,我正在执行一个JDBC批处理插入(每次插入1000行).但是我无法正确处理某些记录抛出的异常.假设1000个记录中的第100条记录是由于数据无效或某个值的大小超过列大小而引起的异常.一旦发生异常,剩余的记录...
  • Jdbc 批处理

    2015-09-26 13:29:49
    package Batch; import java.io.IOException; import java.sql.Connection;...试了一下一条一条插和使用批处理的时间,一条一条等了三分多钟还没插完所以直接终止了,批处理用了1.72s 。。一秒多
  • jdbc批处理原理分析

    2016-07-07 16:39:59
    需要向数据库发送多条sql语句时, 为了提升执行效率, 可以考虑采用JDBC批处理机制. JDBC批处理机制主要涉及Statement或PreparedStatement对象的以下方法: |--addBatch(String sql) :Statement类的方法, 多...
  • jdbc 批处理.rar

    2019-07-26 08:52:31
    NULL 博文链接:https://j2ee2009.iteye.com/blog/660826
  • @Test public void testInsert() { Connection con = null; PreparedStatement ps = null; try { con = GetConnection(); String sql = "insert into goods(name) value(?)"; ps = con.prepareStatement(sql);...
  • 开启mysqljdbc批处理

    2021-06-26 23:23:59
    在url后加参数设置 ?rewriteBatchedStatements=true

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 26,112
精华内容 10,444
关键字:

jdbc批处理

友情链接: 插入损失.rar