一、JDBC操作BLOB类型字段
(一)MySQL的BLOB类型
-
MySQL中,BLOB是一个二进制大型对象,是一个可以存储大量数据的容器,它能容纳不同大小的数据。
-
插入BLOB类型的数据必须使用PreparedStatement,不能使用Statement,因为BLOB类型的数据无法使用字符串拼接写的。
-
MySQL的四种BLOB类型(除了在存储的最大信息量上不同外,他们是等同的)

- 实际使用中根据需要存入的数据大小定义不同的BLOB类型。
- 需要注意的是:如果存储的文件过大,数据库的性能会下降。
- 如果在指定了相关的Blob类型以后,且文件没超过最大范围,还报错:
Packet for query is too large,那么我们需要在mysql的安装目录下,找到my.ini文件加上如下的配置参数:max_allowed_packet=16M。同时注意:修改了my.ini文件之后,需要重新启动mysql服务。
(二)向数据表中插入Blob类型数据
案例:
import com.fox.util.JDBCUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
public class BlobTest1 {
public static void main(String[] args){
Connection connection = null;
PreparedStatement ps = null;
FileInputStream fis =null;
try {
connection = JDBCUtils.getConnection();
String sql="insert into customers(name,email,birth,photo) values(?,?,?,?)";
ps = connection.prepareStatement(sql);
ps.setString(1,"彭于晏");
ps.setString(2,"pengyuyan@qq.com");
ps.setString(3,"1992-02-02");//会隐式转化为Date类型
fis = new FileInputStream(new File("D:/test/pyy.jpg"));
ps.setBlob(4,fis);//该方法需要传入一个InputStream对象
ps.execute();
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.closeResource(connection,ps);
if(fis!=null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
(三)修改数据表中Blob类型的字段
案例:
import com.fox.util.JDBCUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
public class BlobTest2 {
public static void main(String[] args) {
Connection connection = null;
PreparedStatement ps = null;
FileInputStream fis = null;
try {
connection = JDBCUtils.getConnection();
String sql="update customers set photo=? where id=?";
ps = connection.prepareStatement(sql);
fis = new FileInputStream(new File("D:/test/pengyuyan.jpg"));
ps.setBlob(1,fis);
ps.setInt(2,22);
ps.execute();
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.closeResource(connection,ps);
if(fis!=null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
(四)查询数据表中Blob类型的字段
java.sql.Blob接口中有一个方法:
InputStream getBinaryStream() 将此 Blob实例指定的BLOB值作为流 Blob 。
import com.fox.bean.Customer;
import com.fox.util.JDBCUtils;
import java.io.*;
import java.sql.*;
public class BlobTest3 {
public static void main(String[] args) {
Connection connection = null;
PreparedStatement ps = null;
InputStream is =null;
FileOutputStream fos =null;
ResultSet rs =null;
try {
connection = JDBCUtils.getConnection();
String sql="select id,name,email,birth,photo from customers where name=?";
ps = connection.prepareStatement(sql);
ps.setString(1,"彭于晏");
rs = ps.executeQuery();
if(rs.next()){
//方式一:
//int id = rs.getInt(1);
//String name = rs.getString(2);
//String email = rs.getString(3);
//Date birth = rs.getDate(4);
//方式二:(推荐)
int id = rs.getInt("id");
String name = rs.getString("name");
String email = rs.getString("email");
Date birth = rs.getDate("birth");
Customer customer = new Customer(id, name, email, birth);
System.out.println(customer);
//将Blob类型的字段下载下来,以文件的方式保存在本地
Blob photo = rs.getBlob("photo");
is = photo.getBinaryStream();
fos = new FileOutputStream("pengyuyan.jpg");
byte[] buffer=new byte[1024];
int len=0;
while((len=is.read(buffer))!=-1){
fos.write(buffer,0,len);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.closeResource(connection,ps,rs);
if(fos!=null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(is!=null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
二、批量插入
(一)批量执行SQL语句
当需要成批插入或者更新记录时,可以采用Java的批量更新机制,这一机制允许多条语句一次性提交给数据库批量处理。通常情况下比单独提交处理更有效率
JDBC的批量处理语句包括下面三个方法:
(方法在java.sql.Statement及其子接口中)
void addBatch(String):添加需要批量处理的SQL语句或是参数;int[] executeBatch():执行批量处理语句;void clearBatch():清空缓存的数据
通常我们会遇到两种批量执行SQL语句的情况:
- 多条SQL语句的批量处理;
- 一个SQL语句的批量传参;
update、delete本身就具有批量操作的效果。此时的批量操作,主要指的是批量插入。
(二)高效的批量插入
案例:向数据表中插入100000条数据
首先,数据库中提供一个goods表。创建如下:
CREATE TABLE goods(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(20)
);
1.实现层次一:使用Statement
import com.fox.util.JDBCUtils;
import java.sql.Connection;
import java.sql.Statement;
public class InsertTest1 {
public static void main(String[] args) {
Connection connection = null;
Statement statement = null;
try {
long start = System.currentTimeMillis();
connection = JDBCUtils.getConnection();
statement = connection.createStatement();
for (int i = 0; i < 20000; i++) {
String sql="insert into goods(name) values('name_"+i+"')";
statement.executeUpdate(sql);
}
long end = System.currentTimeMillis();
System.out.println("批量插入耗时:"+(end-start)/1000+"秒");
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.closeResource(connection,statement);
}
}
}

效率太低了,在实际的开发中通常都不会使用Statement
2.实现层次二:使用PreparedStatement
import com.fox.util.JDBCUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
public class InsertTest2 {
public static void main(String[] args) {
Connection connection = null;
PreparedStatement ps = null;
try {
long start = System.currentTimeMillis();
connection = JDBCUtils.getConnection();
String sql="insert into goods(name) values(?)";
ps = connection.prepareStatement(sql);
for (int i = 0; i < 20000; i++) {
ps.setString(1,"name_"+i);
ps.executeUpdate();
}
long end = System.currentTimeMillis();
System.out.println("批量插入耗时:"+(end-start)/1000+"秒");
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.closeResource(connection,ps);
}
}
}

可以看到,使用PreparedStatement比使用Statement做批量插入耗时少一点。使用PreparedStatement的性能一定是更高的,因为使用Statement,每一次插入都需要编译一次sql语句,而每次编译都需要进行语法检查,语义检查,翻译成二进制命令,缓存等等,性能低;使用PreparedStatement就能够实现sql语句预编译,只编译一次,每一次插入只需要填充占位符就好。
3.实现层次三:使用批处理
使用批处理即使用 addBatch() 、executeBatch() 、clearBatch()
注意:
-
MySQL服务器默认是关闭批处理的,我们需要通过一个参数,让mysql开启批处理的支持。
rewriteBatchedStatements=true写在配置文件的url后面

-
如果写完参数还是不能使用批处理,是因为MySQL驱动太老了,需要下载新一点的驱动。部分老的MySQL驱动不支持批处理比如mysql-connector-java-5.1.7 ,这里我使用的驱动是mysql-connector-java-5.1.37。
import com.fox.util.JDBCUtils;
import java.sql.Connection;

本文详细介绍了JDBC操作BLOB类型字段的方法,包括插入、修改和查询。接着探讨了批量插入的高效实现,包括使用Statement、PreparedStatement和批处理。接着,深入讲解了JDBC处理数据库事务,包括事务的ACID属性和事务处理方法。最后,讨论了数据库连接池技术,如C3P0、DBCP和Druid,并介绍了Apache-DBUtils工具类在CRUD操作中的应用。
JDBC操作Blob类型字段高效的批量插入JDBC处理数据库事务将多个SQL看成一个事务执行数据库连接池C3P0DBCPDruidDBUtils工具类实现CRUD&spm=1001.2101.3001.5002&articleId=116984875&d=1&t=3&u=be5825b6f3174f43a0904a32b84b9fe3)
274

被折叠的 条评论
为什么被折叠?



