MySQL中,BLOB是一个二进制大型对象,是一个可以存储大量数据的容器,它能容纳不同大小的数据。
插入BLOB类型的数据必须使用PreparedStatement,因为BLOB类型的数据无法使用字符串拼接写的。
MySQL的四种BLOB类型(除了在存储的最大信息量上不同外,他们是等同的)
实际使用中根据需要存入的数据大小定义不同的BLOB类型。
需要注意的是:如果存储的文件过大,数据库的性能会下降。
如果在指定了相关的Blob类型以后,还报错:xxx too large,那么在mysql的安装目录下,找my.ini文件加上如下的配置参数: max_allowed_packet=16M 。同时注意:修改了my.ini文件之后,需要重新启动mysql服务
其中的配置信息和上次使用的一样
@Test public void testInsert() throws Exception { Connection conn = JDBCUtils.getConnection(); String sql = "insert into customers(name,email,birth,photo)values(?,?,?,?)"; PreparedStatement ps = conn.prepareStatement(sql); ps.setObject(1, "冯宝宝"); ps.setObject(2, "[email protected]"); ps.setObject(3, "1000-10-10"); // 图片 FileInputStream is = new FileInputStream(new File("timg.jpg")); ps.setBlob(4, is); // 执行 ps.execute(); JDBCUtils.closeResource(conn, ps); }
Connection conn = JDBCUtils.getConnection(); String sql = "update customers set photo = ? where id = ?"; PreparedStatement ps = conn.prepareStatement(sql); // 填充占位符 // 操作Blob类型的变量 FileInputStream fis = new FileInputStream("coffee.png"); ps.setBlob(1, fis); ps.setInt(2, 25); ps.execute(); fis.close(); JDBCUtils.closeResource(conn, ps);
@Test public void testQuery() { Connection conn = null; PreparedStatement ps = null; InputStream is = null; FileOutputStream fos = null; ResultSet rs = null; try { conn = JDBCUtils.getConnection(); String sql = "select id , name , email , birth , photo from customers where id = ?"; ps = conn.prepareStatement(sql); ps.setObject(1, 19); // 有结果集 rs = ps.executeQuery(); if(rs.next()) { int id = rs.getInt("id"); String name = rs.getString("name"); String email = rs.getString("email"); Date birth = rs.getDate("birth"); Customer cust = new Customer(id , name , email , birth); System.out.println(cust); // 将Blob字段下载下来,保存到本地,除了调用了getBinaryStream()方法,剩下的和二进制流差不多 Blob photo = rs.getBlob("photo"); is = photo.getBinaryStream(); fos = new FileOutputStream("lin.jpg"); byte[] buffer = new byte[1024]; int len; while((len = is.read(buffer)) != -1) { fos.write(buffer , 0, len); } } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { try { if(is != null) is.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { if(fos != null) fos.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } JDBCUtils.closeResource(conn, ps, rs); } }
当需要成批插入或者更新记录时,可以采用Java的批量 更新 机制,这一机制允许多条语句一次性提交给数据库批量处理。通常情况下比单独提交处理更有效率
JDBC的批量处理语句包括下面三个方法:
通常我们会遇到两种批量执行SQL语句的情况:
CREATE TABLE goods( id INT PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR(20) );
这个就不演示了,太low
Connection conn = JDBCUtils.getConnection(); Statement st = conn.createStatement(); for(int i = 1;i <= 20000;i++){ String sql = "insert into goods(name) values('name_' + "+ i +")"; st.executeUpdate(sql); }
JDBCUtils在上一篇写过,获取连接以及释放连接
@Test public void testInsert() { Connection conn = null; PreparedStatement ps = null; try { // 开始时间 long start = System.currentTimeMillis(); conn = JDBCUtils.getConnection(); String sql = "insert into goods(name) values(?)"; ps = conn.prepareStatement(sql); for(int i=1; i <= 20000; i++) { ps.setObject(1, "name_"+i); ps.execute(); } // 结束时间 long end = System.currentTimeMillis(); System.out.println("花费的时间:"+(end-start)); //903016 } catch (Exception e) { e.printStackTrace(); }finally { JDBCUtils.closeResource(conn, ps); } }
可以看到,花费的时间是很长的
需要准备:
需要注意,因为之前用的mysql驱动是mysql-connector-java-5.1.7-bin.jar,所以先把这个
然后再重新导入mysql-connector-java-5.1.37-bin.jar这个
下面就可以写代码了,还是在方式一的基础上:
@Test public void testInsert1() { Connection conn = null; PreparedStatement ps = null; try { // 开始时间 long start = System.currentTimeMillis(); conn = JDBCUtils.getConnection(); String sql = "insert into goods(name) values(?)"; ps = conn.prepareStatement(sql); for(int i=1; i <= 20000; i++) { ps.setObject(1, "name_"+i); // 1. 攒sql ps.addBatch(); if(i % 500 == 0) { // 2. 执行batch ps.executeBatch(); // 3. 清空batch ps.clearBatch(); } } // 结束时间 long end = System.currentTimeMillis(); System.out.println("花费的时间:"+(end-start)); //5399 } catch (Exception e) { e.printStackTrace(); }finally { JDBCUtils.closeResource(conn, ps); } }
花费的时间明显少了很多
@Test public void testInsert2() { Connection conn = null; PreparedStatement ps = null; try { // 开始时间 long start = System.currentTimeMillis(); conn = JDBCUtils.getConnection(); // 设置不允许自动提交数据 conn.setAutoCommit(false); String sql = "insert into goods(name) values(?)"; ps = conn.prepareStatement(sql); for(int i=1; i <= 20000; i++) { ps.setObject(1, "name_"+i); // 1. 攒sql ps.addBatch(); if(i % 500 == 0) { // 2. 执行batch ps.executeBatch(); // 3. 清空batch ps.clearBatch(); } } // 提交数据 conn.commit(); // 结束时间 long end = System.currentTimeMillis(); System.out.println("花费的时间:"+(end-start)); //2223 } catch (Exception e) { e.printStackTrace(); }finally { JDBCUtils.closeResource(conn, ps); } }
速度几乎又提升了一倍
原文链接:https://www.cnblogs.com/mengd/p/13423325.html