13.5.2 处理Blob类型数据
Blob(Binary Long Object)
是二进制长对象的意思,Blob
列通常用于存储大文件,典型的Blob
内容是一张图片或一个声音文件,由于它们的特殊性,必须使用特殊的方式来存储。使用Blob
列可以把图片、声音等文件的二进制数据保存在数据库里,并可以从数据库里恢复指定文件。
如果需要将图片插入数据库,显然不能直接通过普通的SQL
语句来完成,因为有一个关键的问题: Blob
常量无法表示。所以将Blob
数据插入数据库需要使用PreparedStatement
,该对象有一个方法:setBinaryStream(int parameterIndex, InputStream x)
,该方法可以为指定参数传入二进制输入流,从而可以实现将Blob
数据保存到数据库的功能。
当需要从ResultSet
里取出Blob
数据时,可以调用ResultSet
的getBlob( int columnIndex)
方法,该方法将返回一个Blob
对象,Blob
对象提供了getBinaryStream()
方法来获取该Blob
数据的输入流,也可以使用Blb
对象提供的getBytes()
方法直接取出该Blob
对象封装的二进制数据。
为了把图片放入数据库,本程序先使用如下SQL
语句来建立一个数据表。
1 2 3 4 5 6
| create table img_table ( img_id int auto_increment primary key, img_name varchar(255), img_data mediumblob );
|
上面SQL
语句中的img_data
列使用mediumblob
类型,而是blob
类型。因为MySQL
数据库里的blob
类型最多只能存储64KB
内容,这可能不够满足实际用途。所以使用mediumblob
类型,该类型的数据列可以存储16MB
内容.
下面程序可以实现图片”上传”——实际上就是将图片保存到数据库,并在右边的列表框中显示图片的名字,
当用户双击列表框中的图片名时,左边窗口将显示该图片—实质就是根据选中的ID
从数据库里查找图片,并将其显示出来。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278
| import java.sql.*; import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.util.Properties; import java.util.ArrayList; import java.io.*; import javax.swing.filechooser.FileFilter;
public class BlobTest { JFrame jf = new JFrame("图片管理程序"); private static Connection conn; private static PreparedStatement insert; private static PreparedStatement query; private static PreparedStatement queryAll; private DefaultListModel<ImageHolder> imageModel = new DefaultListModel<>(); private JList<ImageHolder> imageList = new JList<>(imageModel); private JTextField filePath = new JTextField(26); private JButton browserBn = new JButton("..."); private JButton uploadBn = new JButton("上传"); private JLabel imageLabel = new JLabel(); JFileChooser chooser = new JFileChooser("."); ExtensionFileFilter filter = new ExtensionFileFilter(); 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); insert = conn.prepareStatement( "insert into img_table" + " values(null,?,?)", Statement.RETURN_GENERATED_KEYS); query = conn.prepareStatement( "select img_data from img_table" + " where img_id=?"); queryAll = conn.prepareStatement( "select img_id, " + " img_name from img_table"); } catch (Exception e) { e.printStackTrace(); } } public void init() throws SQLException { filter.addExtension("jpg"); filter.addExtension("jpeg"); filter.addExtension("gif"); filter.addExtension("png"); filter.setDescription("图片文件(*.jpg,*.jpeg,*.gif,*.png)"); chooser.addChoosableFileFilter(filter); chooser.setAcceptAllFileFilterUsed(false); fillListModel(); filePath.setEditable(false); imageList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); JPanel jp = new JPanel(); jp.add(filePath); jp.add(browserBn); browserBn.addActionListener(event -> { int result = chooser.showDialog(jf, "浏览图片文件上传"); if (result == JFileChooser.APPROVE_OPTION) { filePath.setText(chooser.getSelectedFile().getPath()); } }); jp.add(uploadBn); uploadBn.addActionListener(avt -> { if (filePath.getText().trim().length() > 0) { upload(filePath.getText()); filePath.setText(""); } }); JPanel left = new JPanel(); left.setLayout(new BorderLayout()); left.add(new JScrollPane(imageLabel), BorderLayout.CENTER); left.add(jp, BorderLayout.SOUTH); jf.add(left); imageList.setFixedCellWidth(160); jf.add(new JScrollPane(imageList), BorderLayout.EAST); imageList.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { if (e.getClickCount() >= 2) { ImageHolder cur = (ImageHolder) imageList .getSelectedValue(); try { showImage(cur.getId()); } catch (SQLException sqle) { sqle.printStackTrace(); } } } }); jf.setSize(620, 400); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jf.setVisible(true); } public void fillListModel() throws SQLException {
try ( ResultSet rs = queryAll.executeQuery()) { imageModel.clear(); while (rs.next()) { imageModel.addElement( new ImageHolder(rs.getInt(1), rs.getString(2))); } } } public void upload(String fileName) { String imageName = fileName.substring(fileName.lastIndexOf('\\') + 1, fileName.lastIndexOf('.')); File f = new File(fileName); try (InputStream is = new FileInputStream(f)) { insert.setString(1, imageName); insert.setBinaryStream(2, is, (int) f.length()); int affect = insert.executeUpdate(); if (affect == 1) { fillListModel(); } } catch (Exception e) { e.printStackTrace(); } } public void showImage(int id) throws SQLException { query.setInt(1, id); try ( ResultSet rs = query.executeQuery()) { if (rs.next()) { Blob imgBlob = rs.getBlob(1); ImageIcon icon = new ImageIcon( imgBlob.getBytes(1L, (int) imgBlob.length())); imageLabel.setIcon(icon); } } } public static void main(String[] args) throws SQLException { new BlobTest().init(); } }
class ExtensionFileFilter extends FileFilter { private String description = ""; private ArrayList<String> extensions = new ArrayList<>(); public void addExtension(String extension) { if (!extension.startsWith(".")) { extension = "." + extension; extensions.add(extension.toLowerCase()); } } public void setDescription(String aDescription) { description = aDescription; } public String getDescription() { return description; } public boolean accept(File f) { if (f.isDirectory()) return true; String name = f.getName().toLowerCase(); for (String extension : extensions) { if (name.endsWith(extension)) { return true; } } return false; } }
class ImageHolder { private int id; private String name; public ImageHolder() { } public ImageHolder(int id, String name) { this.id = id; this.name = name; } public void setId(int id) { this.id = id; } public int getId() { return this.id; } public void setName(String name) { this.name = name; } public String getName() { return this.name; } public String toString() { return name; } }
|
下面是一个简单的查询执行器,当用户在文本框内输入合法的查询语句并执行成功后,下面的表格将会显示查询结果。
原文链接: 13.5.2 处理Blob类型数据