JDBC的学习(第六节:处理大数据对象 )

  • Post author:
  • Post category:其他

第一节:JDBC的概述

第二节:JDBC连接数据库

第三节:使用Statement接口实现增、删、改操作

第四节:使用PreparedStatement接口实现增、删、改的操作

第五节:Resultset结果集

第六节:处理大数据对象

第七节:使用CallableStatement接口调用存储过程

第八节:使用元数据分析数据库

第九节:JDBC的事务处理事务

下面是第六个部分,其他部分可以通过上面的链接访问

8.处理大数据对象

主要从下面两个方面来学习

  1. 处理 CLOB 数据
  2. 处理 BLOG 数据

大数据对象处理主要有 CLOB(characterlarge object)和 BLOB(binary large object)两种类型的字段;在 CLOB 中可以存储大字符数据对象,比如长篇小说;在 BLOB 中可以存放二进制大数据对象,比如图片,电影,音乐;

现在做准备工作。
首先学习的是CLOB字段的: 我们进行的是大字符数据的操作,所以要用到IO流的知识以及文件操作File类的知识。简单的提一下这个IO流,第一次接触是在杭州达内实习的时候,我们做捕鱼达人的小游戏,那时候用到了图片IO流,当时只是简单的掌握了图片IO流,但是并没有对IO流进行深究,下面有我最近的一个基础知识的系统性学习。
具体的知识的学习可以看我写的另一个分类,J2SE的系统性学习——IO流和File类,对于这部分的知识点就不在这里做过多的介绍了。
首先把我一开始创建的t_book这个表再增加一个列,这列的作用是文章摘要。

如图
在这里插入图片描述此数据类型存储的是大字符数据。

接下来选择一个硬盘,创建一个text文本文件,可以先不放东西进去。
我在我的项目学习专用盘中创建的text文本,如图,helloWorld
在这里插入图片描述这个就是路径,实在不会找的看这里,不过记住,要改成/,这里的\是错的!。

在这里插入图片描述
然后下面的工作就是代码方面的了
经过表的列的增加,Book类用该也增加一个属性,并且要重写构造方法。
具体的区别与前面对比看一下

package model;

import java.io.File;

/**
 * 图书的实体,有图书的所有的属性
 * @author Administrator
 *
 */
public class Book {
	private int id;
	private String bookName;
	private float price;
	private String author;
	private int bookTypeId;
	private File context;
	
	//构造方法(快捷键写的)
	public Book(String bookName, float price, String author, int bookTypeId) {
		super();
		this.bookName = bookName;
		this.price = price;
		this.author = author;
		this.bookTypeId = bookTypeId;
	}
	//重载的构造方法
	public Book(int id, String bookName, float price, String author, int bookTypeId) {
		super();
		this.id = id;
		this.bookName = bookName;
		this.price = price;
		this.author = author;
		this.bookTypeId = bookTypeId;
	}
	//为第六章的学习重载构造方法
	public Book(String bookName, float price, String author, int bookTypeId, File context) {
		super();
		this.bookName = bookName;
		this.price = price;
		this.author = author;
		this.bookTypeId = bookTypeId;
		this.context = context;
	}
	//下面的所有的代码都是通过快捷键实现的
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getBookName() {
		return bookName;
	}
	public void setBookName(String bookName) {
		this.bookName = bookName;
	}
	public float getPrice() {
		return price;
	}
	public void setPrice(float price) {
		this.price = price;
	}
	public String getAuthor() {
		return author;
	}
	public void setAuthor(String author) {
		this.author = author;
	}
	public int getBookTypeId() {
		return bookTypeId;
	}
	public void setBookTypeId(int bookTypeId) {
		this.bookTypeId = bookTypeId;
	}
	
	public File getContext() {
		return context;
	}
	public void setContext(File context) {
		this.context = context;
	}
	@Override
	public String toString() {
		return "Book [id=" + id + ", bookName=" + bookName + ", price=" + price + ", author=" + author + ", bookTypeId="
				+ bookTypeId + "]";
	}
}

在这里插入图片描述新定义的一个属性是File类型的

