[疯狂Java]JDBC:用blob处理多媒体类型数据
2016-04-20 21:32
155 查看
1. JDBC导入Blob类型数据:
1) Blob即Binary Long Object的缩写,即二进制长对象,常用于存储大型文件,比如图片、音视频等;
2) 由于在SQL中无法表示blob常量,因此就不能用Statement导入到数据库,但幸好可以用PreparedStatement导入数据库:
i. PreparedStatement可以用通配符?来表示要插入的blob常量;
ii. 然后使用PreparedStatement的setBinaryStream将blob类型数据插入到通配符?的位置:
a. 这里要求导入的blob数据以输入流的形式提交给数据库;
b. 而一般要导入的数据都是保存在磁盘上的,因此通常会创建目标文件的文件节点流作为该参数传入;
c. 例如:pstmt.setBinaryStream(1, new FileInputStream(new File("xxx.mp3")));
d. 还有一个可选参数length,即流中的字节数;
iii. 最后提交insert into语句完成blob类型数据的导入;
3) 从数据库读取Blob类型数据:
i. ResultSet直接提供了getBlob方法:Blob getBlob(int columnIndex | String columnLabel);
ii. 可以看到Java直接提供了Blob类型;
4) Blob类型常用方法:
i. byte[] Blob.getBytes(long pos, int length); // 从blob对象的第pos个字节开始,复制出length个字节的byte数组返回,blob变量的第一个字节的位置是1不是0!!!
ii. long Blob.length(); // blob变量中共有多少个字节
2. 示例:图片数据库交互
1) 是一个Swing界面,右侧是一个图片名列表,显示当前数据库中存在的图片名,左侧是一个图片显示框,双击列表中的图片名就可以在显示框中显示图片;
2) 左下侧是一个文件按钮,点击可以在Windows资源管理内选择图片格式的文件,选中后图片的路径会显示在一个不可编辑的文本框内;
3) 点击upload按钮,可以将选中的图片文件导入到数据库,同时更新右侧列表中的内容;
首先需要在select_test数据库中加一张保存图片的表
mysql.ini
1) Blob即Binary Long Object的缩写,即二进制长对象,常用于存储大型文件,比如图片、音视频等;
2) 由于在SQL中无法表示blob常量,因此就不能用Statement导入到数据库,但幸好可以用PreparedStatement导入数据库:
i. PreparedStatement可以用通配符?来表示要插入的blob常量;
ii. 然后使用PreparedStatement的setBinaryStream将blob类型数据插入到通配符?的位置:
void PreparedStatement.setBinaryStream(int parameterIndex, java.io.InputStream x[, int length]);
a. 这里要求导入的blob数据以输入流的形式提交给数据库;
b. 而一般要导入的数据都是保存在磁盘上的,因此通常会创建目标文件的文件节点流作为该参数传入;
c. 例如:pstmt.setBinaryStream(1, new FileInputStream(new File("xxx.mp3")));
d. 还有一个可选参数length,即流中的字节数;
iii. 最后提交insert into语句完成blob类型数据的导入;
3) 从数据库读取Blob类型数据:
i. ResultSet直接提供了getBlob方法:Blob getBlob(int columnIndex | String columnLabel);
ii. 可以看到Java直接提供了Blob类型;
4) Blob类型常用方法:
i. byte[] Blob.getBytes(long pos, int length); // 从blob对象的第pos个字节开始,复制出length个字节的byte数组返回,blob变量的第一个字节的位置是1不是0!!!
ii. long Blob.length(); // blob变量中共有多少个字节
2. 示例:图片数据库交互
1) 是一个Swing界面,右侧是一个图片名列表,显示当前数据库中存在的图片名,左侧是一个图片显示框,双击列表中的图片名就可以在显示框中显示图片;
2) 左下侧是一个文件按钮,点击可以在Windows资源管理内选择图片格式的文件,选中后图片的路径会显示在一个不可编辑的文本框内;
3) 点击upload按钮,可以将选中的图片文件导入到数据库,同时更新右侧列表中的内容;
首先需要在select_test数据库中加一张保存图片的表
create table img_table ( img_id int auto_increment primary key, img_name varchar(255), img_data mediumblob );
public class ImageHolder { // 封装图片名和ID private int id; private String name; public ImageHolder() {} public ImageHolder(int id, String name) { this.id = id; this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { // TODO Auto-generated method stub return name; } }
public class ExtensionFileFilter extends FileFilter { // 自行对FileFilter进行扩展 private String desc = ""; // 过滤器的描述文本 private ArrayList<String> exts = new ArrayList<>(); @Override public boolean accept(File f) { // 判断该过滤器是否该接受该文件 // TODO Auto-generated method stub if (f.isDirectory()) { return true; // 目录必定接受 } String name = f.getName().toLowerCase(); for (String ext: exts) { // 如果文件名以指定后缀结尾就接受 if (name.endsWith(ext)) { return true; } } return false; } @Override public String getDescription() { // TODO Auto-generated method stub return desc; } public void addExt(String ext) { // 向过滤器中添加扩展名 if (!ext.startsWith(".")) { // 给定的扩展名全部统一成以.开头的小写形式 ext = "." + ext; exts.add(ext.toLowerCase()); } } public void addExts(String[] exts) { // 用扩展名列表来添加扩展名 for (String ext: exts) { addExt(ext); } } public String getDesc() { return desc; } public void setDesc(String desc) { // 设置过滤器的描述文本 this.desc = desc; } }
public class BlobTest { // Connection private static Connection conn; private static PreparedStatement pstmtInsertImg; private static PreparedStatement pstmtQueryImg; private static PreparedStatement pstmtQueryAllImg; static { // 仅用来初始化连接资源 try { Properties props = new Properties(); props.load(new FileInputStream("mysql.ini")); String driver = props.getProperty("driver"); String url = props.getProperty("url"); String user = props.getProperty("user"); String pass = props.getProperty("pass"); Class.forName(driver); conn = DriverManager.getConnection(url, user, pass); pstmtInsertImg = conn.prepareStatement("insert into img_table values(null, ?, ?)", Statement.RETURN_GENERATED_KEYS); pstmtQueryImg = conn.prepareStatement("select img_data from img_table where img_id = ?"); pstmtQueryAllImg = conn.prepareStatement("select img_id, img_name from img_table"); } catch (Exception e) { e.printStackTrace(); } } // GUI private JFrame jf; private JPanel jpLeft; private JLabel jlImg; private JPanel jp; private JTextField jtFilePath; private JButton jbBrowser; private JButton jbUpload; private JList<ImageHolder> jliImgList; private DefaultListModel<ImageHolder> imgModel; // 文件选择器和过滤器 private JFileChooser chooser; private ExtensionFileFilter filter; public void initGUI() { jf = new JFrame("Pics Manager"); jpLeft = new JPanel(); jf.add(jpLeft); jpLeft.setLayout(new BorderLayout()); jlImg = new JLabel(); jpLeft.add(new JScrollPane(jlImg)); jp = new JPanel(); jpLeft.add(jp, BorderLayout.SOUTH); jtFilePath = new JTextField(26); jp.add(jtFilePath); jtFilePath.setEditable(false); // 文件路径编辑框只能显示不能编辑 jbBrowser = new JButton("..."); jp.add(jbBrowser); jbUpload = new JButton("upload"); jp.add(jbUpload); imgModel = new DefaultListModel<>(); jliImgList = new JList<>(imgModel); jf.add(new JScrollPane(jliImgList), BorderLayout.EAST); jliImgList.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION); // 列表只能单选(因为这里一次只能显示一张图片) jliImgList.setFixedCellWidth(160); jf.setSize(620, 400); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jf.setVisible(true); } public void showImage(int id) throws SQLException { // 给定图片ID在图片显示界面中显示出来 pstmtQueryImg.setInt(1, id); // 拿ID去查 try (ResultSet rs = pstmtQueryImg.executeQuery()) { if (rs.next()) { Blob img = rs.getBlob(1); // 获取blob图片 ImageIcon icon = new ImageIcon(img.getBytes(1L, (int)img.length())); // 转换成Icon类型 jlImg.setIcon(icon); // 加入到静态标签中 } } } public void updateListModel() throws SQLException { // 更新列表模型 try (ResultSet rs = pstmtQueryAllImg.executeQuery()) { // 重新查询 imgModel.clear(); // 先清空原来的模型 while (rs.next()) { // 然后再逐个添加ImageHolder(从数据库取出后包装) imgModel.addElement(new ImageHolder(rs.getInt(1), rs.getString(2))); } } } public void upload(String fileName) { // 将指定图片上传到数据库中 // 截取路径和扩展名作为数据库中图片的名称 String imgName = fileName.substring(fileName.lastIndexOf('\\') + 1, fileName.lastIndexOf('.')); File f = new File(fileName); // 为指定的图片(保存在磁盘中)创建一个节点 try (InputStream is = new FileInputStream(f)) { // 获取一个节点流 pstmtInsertImg.setString(1, imgName); pstmtInsertImg.setBinaryStream(2, is, (int)f.length()); // 作为输出流输出给数据库 int affect = pstmtInsertImg.executeUpdate(); if (affect == 1) { updateListModel(); // 成功上传则应该立即更新列表(列表显示的是当前数据库中的图片) } } catch (Exception e) { e.printStackTrace(); } } public void init() throws SQLException { // 初始化文件选择器 chooser = new JFileChooser("."); // 默认从当前路径开始查找 filter = new ExtensionFileFilter(); filter.addExts(new String[] {"jpg", "jpeg", "gif", "png"}); // 设置文件类型 filter.setDesc("Image file(*.jpg, *jpeg, *.gif, *.png)"); // 设置过滤器描述信息 chooser.addChoosableFileFilter(filter); // 为文件选择器绑定过滤器 chooser.setAcceptAllFileFilterUsed(false); // 将文件选择器中“显示所有文件”的选项关闭 // 初始化GUI界面 initGUI(); updateListModel(); // 先用数据库已有的图片初始化列表模型 // 注册监听器 jbBrowser.addActionListener(e -> { // 打开文件选择器对话框选择文件 int res = chooser.showDialog(jf, "Select an image to upload"); if (res == JFileChooser.APPROVE_OPTION) { jtFilePath.setText(chooser.getSelectedFile().getPath()); // 将选中的文件路径更新至路径编辑框中 } }); jbUpload.addActionListener(e -> { if (jtFilePath.getText().trim().length() > 0) { upload(jtFilePath.getText()); jtFilePath.setText(""); // 上传完毕后编辑框清空 } }); jliImgList.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { // TODO Auto-generated method stub if (e.getClickCount() >= 2) { // 双击选中列表中的文件则从数据库载入该图片并显示 ImageHolder selected = (ImageHolder)jliImgList.getSelectedValue(); try { showImage(selected.getId()); // 选中后直接显示 } catch (Exception ex) { ex.printStackTrace(); } } } }); } public static void main(String[] args) throws SQLException { // TODO Auto-generated method stub new BlobTest().init(); } }
mysql.ini
driver=com.mysql.jdbc.Driver url=jdbc:mysql://127.0.0.1:3306/select_test user=root pass=1234
相关文章推荐
- JAVA中的NIO(一)
- 常用查找算法的Java实现
- JAVA设计模式(02):创建型-抽象工厂模式(Abstract Factory)
- java虚拟机和Dalvik虚拟机
- Java字符串格式化记录
- 代码统计工具java 实现
- 如何在 Java 中正确使用 wait, notify 和 notifyAl
- 【Leetcode】:343. Integer Break 问题 in JAVA
- 20160420javaweb之文件上传和下载
- (转载)Java之外观模式(Facade Pattern)
- SpringMVC的几种返回方式
- struts2 xwork微观结构
- Spring 事务管理 DataSourceTransactionManager 和 DataSourceTransactionManager
- 贪吃蛇java源代码
- java.lang.NoClassDefFoundError;java.io.IOException: Cannot initialize Cluster.
- 浅析Spring事务传播行为和隔离级别
- SpringMVC中文乱码总结
- java中方法重载与重写的区别
- Netty中ChannelHandler共享数据的方式
- spring错误汇总