批量处理JDBC语句提高处理速度
当需要成批插入或者更新记录时。可以采用Java的批量更新机制,这一机制允许多条语句一次性提交给数据库批量处理。通常情况下比单独提交处理更有效率
JDBC的批量处理语句包括下面两个方法:
addBatch(String):添加需要批量处理的SQL语句或是参数;
executeBatch();执行批量处理语句;
通常我们会遇到两种批量执行SQL语句的情况:
用Statement实现批量处理;
用PreparedStatement实现批量处理
/**
* 用Statement批量保存5000条记录 mysql statement batch time=3047 oracle statement
* batch time=2453
*/
@Test
public void testStatementBatch() {
Connection conn = null;
Statement stmt = null;
long time = System.currentTimeMillis();
conn = OracleJDBCUtils.getConnection();
try {
stmt = conn.createStatement();
for (int i = 0; i < 5000; i++) {
String sql = "INSERT INTO b_user(id,NAME,PASSWORD,age) VALUES(1,'t','t',1)";
stmt.addBatch(sql);
}
stmt.executeBatch();
System.out.println("mysql statement batch time=" + (System.currentTimeMillis() - time));
} catch (SQLException e) {
e.printStackTrace();
} finally {
OracleJDBCUtils.closeResource(conn, stmt, null);
}
}
/**
* 用PreparedStatement批量保存5000条记录
* mysql preparedstatement batch time=3094
* 5000
* oracle preparedstatement batch time=265 oracle preparedstatement
* batch time=422 50000
* oracle preparedstatement batch time=2187
*/
@Test
public void testPreparedStatementBatch() {
Connection conn = null;
PreparedStatement pstmt = null;
long time = System.currentTimeMillis();
conn = OracleJDBCUtils.getConnection();
String sql = "INSERT INTO b_user(id,NAME,PASSWORD,age) VALUES(?,?,?,?)";
try {
pstmt = conn.prepareStatement(sql);
for (int i = 0; i < 500000; i++) {
pstmt.setInt(1, 1);
pstmt.setString(2, "t");
pstmt.setString(3, "t");
pstmt.setInt(4, 1);
pstmt.addBatch();//这里一定不能传sql字符串
if (i % 50000 == 0) {
pstmt.executeBatch();
pstmt.clearBatch();
}
}
pstmt.executeBatch();
System.out.println("oracle preparedstatement batch time="
+ (System.currentTimeMillis() - time));
} catch (SQLException e) {
e.printStackTrace();
} finally {
OracleJDBCUtils.closeResource(conn, pstmt, null);
}
}
MySQLBLOB 类型介绍
大对象操作 :
MySQL中,BLOB是一个二进制大型对象,是一个可以存储大量数据的容器,它能容纳不同大小的数据。BLOB类型实际是个类型系列( TinyBlob、Blob、MediumBlob和LongBlob ),除了在存储的最大信息量上不同外,他们是等同的。
MySQL的四种BLOB类型
l 实际使用中根据需要存入的数据大小定义不同的 BLOB 类型。需要注意的是:
MySQL的四种BLOB类型
l 实际使用中根据需要存入的数据大小定义不同的 BLOB 类型。需要注意的是:
如果你存储的文件过大,数据库的性能会下降很多。
l
l
有
4
种
TEXT
类型:
TINYTEXT
、
TEXT
、
MEDIUMTEXT
和
LONGTEXT
。这些对应
4
种
BLOB
类型,有相同的最大长度和存储需求
package com.jiangyi.testblob;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.junit.Test;
import com.sun.corba.se.spi.orbutil.fsm.Input;
public class TestBlob {
private static final String URL = "jdbc:mysql://localhost:3306/t";
private static final String USER = "root";
private static final String PASSWORD = "";
static {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/*
*
* 保存带图片的数据
*/
@Test
public void save() {
Connection conn = null;
String sql = "insert into t(name,headimage) values ('tom',?)";
PreparedStatement pstmt = null;
try {
conn = DriverManager.getConnection(URL, USER, PASSWORD);
pstmt = conn.prepareStatement(sql);
InputStream in = new FileInputStream(
"D:/allworkspace/xxxx/day14_jdbc/src/com/jiangyi/testblob/mm.jpg");
// 虽然jdbc定义里所有的方法 但是mysql并没有真正实现所有的犯法
pstmt.setBinaryStream(1, in, in.available());
// pstmt.setBlob(2,in,in.available());//没有实现 无法使用
pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
pstmt.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
/*
*
* 读取带图片的数据
*/
@Test
public void read() {
Connection conn = null;
String sql = "select * from t where id=1";
PreparedStatement pstmt = null;
ResultSet rs=null;
try {
conn = DriverManager.getConnection(URL, USER, PASSWORD);
pstmt = conn.prepareStatement(sql);
rs= pstmt.executeQuery();
while(rs.next()){
Blob blob=rs.getBlob(4);
InputStream in=blob.getBinaryStream();
String path="D:/allworkspace/xxxx/day14_jdbc/src/com/jiangyi/testblob/new.jpg";
OutputStream out=new FileOutputStream(path);
byte[] buffer = new byte[1024];
int len = -1;
while((len=in.read(buffer))!=-1) {
out.write(buffer, 0, len);
}
out.flush();
out.close();
in.close();
}
} catch (SQLException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
rs.close();
pstmt.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
使用JDBC驱动程序处理元数据
元数据(MetaData):是关于数据的数据,也就是对数据的定义和描述
JDBC中定义了2个元数据类型
DataBaseMetaData:
数据库的相关信息,表的相关信息等等
通过Connection对象得到此类型的对象
ResultSetMetaData:
结果集中列的数量,类型和属性等信息
通过ResultSet对象得到
JDBC中定义了2个元数据类型
DataBaseMetaData:
数据库的相关信息,表的相关信息等等
通过Connection对象得到此类型的对象
ResultSetMetaData:
结果集中列的数量,类型和属性等信息
通过ResultSet对象得到
DatabaseMetaData 类中提供了许多方法用于获得数据源的各种信息,通过这些方法可以非常详细的了解数据库的信息:
getURL():返回一个String类对象,代表数据库的URL。
getUserName():返回连接当前数据库管理系统的用户名。
isReadOnly():返回一个boolean值,指示数据库是否只允许读操作。
getDatabaseProductName():返回数据库的产品名称。
getDatabaseProductVersion():返回数据库的版本号。
getDriverName():返回驱动驱动程序的名称。
getDriverVersion():返回驱动程序的版本号。
getURL():返回一个String类对象,代表数据库的URL。
getUserName():返回连接当前数据库管理系统的用户名。
isReadOnly():返回一个boolean值,指示数据库是否只允许读操作。
getDatabaseProductName():返回数据库的产品名称。
getDatabaseProductVersion():返回数据库的版本号。
getDriverName():返回驱动驱动程序的名称。
getDriverVersion():返回驱动程序的版本号。
获取结果集的元数据
可用于获取关于 ResultSet 对象中列的类型和属性信息的对象:
getColumnName(int column):获取指定列的名称
getColumnCount():返回当前 ResultSet 对象中的列数。
getColumnTypeName(int column):检索指定列的数据库特定的类型名称。
getColumnDisplaySize(int column):指示指定列的最大标准宽度,以字符为单位。
isNullable(int column):指示指定列中的值是否可以为 null。
isAutoIncrement(int column):指示是否自动为指定列进行编号,这样这些列仍然是只读的。
getColumnName(int column):获取指定列的名称
getColumnCount():返回当前 ResultSet 对象中的列数。
getColumnTypeName(int column):检索指定列的数据库特定的类型名称。
getColumnDisplaySize(int column):指示指定列的最大标准宽度,以字符为单位。
isNullable(int column):指示指定列中的值是否可以为 null。
isAutoIncrement(int column):指示是否自动为指定列进行编号,这样这些列仍然是只读的。
用于获取关于 ResultSet 对象中列的类型和属性信息的对象
ResultSet rs = stmt.executeQuery("select * from students");
//可用于获取关于 ResultSet 对象中列的类型和属性信息的对象
//获取此 ResultSet 对象的列的编号、类型和属性。
ResultSetMetaData rsmd = rs.getMetaData();
System.out.println("有"+rsmd.getColumnCount()+"字段");
System.out.println("第1个字段名称是:"+rsmd.getColumnName(1));
ResultSet rs = stmt.executeQuery("select * from students");
//可用于获取关于 ResultSet 对象中列的类型和属性信息的对象
//获取此 ResultSet 对象的列的编号、类型和属性。
ResultSetMetaData rsmd = rs.getMetaData();
System.out.println("有"+rsmd.getColumnCount()+"字段");
System.out.println("第1个字段名称是:"+rsmd.getColumnName(1));