BLOb(Binary long object) 是二进制长对象的意思,Blob列通常用于存储大文件,典型的用于存储一张图片或者一个声音文件。由于他们的特殊性,需要用特殊的格式存储。使用Blob列可以把图片或者声音等二进制文件保存在数据库,并可以从数据库中恢复指定其文件。
如果需要将图片插入数据库中,显然不能用普通 的SQL语句操作,因为有一个关键的问题那就是Blob常量无法表示。自然而然,所以将要把Blob数据插入数据库中需要使用PreparedStatement,该对象有一个方法,就是
SetBianryStream(int paramterIndex,InputStream)
该方法可以指定参数传入二进制流,从而实现Blob数据到数据库的保存。
当我们需要从ResultSet中取出数据时,可以调用Result中的
GetBlob(int paramIndex)
该方法返回一个Blob对象,而该对象提供了GetBianryStream方法来获取BLOb对象中数据流,也可使用Blob对象的GetByte方法直接取出其中的封装的二进制数据。
为了把图片放进数据库中,下面先用SQL语句建立一个表
create table img_table(
img_id int auto_increment primary key ,
img_name varchar(255),
img_data mediumblob #存储图片数据流最大16M
);
上图SQl语句中img_data 使用的是mediumblob类型而非blob类型,因为mysql中blob类型只能存储4kb内容,显然不能满足项目要求,而mediumblob类型可以存储16M的内容
下面我写一个demo,该图片的功能就是将图片“上传” - 就是将图片保存在数据库中,并且右边的列表框显示图片的名字,当你双击图片的名字时候,左边的图片将要显示该图片
package mysql;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.*;
import java.sql.*;
import java.util.Properties;
import java.util.Map.Entry;
public class img_mysql_test {
JFrame jFrame = new JFrame("图片管理员");
private static Connection connection;
private static PreparedStatement insert;
private static PreparedStatement query;
private static PreparedStatement queryALL;
//定义一个默认的defaultList对象
private DefaultListModel imageModel = new DefaultListModel();
//list绑定到model,通过model控制list
private JList imageList = new JList(imageModel);
private JTextField fileFiled = new JTextField(26);
private JButton browseButton = new JButton("浏览");
private JButton uploadBn = new JButton("上传");
private JLabel imageLable = new JLabel("");
//以当前路径创建文件浏览器
JFileChooser fileChooser = new JFileChooser("../图片/");
//创建文件过滤器
ExtensionFileFilter filter = new ExtensionFileFilter();
//独立于成员变量和成员函数的代码块,表示这些代码只可以被执行一次
static
{
Properties properties = new Properties();
try {
properties.load(new FileInputStream("database.ini"));
} catch (IOException e) {
e.printStackTrace();
}
String mysqlDriver = properties.getProperty("mysqlDriver");
String mysqlURL = properties.getProperty("mysqlURl");
String mysqlUser = properties.getProperty("mysqlUserName");
String mysqlPass = properties.getProperty("mysqlUserPassword");
// 注册驱动
try {
Class.forName(mysqlDriver);
} catch (ClassNotFoundException e) {
System.out.println("未能成功加载驱动程序,请检查是否成功导入驱动程序");
e.printStackTrace();
}
//登录数据库
try {
System.out.println("读取配置信息:"+mysqlURL + "_" + mysqlUser + "_" +mysqlPass + "\t\n");
connection = DriverManager.getConnection(mysqlURL, mysqlUser,mysqlPass);
System.out.println("连接数据库成功");
} catch (SQLException throwable) {
System.out.println("连接数据库失败");
throwable.printStackTrace();
}
try {
//该对象插入后自动生成主要键
insert = connection.prepareStatement("insert into img_table values (null,?,?);", Statement.RETURN_GENERATED_KEYS);
//创建两个对象,用于查询指定图片,所有图片
query = connection.prepareStatement("select img_data from img_table where img_id = ?");
queryALL = connection.prepareStatement("select img_id ,img_name from img_table");
} catch (SQLException throwable) {
throwable.printStackTrace();
}
}
// -------初始化文件选择器-----
public void init()
{
filter.AddExtension("jpg");
filter.AddExtension("jpeg");
filter.AddExtension("gif");
filter.AddExtension("png");
//设置文件过滤类型
filter.setDescription("图片文件(*.jpg,*jpeg,*.gif,*.png)");
fileChooser.addChoosableFileFilter(filter);
//禁止显示文件的所有类型
fileChooser.setAcceptAllFileFilterUsed(false);
//初始化程序界面,数据库里存的图片展示出来
fillListModel();
fileFiled.setEditable(false);
//设置单选
imageList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
JPanel jPanel = new JPanel();
jPanel.add(fileFiled);
jPanel.add(browseButton);
browseButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int result = fileChooser.showDialog(jFrame,"浏览文件图片上传");
//保存,显示
if(result == JFileChooser.APPROVE_OPTION)
{
fileFiled.setText(fileChooser.getSelectedFile().getPath());
}
}
});
jPanel.add(uploadBn);//加入更新按钮
uploadBn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//上传的文件有内容
if(fileFiled.getText().trim().length() > 0)
{
//将指定文件保存到数据库
updatePictureToDatabase(fileFiled.getText());
//清除文本框
fileFiled.setText("");
}
}
});
JPanel jPanel_left = new JPanel();
jPanel_left.setLayout(new BorderLayout());
jPanel_left.add(new JScrollPane(imageLable),BorderLayout.CENTER);
jPanel_left.add(jPanel,BorderLayout.SOUTH);
jFrame.add(jPanel_left);// 包含
//设置列表的宽度
imageList.setFixedCellWidth(250);
jFrame.add(new JScrollPane(imageList),BorderLayout.EAST);
imageList.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
//双击list选项
if(e.getClickCount() >= 2)
{
Image_holder curImage = (Image_holder)imageList.getSelectedValue();
//显示对应项的图片
try {
showPictureFromId(curImage.getImg_id());
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
});
//显示视频
jFrame.setSize(620,400);
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jFrame.setVisible(true);
}
public void closeResources()
{
try {
if(connection != null)
{
connection.close();
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
public void fillListModel()
{
ResultSet resultSet = null;
try {
imageModel.clear();
//执行查询
resultSet = queryALL.executeQuery();
//查询结果放在list中
while (resultSet.next())
{
imageModel.addElement(new Image_holder(resultSet.getInt(1),resultSet.getString(2)));
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
if(resultSet != null)
{
try {
resultSet.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
//将指定图片放入数据库
public void updatePictureToDatabase(String fileName)
{
InputStream inputStream = null;
try {
//获取图片名
String imgName = fileName.substring(fileName.lastIndexOf("\\") + 1,fileName.lastIndexOf("."));
//操作占位符
insert.setString(1,imgName);
System.out.println("文件名" + imgName);
File file = new File(fileName);
try {
inputStream = new FileInputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//设置二进制流
insert.setBinaryStream(2,inputStream,(int)file.length());
int affect = insert.executeUpdate();
if(affect ==1)
{
//重新更新,会让list显示最新的图片
fillListModel();
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
if(inputStream != null)
{
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public void showPictureFromId(int id) throws SQLException
{
ResultSet resultSet = null;
try {
query.setInt(1,id);
resultSet = query.executeQuery();
if(resultSet.next())
{
//取出Blob列
Blob imgBlob = resultSet.getBlob(1);
//取出bob列的数据
ImageIcon imageIcon = new ImageIcon(imgBlob.getBytes(1L,(int)imgBlob.length()));
imageLable.setIcon(imageIcon);
}
}finally {
if(resultSet != null)
{
resultSet.close();
}
}
}
}
需要一个图片类
package mysql;
/**
*用于封装图片名,图片id
*
* @Autor:lvp
* @Date:2020
* */
public class Image_holder
{
private int img_id;
//封装图片的图片名字
private String img_name;
public Image_holder(){};
public Image_holder(int id ,String name)
{
img_id = id;
img_name = name;
}
public void setImgId(int id)
{
img_id = id;
}
public int getImg_id()
{
return this.img_id;
}
public void setImg_name(String name)
{
img_name = name;
}
public String getImg_name()
{
return this.img_name;
}
}
还需要实现一个文件过滤的功能
package mysql;
import javax.swing.filechooser.FileFilter;
import java.io.File;
import java.util.ArrayList;
/**
*
* 重新实现FileFilter ,实现文件过滤功能
* */
public class ExtensionFileFilter extends FileFilter {
private String description = "";
private ArrayList<String> list = new ArrayList<>();
//自定义文件,用于添加文件扩展名
public void AddExtension(String extension)
{
if(!extension.startsWith("."))
{
extension = "." +extension;
list.add(extension.toLowerCase());
}
}
//抽象办法的实现,判断该文件过滤器是否应该接受文件过滤
@Override
public boolean accept(File f) {
if(f.isDirectory()) return true;
String fileName = f.getName().toLowerCase();
//如果有类似的扩展名,则表示接受文件
for(String str: list)
{
if(fileName.endsWith(str))
{
return true;
}
}
return false;
}
public void setDescription(String aDescription)
{
description = aDescription;
}
@Override
public String getDescription() {
return description;
}
}
代码全部写完,运行过后
点击上传一些图片过后
将要图片存储在数据库里
双击图片名称,从数据库里取出来显示