JAVA学习笔记——BLOB类型和数据批量操作

写在开头:本文是学习尚硅谷JavaWeb的个人笔记,便于自己后期复习,也供各位参考评论,指出错误共同进步。

1 MySQL BLOB 类型

  • MySQL中,BLOB是一个二进制大型对象,是一个可以存储大量数据的容器,它能容纳不同大小的数据。
  • MySQL的四种BLOB类型(除了在存储的最大信息量上不同外,他们是等同的)。
    在这里插入图片描述
  • 实际使用中根据需要存入的数据大小定义不同的BLOB类型。需要注意的是:如果存储的文件过大,数据库的性能会下降。

1.1 向数据表中插入Blob类型数据

package com.atguigu5.blob;

import java.io.File;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;

import org.junit.Test;

import com.atguigu3.util.JDBCUtils;

public class BlobTest {
	//向数据表customer中插入Blob类型的字段
	@Test
	public void tesrInsert() 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, "lin@qq.com");
		ps.setObject(3, "1992-06-08");
		//大的数据一般用流来操作
		FileInputStream is = new FileInputStream(new File("playgirl.jpg"));
		ps.setBlob(4, is);
		
		ps.execute();
		JDBCUtils.closeResource(conn, ps);
	}
}

运行结果:
在这里插入图片描述

1.2 从数据表中读入Blob类型数据

@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.setInt(1, 21);
			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 cust = new Customer(id, name, email, birth);
				System.out.println(cust);
				
				//将Blob类型的字段下载下来,以文件的方式保存在本地
				Blob photo = rs.getBlob("photo");
				is = photo.getBinaryStream();
				fos = new FileOutputStream("zhangyuhao.jpg");
				byte[] buffer = new byte[1024];
				int len;
				while((len = is.read(buffer)) != -1){
					fos.write(buffer, 0, len);
				}
				
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			
			try {
				if(is != null)
					is.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			
			try {
				if(fos != null)
					fos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			
			JDBCUtils.closeResource(conn, ps, rs);
		}
			
	}

2 使用PreparedStatement实现批量数据的操作

2.1 进阶一

普通的向数据库中一条一条插入数据(填充一次占位符,我们就执行一次,效率太低)

package com.atguigu5.blob;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import org.junit.Test;

import com.atguigu3.util.JDBCUtils;

/*
 * 使用PreparedStatement实现批量数据的操作
 * 
 * update、delete本身就具有批量操作的效果。
 * 此时的批量操作,主要指的是批量插入。使用PreparedStatement如何实现更高效的批量插入?
 * 
 * 题目:向goods表中插入20000条数据
 * 在SQLyong里面创建新表
 * CREATE TABLE goods(
	id INT PRIMARY KEY AUTO_INCREMENT,
	NAME VARCHAR(25)
 */
public class InsertTest {
	//批量插入的方式二:使用PreparedStatement
	@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(?)";//这里只增加名字,id是自增长
			ps = conn.prepareStatement(sql);
			for(int i =1;i<=2000;i++) {
				ps.setObject(1, "name_"+1);
				ps.execute();//填充一次占位符,我们就执行一次效率太低
			}
			long end = System.currentTimeMillis();
			System.out.println("花费的时间为:" + (end - start));//花费的时间为:81426
		}catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			JDBCUtils.closeResource(conn, ps);
		}
	}
}

2.2 进阶二

(填充一次占位符,我们就执行一次,效率太低,进阶二便多填充几次占位符(这里是500次),再去执行一次,效率在一定程度上得以提高)。
官方语言: 当需要成批插入或者更新记录时。可以采用Java的批量更新机制,这一机制允许多条语句一次性提交给数据库批量处理。通常情况下比单独提交处理更有效率

  • JDBC的批量处理语句包括下面两个方法:
    addBatch(String): 添加需要批量处理的SQL语句或是参数;
    executeBatch(): 执行批量处理语句;
    clearBatch(): 清空缓存的数据

更新驱动方法:之前我们使用的是1.7的驱动已经加载好了,现在复制1.37的驱动进去需要重新记载
1、在先在项目上右键Build Path->configure Build Path,在Libraries中找到1.7的驱动,remove后点击ok。
2、现在右击刚复制进来的1.37驱动,Build Path-> add to Build Path。

//方式二 
	/*
	 * 批量插入的方式二:
	 * 1.addBatch()、executeBatch()、clearBatch()
	 * 2.mysql服务器默认是关闭批处理的,我们需要通过一个参数,让mysql开启批处理的支持。
	 * 		 ?rewriteBatchedStatements=true 写在配置文件的url后面(配置文件就是之前我们写的jdbc.properties文件)
	 * 3.使用更新的mysql 驱动:mysql-connector-java-5.1.37-bin.jar
	 */
	@Test
	public void testInsert2() {
		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 <= 1000000;i++){
				ps.setObject(1, "name_" + i);
				
				//1."攒"sql,"攒"到500次
				ps.addBatch();
				
				if(i % 500 == 0){
					//2.执行batch
					ps.executeBatch();//每获取500条是都会提交一次
					//3.清空batch
					ps.clearBatch();
				}
				
			}
			
			long end = System.currentTimeMillis();
			
			System.out.println("花费的时间为:" + (end - start));//20000:83065 -- 565
		} catch (Exception e) {								//1000000:16086
			e.printStackTrace();
		}finally{
			JDBCUtils.closeResource(conn, ps);
			
		}
		
	}

2.3 层次三

(虽然执行了,但我们不提交。设置不允许自动提交数据到数据库,执行完之后一起提交,能在一定程度上提高速率)

	//批量插入的方式四:设置连接不允许自动提交数据
	@Test
	public void testInsert3() {
		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 <= 1000000;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));//20000:83065 -- 565
		} catch (Exception e) {								//1000000:16086 -- 5114
			e.printStackTrace();
		}finally{
			JDBCUtils.closeResource(conn, ps);
			
		}
		
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值