然后还是引用前面学的,第四节的学习中的向数据库中写入数据的知识,唯一的变化是写进去一个大字符数据。

package chap6_sec01;

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

import model.Book;
import util.DbUtil;

public class Demo1 {
	private static DbUtil dbUtil=new DbUtil();
	private static int addBook(Book book) throws Exception{
		Connection con=null;
		con=dbUtil.getCon();//获取连接
		//数据添加的sql语句,然后挖五个坑,五个坑代表表中的五个属性
		String sql="insert into t_book values(null,?,?,?,?,?)";
		PreparedStatement pstmt= con.prepareStatement(sql);
		//下面是给五个坑填值
		pstmt.setString(1, book.getBookName());
		pstmt.setFloat(2, book.getPrice());
		pstmt.setString(3, book.getAuthor());
		pstmt.setInt(4, book.getBookTypeId());
		File context=book.getContext();//获取文件
		InputStream inputStream=new FileInputStream(context);//定义一个输入流
		//最后一个参数是用多常给第五个坑填值
		pstmt.setAsciiStream(5, inputStream, context.length());//给第五个坑填上值
		//返回的值是执行sql语句之后得表受影响的数据的条数
		int result=pstmt.executeUpdate();
		dbUtil.close(pstmt, con);
		return result;
	}
	public static void main(String[] args) {
		File context=new File("x:/helloWorld.txt");
		Book book=new Book("网易云音乐集", 20.5f, "网易云", 5, context);
		try {
			int result = addBook(book);
			System.out.println("信息添加成功");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			System.out.println("信息添加失败");
		}
	}
}

看一下变化:

  1. IO流的引入,在main函数中获取text文本中的东西,然后传到addBook函数中去。
  2. addBook函数中引入了IO流和File类的知识,并且将SQL语句多挖了一个坑,将最后一个坑的数据写进去,因为是大字符类型的数据,多以我们写的时候要传写进的数据的长度,这样能合理的应用存储的空间,也能解决定义的死的空间不够用的问题。

执行结果
在这里插入图片描述在这里插入图片描述为什么插入的信息context的部分是空的呢?因为我创建text文本的时候,没有写东西进去,所以我们只要在text文本中写进东西,再执行一次就能看到效果了。
简单的写点东西进去
在这里插入图片描述
再运行代码之后查看数据库
在这里插入图片描述但是值得注意的是,文本文件中存汉子执行代码是不被允许执行的,我写进去的都是按照英文的键盘输入的。longtext不支持汉语文本。
上面是插入到数据库,下面学习怎么的读取数据库中的大字符类型的数据。
先看一下我写完了的效果吧
在这里插入图片描述跟上面的对比可以看到我们是正确的读取的,这里是从数据库中读取的,不是从text文本文件中读的。
下面看代码:

package chap6_sec01;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import model.Book;
import util.DbUtil;

public class Demo1 {
	private static DbUtil dbUtil=new DbUtil();
	private static int addBook(Book book) throws Exception{
		Connection con=null;
		con=dbUtil.getCon();//获取连接
		//数据添加的sql语句,然后挖五个坑,五个坑代表表中的五个属性
		String sql="insert into t_book values(null,?,?,?,?,?)";
		PreparedStatement pstmt= con.prepareStatement(sql);
		//下面是给五个坑填值
		pstmt.setString(1, book.getBookName());
		pstmt.setFloat(2, book.getPrice());
		pstmt.setString(3, book.getAuthor());
		pstmt.setInt(4, book.getBookTypeId());
		File context=book.getContext();//获取文件
		InputStream inputStream=new FileInputStream(context);//定义一个输入流
		//最后一个参数是用多常给第五个坑填值
		pstmt.setAsciiStream(5, inputStream, context.length());//给第五个坑填上值
		//返回的值是执行sql语句之后得表受影响的数据的条数
		int result=pstmt.executeUpdate();
		dbUtil.close(pstmt, con);
		return result;
	}

