• LobHandler和LobCreator


    处理 BLOB 和 CLOB 对象

    您可以在数据库中存储图像,其他二进制数据和大块文本。这些大对象称为二进制数据的 BLOB(二进制大型对象),而字符数据称为 CLOB(字符大型对象)。在 Spring 中,可以直接使用JdbcTemplate来处理这些大对象,也可以使用 RDBMS Objects 和SimpleJdbc类提供的更高抽象来处理这些大对象。所有这些方法都将LobHandler接口的实现用于 LOB(大对象)数据的实际 Management。 LobHandler通过getLobCreator方法提供对LobCreator类的访问,该方法用于创建要插入的新 LOB 对象。

    LobCreatorLobHandler为 LOBImporting 和输出提供以下支持:

    • BLOB
    • byte[]getBlobAsBytessetBlobAsBytes
      • InputStreamgetBlobAsBinaryStreamsetBlobAsBinaryStream
    • CLOB
    • StringgetClobAsStringsetClobAsString
      • InputStreamgetClobAsAsciiStreamsetClobAsAsciiStream
      • ReadergetClobAsCharacterStreamsetClobAsCharacterStream

    下一个示例显示了如何创建和插入 BLOB。稍后,我们展示如何从数据库中读取它。

    本示例使用JdbcTemplateAbstractLobCreatingPreparedStatementCallback的实现。它实现了一种方法setValues。此方法提供LobCreator,我们可以用来设置 SQL 插入语句中 LOB 列的值。

    对于此示例,我们假设存在一个变量lobHandler,该变量已设置为DefaultLobHandler的实例。通常,您可以通过依赖注入来设置此值。

    以下示例显示如何创建和插入 BLOB:

    final File blobIn = new File("spring2004.jpg");
    final InputStream blobIs = new FileInputStream(blobIn);
    final File clobIn = new File("large.txt");
    final InputStream clobIs = new FileInputStream(clobIn);
    final InputStreamReader clobReader = new InputStreamReader(clobIs);
    
    jdbcTemplate.execute(
        "INSERT INTO lob_table (id, a_clob, a_blob) VALUES (?, ?, ?)",
        new AbstractLobCreatingPreparedStatementCallback(lobHandler) {  (1)
            protected void setValues(PreparedStatement ps, LobCreator lobCreator) throws SQLException {
                ps.setLong(1, 1L);
                lobCreator.setClobAsCharacterStream(ps, 2, clobReader, (int)clobIn.length());  (2)
                lobCreator.setBlobAsBinaryStream(ps, 3, blobIs, (int)blobIn.length());  (3)
            }
        }
    );
    
    blobIs.close();
    clobReader.close();
    
    • (1) 传递lobHandler(在此示例中)为普通DefaultLobHandler
    • (2) 使用方法setClobAsCharacterStream传递 CLOB 的内容。
    • (3) 使用方法setBlobAsBinaryStream传入 BLOB 的内容。

    如果在从DefaultLobHandler.getLobCreator()返回的LobCreator上调用setBlobAsBinaryStreamsetClobAsAsciiStreamsetClobAsCharacterStream方法,则可以选择为contentLength参数指定负值。如果指定的内容长度为负数,则DefaultLobHandler使用不带 length 参数的 set-stream 方法的 JDBC 4.0 变体。否则,它将指定的长度传递给驱动程序。

    现在是时候从数据库中读取 LOB 数据了。同样,您使用具有相同实例变量lobHandlerJdbcTemplate和对DefaultLobHandler的引用。以下示例显示了如何执行此操作:

    List<Map<String, Object>> l = jdbcTemplate.query("select id, a_clob, a_blob from lob_table",
        new RowMapper<Map<String, Object>>() {
            public Map<String, Object> mapRow(ResultSet rs, int i) throws SQLException {
                Map<String, Object> results = new HashMap<String, Object>();
                String clobText = lobHandler.getClobAsString(rs, "a_clob");  (1)
                results.put("CLOB", clobText);
                byte[] blobBytes = lobHandler.getBlobAsBytes(rs, "a_blob");  (2)
                results.put("BLOB", blobBytes);
                return results;
            }
        });
    
    • (1) 使用方法getClobAsString检索 CLOB 的内容。

    • (2) 使用方法getBlobAsBytes检索 BLOB 的内容。

    示例代码

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(classes = SpringConfiguration.class)
    public class SpringLobTest {
    
        @Autowired
        private JdbcTemplate jdbcTemplate;
    
        @Autowired
        private LobHandler lobHandler;
    
        @Test
        public void testWrite(){
            try {
                //准备images的字节数组
                Resource resource = new FileSystemResource("C:\Users\zhy\Desktop\6.jpg");
                byte[] images = FileCopyUtils.copyToByteArray(resource.getFile());
                //准备description
                String description = "BLOB (binary large object),二进制大对象,是一个可以存储二进制文件的容器。
    " +
                        "在计算机中,BLOB常常是数据库中用来存储二进制文件的字段类型。
    " +
                        "BLOB是一个大文件,典型的BLOB是一张图片或一个声音文件,
    " +
                        "由于它们的尺寸,必须使用特殊的方式来处理(例如:上传、下载或者存放到一个数据库)。
    " +
                        "根据Eric Raymond的说法,处理BLOB的主要思想就是让文件处理器(如数据库管理器)不去理会文件是什么,
    " +
                        "而是关心如何去处理它。但也有专家强调,这种处理大数据对象的方法是把双刃剑,
    " +
                        "它有可能引发一些问题,如存储的二进制文件过大,会使数据库的性能下降。
    " +
                        "在数据库中存放体积较大的多媒体对象就是应用程序处理BLOB的典型例子。";
                //1.创建Userinfo
                Userinfo userinfo = new Userinfo();
                userinfo.setImages(images);
                userinfo.setDescription(description);
    
                jdbcTemplate.execute("insert into userinfo(images,description)values(?,?)", new AbstractLobCreatingPreparedStatementCallback(lobHandler) {
                    @Override
                    protected void setValues(PreparedStatement ps, LobCreator lobCreator) throws SQLException, DataAccessException {
                        lobCreator.setBlobAsBytes(ps, 1, userinfo.getImages());
                        lobCreator.setClobAsString(ps, 2, userinfo.getDescription());
                    }
                });
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    
        @Test
        public void testRead(){
            Userinfo userinfo = jdbcTemplate.query("select * from userinfo where id = ?", new ResultSetExtractor<Userinfo>() {
                @Override
                public Userinfo extractData(ResultSet rs) throws SQLException, DataAccessException {
                    Userinfo userinfo1 = null;
                    if(rs.next()){
                        userinfo1 = new Userinfo();
                        userinfo1.setId(rs.getInt("id"));
                        userinfo1.setImages(lobHandler.getBlobAsBytes(rs,"images"));
                        userinfo1.setDescription(lobHandler.getClobAsString(rs,"description"));
                    }
                    return userinfo1;
                }
            }, 1);
            System.out.println(userinfo);
        }
    }
    
    

    image-20200924165710774

    image-20200924170737244

  • 相关阅读:
    JS高级
    函数作用域面试题
    11.14
    11.13
    Redux知识
    react-router-dom
    react 的三大属性
    vuex
    数组的扩展
    函数作用域和 class
  • 原文地址:https://www.cnblogs.com/dalianpai/p/13725105.html
Copyright © 2020-2023  润新知