SQL大数据
目标:把mp3保存到数据库中!
在my.ini中添加如下配置!
max_allowed_packet=10485760
BLOB (binary large object): 二进制大对象–>字节数据大对象
CLOB(chractor large object): 字符数据大对象
1.什么是SQL当中的大数据
所谓SQL当中的大数据,就是大的字节数据,或大的字符数据。
标准SQL中提供了如下类型来保存大数据类型:
类型 | 长度 |
---|---|
tinyblob | 28–1B(256B) |
blob | 216-1B(64K) |
mediumblob | 224-1B(16M) |
longblob | 232-1B(4G) |
tinyclob | 28–1B(256B) |
clob | 216-1B(64K) |
mediumclob | 224-1B(16M) |
longclob | 232-1B(4G) |
但是,在mysql中没有提供tinyclob、clob、mediumclob、longclob
四种类型,
mysql当中没有字符数据大对象,只有字节数据大对象
字符数据对象主要用来处理文本,字节数据对象可以用来处理一切形式的数据。
在mysql当中用来处理文本的大数据对象是下面的格式
使用如下四种类型来处理文本大数据:
类型 | 长度 |
---|---|
tinytext | 28–1B(256B) |
text | 216-1B(64K) |
mediumtext | 224-1B(16M) |
longtext | 232-1B(4G) |
首先我们需要创建一张表,
表中要有一个mediumblob(16M)类型的字段。
create table tab_bin(
id int primary key auto_increment,
filename varchar(100),
data mediumblob
);
向数据库插入二进制数据需要使用PreparedStatement
对象的setBinaryStream(int, InputSteam)
方法来完成。
con = JdbcUtils.getConnection();
String sql = "insert into tab_bin(filename,data) values(?, ?)";
pstmt = con.prepareStatement(sql);
pstmt.setString(1, "a.jpg");
InputStream in = new FileInputStream("f:\\a.jpg");
pstmt.setBinaryStream(2, in);
pstmt.executeUpdate();
读取二进制数据,
需要在查询后使用ResultSet类
的getBinaryStream()
方法来获取输入流对象。
也就是说,
PreparedStatement
有setXXX()
,
那么ResultSet
就有getXXX()
。
con = JdbcUtils.getConnection();
String sql = "select filename,data from tab_bin where id=?";
pstmt = con.prepareStatement(sql);
pstmt.setInt(1, 1);
rs = pstmt.executeQuery();
rs.next();
String filename = rs.getString("filename");
OutputStream out = new FileOutputStream("F:\\" + filename);
InputStream in = rs.getBinaryStream("data");
IOUtils.copy(in, out);
out.close();
还有一种方法,
就是把要存储的数据包装成Blob类型,
然后调用PreparedStatement的setBlob()方法来设置数据
con = JdbcUtils.getConnection();
String sql = "insert into tab_bin(filename,data) values(?, ?)";
pstmt = con.prepareStatement(sql);
pstmt.setString(1, "a.jpg");
File file = new File("f:\\a.jpg");
byte[] datas = FileUtils.getBytes(file);//获取文件中的数据
Blob blob = new SerialBlob(datas);//创建Blob对象
pstmt.setBlob(2, blob);//设置Blob类型的参数
pstmt.executeUpdate();
con = JdbcUtils.getConnection();
String sql = "select filename,data from tab_bin where id=?";
pstmt = con.prepareStatement(sql);
pstmt.setInt(1, 1);
rs = pstmt.executeQuery();
rs.next();
String filename = rs.getString("filename");
File file = new File("F:\\" + filename) ;
Blob blob = rs.getBlob("data");
byte[] datas = blob.getBytes(0, (int)file.length());
FileUtils.writeByteArrayToFile(file, datas);
☆ 批处理
1-Statement批处理
批处理就是一批一批的处理,而不是一个一个的处理!
当你有10条SQL语句要执行时,一次向服务器发送一条SQL语句,
这么做效率上很差!处理的方案是使用批处理,
即一次向服务器发送多条SQL语句,然后由服务器一次性处理。
批处理只针对更新(增、删、改)语句,
批处理没有查询什么事儿!
可以多次调用Statement类
的addBatch(String sql)
方法,
把需要执行的所有SQL语句添加到一个“批”中,
然后调用Statement类
的executeBatch()方法
来执行当前“批”中的语句。
void addBatch(String sql)
:添加一条语句到“批”中;int[] executeBatch()
:执行“批”中所有语句。返回值表示每条语句所影响的行数据;void clearBatch()
:清空“批”中的所有语句。
for(int i = 0; i < 10; i++) {
String number = "S_10" + i;
String name = "stu" + i;
int age = 20 + i;
String gender = i % 2 == 0 ? "male" : "female";
String sql = "insert into stu values('" + number + "', '" + name + "', " + age + ", '" + gender + "')";
stmt.addBatch(sql);
}
stmt.executeBatch();
当执行了“批”之后,
“批”中的SQL语句就会被清空!
也就是说,连续两次调用executeBatch()相当于调用一次!
因为第二次调用时,“批”中已经没有SQL语句了。
还可以在执行“批”之前,调用Statement的clearBatch()方法来清空“批”!
2-PreparedStatement批处理
PreparedStatement
的批处理有所不同,
因为每个PreparedStatement对象都绑定一条SQL模板。
所以向PreparedStatement中添加的不是SQL语句,
而是给“?”赋值。
con = JdbcUtils.getConnection();
String sql = "insert into stu values(?,?,?,?)";
pstmt = con.prepareStatement(sql);
for(int i = 0; i < 10; i++) {
pstmt.setString(1, "S_10" + i);
pstmt.setString(2, "stu" + i);
pstmt.setInt(3, 20 + i);
pstmt.setString(4, i % 2 == 0 ? "male" : "female");
pstmt.addBatch();
}
pstmt.executeBatch();