	public static void getBook(int id)throws Exception{
		Connection con=dbUtil.getCon();
		String sql="select * from t_book where id=?";
		PreparedStatement pstmt=con.prepareStatement(sql);
		pstmt.setInt(1, id);
		//用到的是第五节的结果集的学习
		ResultSet rs=pstmt.executeQuery();
		if(rs.next()){
			String bookName=rs.getString("bookName");
			Float price=rs.getFloat("price");
			String author=rs.getString("author");
			int bookTypeId=rs.getInt("bookTypeId");
			Clob c=rs.getClob("context");
			String context=c.getSubString(1, (int)c.length());
			System.out.println("图书名称:"+bookName);
			System.out.println("图书价格:"+price);
			System.out.println("图书作者:"+author);
			System.out.println("图书分类:"+bookTypeId);
			System.out.println("图书描述:"+context);
		}
		dbUtil.close(pstmt, con);//关闭相关的操作和连接
	}
	
	
	public static void main(String[] args) throws Exception {
		/*File context=new File("x:/helloWorld.txt");
		Book book=new Book("网易云音乐集", 20.5f, "网易云", 5, context);
		try {
			int result = addBook(book);
			System.out.println("信息添加成功");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			System.out.println("信息添加失败");
		}*/
		getBook(6);
	}
}

具体看getBook的函数,其他的和上面是一样的,我就是懒的注释,,,
然后根据这个,我们可以读取数据库中的id=6的所有的数据。
在这里插入图片描述还是老样子,为什么通过id进行查询,因为这里的id是唯一的,id是主键,所以查询的结果也是唯一性的,我们只能查询一条数据的所有信息。
上面用到了Clob,这个我看这篇文章学习了一下,JAVA处理Clob大对象,这里也可以用IO流进行处理,但是很麻烦,然后直接用这个封装好的Clob就行了。

========================================================================================

下面学习的是BLOG部分的,主要是对图片,电影,音乐的存储,把这些信息存到数据库中,本质是处理二进制的内容。

做准备工作,上面的加了书的简介,下面可以给这本书加上插图,所以老样子,我要去改变数据库的表,为表再增加一列,然后改变实体Book,在其中再增加一个属性。
网上查了一下这个存二进制的东西的限制大小,能存好几个G,所以完全放心的,已经足够用了
在这里插入图片描述改变表,增加新的一列。
然后在X盘中放一个图片。
在这里插入图片描述最近迷上大Q宝贝了,,,将就看一下吧,还蛮可爱的。
然后我们看代码,,,
老样子,先改Book类,增加新的属性,重写构造方法。

package model;

import java.io.File;

/**
 * 图书的实体,有图书的所有的属性
 * @author Administrator
 *
 */
public class Book {
	private int id;
	private String bookName;
	private float price;
	private String author;
	private int bookTypeId;
	private File context;
	private File pic;

//构造方法(快捷键写的)
public Book(String bookName, float price, String author, int bookTypeId) {
	super();
	this.bookName = bookName;
	this.price = price;
	this.author = author;
	this.bookTypeId = bookTypeId;
}
//重载的构造方法
public Book(int id, String bookName, float price, String author, int bookTypeId) {
	super();
	this.id = id;
	this.bookName = bookName;
	this.price = price;
	this.author = author;
	this.bookTypeId = bookTypeId;
}
//为第六章的学习重载构造方法
public Book(String bookName, float price, String author, int bookTypeId, File context) {
	super();
	this.bookName = bookName;
	this.price = price;
	this.author = author;
	this.bookTypeId = bookTypeId;
	this.context = context;
}

//BLOG部分的重载
public Book(String bookName, float price, String author, int bookTypeId, File context, File pic) {
	super();
	this.bookName = bookName;
	this.price = price;
	this.author = author;
	this.bookTypeId = bookTypeId;
	this.context = context;
	this.pic = pic;
}
//下面的所有的代码都是通过快捷键实现的
public int getId() {
	return id;
}
public void setId(int id) {
	this.id = id;
}
public String getBookName() {
	return bookName;
}
public void setBookName(String bookName) {
	this.bookName = bookName;
}
public float getPrice() {
	return price;
}
public void setPrice(float price) {
	this.price = price;
}
public String getAuthor() {
	return author;
}
public void setAuthor(String author) {
	this.author = author;
}
public int getBookTypeId() {
	return bookTypeId;
}
public void setBookTypeId(int bookTypeId) {
	this.bookTypeId = bookTypeId;
}

public File getContext() {
	return context;
}
public void setContext(File context) {
	this.context = context;
}


public File getPic() {
	return pic;
}
public void setPic(File pic) {
	this.pic = pic;
}
@Override
public String toString() {
	return "Book [id=" + id + ", bookName=" + bookName + ", price=" + price + ", author=" + author + ", bookTypeId="
			+ bookTypeId + "]";
}

}

