一、基本概念
1、数据库内存放的一定是数据。
2、那么数据在计算机内摆脱不掉的就是二进制,而且计算机的底层也是对二进制进行操作。
3、数据库的操作也基本一致
一、Connection对象(连接对象)
二、PreparedStatement对象(SQL语句执行对象)
三、ResultSet对象(结果集对象)
4、只要和数据库进行了连接,那么在程序中就存在了一条输入输出通道(重点)
二、将图片存入数据库
1、基本步骤
将文件写入数据库中(全程都是数据的I/O操作) 1、将需要存入数据库的文件放入到输入流中; 2、写插入的SQL语句:INSERT INTO tbl_image(img) VALUES(?) 3、设置?对应的值,这里采用将文件流对象直接写入到数据库连接流对象中 4、执行SQL语句
2、步骤的实现
private static void setImageByDateBase(File file){
//将指定的文件放入输入流中
try(BufferedInputStream bis=new BufferedInputStream(new FileInputStream(file))){
String sql="INSERT INTO tbl_image(img,name) VALUES(?,?)";
statement=con.prepareStatement(sql);
//将指定的文件流对象放入连接对象中,进行封装性的执行
statement.setBlob(1,bis);//设置第一个问号对应的值
//statement.setBinaryStream(1,bis,bis.available());
statement.setString(2,"空荡的房间");//设置第二个问好对应的值
int r=statement.executeUpdate();//执行SQL语句;
if(r>0){
System.out.println("插入成功");
}else{
System.out.println("插入失败");
}
statement.close();
}catch (IOException | SQLException e) {
e.printStackTrace();
}
}
设置数据库执行流的路径有两个方法
1、statement.setBinaryStream(1,bis,bis.available());
第一个参数是第几个问号
第二个参数是输入流对象
第三个参数是指定输入流的长度
2、statement.setBlob(1,bis)
第一个参数是第几个问号
第二个参数是输入流对象
两个方法的效果都是一样的
三、将图片从数据库中读出
1、基本步骤
从数据库中把图片读取出来,这里需要把数据库中的图片想象成一堆二进制数据,数据库存放的肯定是数据
1、和常规的数据库读取操作一样,都是通过sql语句进行数据(二进制数据)的读取
2、通过对结果集合进行遍历,得到数据库中符合条件的数据
3、在遍历的过程中得到每一条结果集的输入流对象
4、进行I/O操作
2、步骤的实现
private static void getImage(){
String sql="SELECT * FROM tbl_image WHERE id=?";//需要对数据库中的数据进行读取的sql语句
String path="F:\\1.jpg";//将数据从数据库中读取出来后需要存放的目标位置
//将改目标地址作为一个输出流对象,这里采用的缓存流,所以效率会比字节流的效率高
try ( BufferedOutputStream bop=new BufferedOutputStream(new FileOutputStream(path))){
statement=con.prepareStatement(sql);
statement.setInt(1,"空荡的房间");//设置sql语句中的?对应的值
ResultSet result=statement.executeQuery();//执行sql语句
InputStream inputSteam=null;
result=statement.executeQuery();//得到执行了sql语句后的结果集对象
while(result.next()){ //遍历结果集
//得到结果集中的每一条数据,将该条数据放入结果集的输入流中,并返回一个InputStream对象
inputSteam=result.getBinaryStream("img");
byte[] z=new byte[1024];
//进行读写的I/O操作
while(inputSteam.read(z)!=-1){
bop.write(z);
}
}
System.out.println("复制完成");
con.close();
} catch (SQLException | IOException throwables) {
throwables.printStackTrace();
}
}
result.getBinaryStream();方法
就是需要从结果集对象中得到当前这条数据的输入流,返回的是一个Input Stream对象
总结
- 在Java的世界里,万物皆对象
- 在文件(I/O)的世界里,万物皆是二进制文件
- 对于二进制的文件,最好使用BufferedInputStream和BufferedOutputStream
- 对于含有中文的文件,因为中文所占据的字节长度和英文字符字节长度是不一样的,
- 所以,含有中文字符的文件,最好使用BufferedReader和BufferedWriter
- 但是,无论是哪种高层流对象,都是对底层流的一种封装
- 不过,其中需要很好的理解什么是输入方、什么是输出方
- 输入方:需要将数据读入内存的一方(输入流对象)
- 输出方:需要将数据从内存写入到目的地的一方(输出流对象)