有了新增的属性,新的构造方法以及set和get,现在我们就可以写主要的代码了,直接copy上面的学习用的代码 ,稍微改一下

package chap6_sec02;


import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import model.Book;
import util.DbUtil;

public class Demo1 {
	private static DbUtil dbUtil=new DbUtil();
	private static int addBook(Book book) throws Exception{
		Connection con=null;
		con=dbUtil.getCon();//获取连接
		//数据添加的sql语句,然后挖五个坑,五个坑代表表中的五个属性
		String sql="insert into t_book values(null,?,?,?,?,?,?)";
		PreparedStatement pstmt= con.prepareStatement(sql);
		//下面是给五个坑填值
		pstmt.setString(1, book.getBookName());
		pstmt.setFloat(2, book.getPrice());
		pstmt.setString(3, book.getAuthor());
		pstmt.setInt(4, book.getBookTypeId());
		File context=book.getContext();//获取文件
		InputStream inputStream=new FileInputStream(context);//定义一个输入流
		//最后一个参数是用多常给第五个坑填值
		pstmt.setAsciiStream(5, inputStream, context.length());//给第五个坑填上值
		
		
		File pic=book.getPic();
		InputStream inputStream2=new FileInputStream(pic);//定义一个输入流
		pstmt.setBinaryStream(6, inputStream2, pic.length());
		//返回的值是执行sql语句之后得表受影响的数据的条数
		int result=pstmt.executeUpdate();
		dbUtil.close(pstmt, con);
		return result;
	}

	public static void getBook(int id)throws Exception{
		Connection con=dbUtil.getCon();
		String sql="select * from t_book where id=?";
		PreparedStatement pstmt=con.prepareStatement(sql);
		pstmt.setInt(1, id);
		//用到的是第五节的结果集的学习
		ResultSet rs=pstmt.executeQuery();
		if(rs.next()){
			String bookName=rs.getString("bookName");
			Float price=rs.getFloat("price");
			String author=rs.getString("author");
			int bookTypeId=rs.getInt("bookTypeId");
			Clob c=rs.getClob("context");
			String context=c.getSubString(1, (int)c.length());
			System.out.println("图书名称:"+bookName);
			System.out.println("图书价格:"+price);
			System.out.println("图书作者:"+author);
			System.out.println("图书分类:"+bookTypeId);
			System.out.println("图书描述:"+context);
		}
		dbUtil.close(pstmt, con);//关闭相关的操作和连接
	}
	
	
	public static void main(String[] args) throws Exception {
		File context=new File("x:/helloWorld.txt");
		File pic=new File("x:/pic.jpg");
		Book book=new Book("网易云音乐集", 20.5f, "网易云", 5, context,pic);
		try {
			int result = addBook(book);
			System.out.println("信息添加成功");
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("信息添加失败");
		}
	}
}

主要改变在addBook这个类中,然后在main函数中写了一个新的File,作为对图片的引入。
变动如下,在addBook中的变动
在这里插入图片描述在main中的变动
在这里插入图片描述执行之后去数据库中查看,效果如下,还是能看到我们可爱的大Q宝的。
在这里插入图片描述老样子,进去了是进去了,怎么把它从数据库中弄出来呢?
下面看代码

package chap6_sec02;


import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import model.Book;
import util.DbUtil;

public class Demo1 {
	private static DbUtil dbUtil=new DbUtil();
	private static int addBook(Book book) throws Exception{
		Connection con=null;
		con=dbUtil.getCon();//获取连接
		//数据添加的sql语句,然后挖五个坑,五个坑代表表中的五个属性
		String sql="insert into t_book values(null,?,?,?,?,?,?)";
		PreparedStatement pstmt= con.prepareStatement(sql);
		//下面是给五个坑填值
		pstmt.setString(1, book.getBookName());
		pstmt.setFloat(2, book.getPrice());
		pstmt.setString(3, book.getAuthor());
		pstmt.setInt(4, book.getBookTypeId());
		File context=book.getContext();//获取文件
		InputStream inputStream=new FileInputStream(context);//定义一个输入流
		//最后一个参数是用多常给第五个坑填值
		pstmt.setAsciiStream(5, inputStream, context.length());//给第五个坑填上值
		
		
		File pic=book.getPic();
		InputStream inputStream2=new FileInputStream(pic);//定义一个输入流
		pstmt.setBinaryStream(6, inputStream2, pic.length());
		//返回的值是执行sql语句之后得表受影响的数据的条数
		int result=pstmt.executeUpdate();
		dbUtil.close(pstmt, con);
		return result;
	}

	public static void getBook(int id)throws Exception{
		Connection con=dbUtil.getCon();
		String sql="select * from t_book where id=?";
		PreparedStatement pstmt=con.prepareStatement(sql);
		pstmt.setInt(1, id);
		//用到的是第五节的结果集的学习
		ResultSet rs=pstmt.executeQuery();
		if(rs.next()){
			String bookName=rs.getString("bookName");
			Float price=rs.getFloat("price");
			String author=rs.getString("author");
			int bookTypeId=rs.getInt("bookTypeId");
			Clob c=rs.getClob("context");
			String context=c.getSubString(1, (int)c.length());
			
			Blob b=rs.getBlob("pic");
			/*由于开发工具是没法显示图片的
			*所以把从数据库中获得的数据存到某个硬盘中
			*/
			//定义一个输出流
			FileOutputStream out=new FileOutputStream(new File("e:/pic2.jpg"));
			out.write(b.getBytes(1, (int)b.length()));
			out.close();//用完就关闭
			System.out.println("图书名称:"+bookName);
			System.out.println("图书价格:"+price);
			System.out.println("图书作者:"+author);
			System.out.println("图书分类:"+bookTypeId);
			System.out.println("图书描述:"+context);
		}
		dbUtil.close(pstmt, con);//关闭相关的操作和连接
	}
	
	
	public static void main(String[] args) throws Exception {
		/*File context=new File("x:/helloWorld.txt");
		File pic=new File("x:/pic.jpg");
		Book book=new Book("网易云音乐集", 20.5f, "网易云", 5, context,pic);
		try {
			int result = addBook(book);
			System.out.println("信息添加成功");
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("信息添加失败");
		}*/
		getBook(7);
	}
}

主要变动如下:
在getBook中新增
在这里插入图片描述在main函数中注释点addBook函数的使用,然后调用getBook函数
在这里插入图片描述id=7是数据库中的,看数据库
在这里插入图片描述然后在上面的写的有输出流,把从数据库中的数据写道E盘中存储,下面是执行代码之后的效果。
在这里插入图片描述

本次的学习就在这里结束了,注意BLOG部分的学习,我们操作的都是二进制的数据,学习过计算机组成的都知道,计算机中存储的数据都是二进制的形式,8进制和16进制只是为了方面我们人类对数据的处理,所以我们在计算的时候,移位运算比正常的扩大缩小的运算要看,这个本质上说是不用转化成二进制来进行计算的,还有ClOB部分的学习的时候,是对大字符类型的数据进行处理,不论是ClOB还是BLOG ,我们在数据库中定义数据类型的时候,都不用写数据的长度。

需要学习的时候用到的数据库和所有的源代码,请去百度网盘提取
链接:https://pan.baidu.com/s/1wDL_aFCPQ9WAZ_vSy6UVdg
提取码:hime


版权声明:本文为qq_43918130原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。