因连接关闭引起的Blob操作异常

本文探讨了在Java中处理数据库Blob字段的正确方式。通过对比不同场景下Blob对象的行为,揭示了在关闭数据库连接前后读取Blob数据的区别。指出Blob对象本质上是对数据库中数据的一种引用,而非直接的数据副本。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在处理结果集的时候,做了一个处理,把记录都处理成了Map的对象,而把结果集处理成了一个List对象。
如下:
public List<Map<String, Object>> toList() throws SQLException {

            List<Map<String,Object>> recordsList = new ArrayList<Map<String, Object>>();
       
            ResultSetMetaData meta = rst.getMetaData();
            int colCnt = meta.getColumnCount();
           
            while(rst.next()){
               
                Map<String,Object> record = new HashMap<String, Object>();
               
                for(int i=0;i<colCnt;i++){
                    String colName = meta.getColumnName(i+1);
                    Object colValue = rst.getObject(colName);
                    log.debug(colValue);
                    if(colValue instanceof Blob){
                        log.debug("blob type");
                    }else{
                        record.put(colName, colValue);
                    }
                   
                }
               
                recordsList.add(record);
            }      
              
            return recordsList;
        }

之后,就关闭了resultset ,statement ,connection。然而在我从map对象里面取得blob对象时,总是报SQLException异常。经过调试,发现在blob.getBinaryStream()时发生异常。

无奈之下做了一个试验。

PreparedStatement stmt = null;
//        ResultSet rst = null;
//
//        try {
//            stmt = this.con
//                    .prepareStatement("SELECT * FROM CCX_INFO_ARTICAL WHERE ARTICAL_ID=?");
//            stmt.setLong(1, articalId);
//
//            rst = stmt.executeQuery();
//            if(rst.next()){
//                Blob b = rst.getBlob("ARTICAL_CONTENT");
//                log.debug(b);
////                InputStream in = b.getBinaryStream();
//               
//               
//               
//               
//                log.debug(in);
//               
//            }
//
//        } catch (SQLException e) {
//            throw e;
//        } finally {
//            rst.close();
//            if (stmt != null) {
//                stmt.close();
//            }
//            if (this.con != null && this.con.getAutoCommit()) {
//                this.con.close();
//            }
//        }
//

此段代码可以顺利的无异常的执行。由此我推测认为,主要是因为 resultset ,connection关闭引起的。这说明,在执行了查询操作之后,
我们虽然可以得到一个blob对象,但是实际的内容并没有读如内存,也就是说,并没有读如到blob对象中,而此blob对象也就相当于一个对数据库中blob字段操作的一个引用,所以,此时,如果想从blob字段中读取数据,还是需要数据库连接的。

而上面的封装操作之后,数据库连接已经中断,所以,再读取数据时,就发生了异常。


下面是Blob接口的说明,也许能给我们更好的解释.

public interface Blob

SQL BLOB 值在 JavaTM 编程语言中的表示形式(映射关系)。SQL BLOB 是内置类型,它将 Binary Large Object 存储为数据库表的某一行中的一个列值。默认情况下,驱动程序使用 SQL locator(BLOB) 实现 Blob,这意味着 Blob 对象包含一个指向 SQL BLOB 数据而不是数据本身的逻辑指针。Blob 对象在它被创建的事务处理期间有效。

接口 ResultSetCallableStatementPreparedStatement 中的方法(如 getBlobsetBlob)允许编程人员访问 SQL BLOB 值。Blob 接口提供某些方法来获得 SQL BLOB (Binary Large Object) 值的长度、在客户端实现 BLOB 值以及确定 BLOB 值中某一字节样本的位置。此外,此接口还拥有更新 BLOB 值的方法。

import time, os, gc, sys from media.sensor import * from media.display import * from media.media import * from machine import UART import time from machine import PWM, FPIOA #servo CONSTRUCT_WITH_FPIOA = False PWM1_CHANNEL = 0 PWM1_PIN = 39 TEST_FREQ1 = 50 # Hz PWM2_CHANNEL = 0 PWM2_PIN = 40 TEST_FREQ2 = 50 # Hz #image DETECT_WIDTH = ALIGN_UP(320, 16) DETECT_HEIGHT = 240 sensor = None color_threshold =(71, 100, -15, 15, -34, -3) #color_threshold =((97, 100, -14, -4, -45, -2)) def camera_init(): global sensor # construct a Sensor object with default configure sensor = Sensor(width=DETECT_WIDTH,height=DETECT_HEIGHT) # sensor reset sensor.reset() # set hmirror # sensor.set_hmirror(False) # sensor vflip # sensor.set_vflip(False) # set chn0 output size sensor.set_framesize(width=DETECT_WIDTH,height=DETECT_HEIGHT) # set chn0 output format sensor.set_pixformat(Sensor.RGB565) # use IDE as display output Display.init(Display.VIRT, width= DETECT_WIDTH, height = DETECT_HEIGHT,fps=100,to_ide = True) # init media manager MediaManager.init() # sensor start run sensor.run() #######################image_function def camera_deinit(): global sensor # sensor stop run sensor.stop() # deinit display Display.deinit() # sleep os.exitpoint(os.EXITPOINT_ENABLE_SLEEP) time.sleep_ms(100) # release media buffer MediaManager.deinit() def find_min_b(blobs): min_size=1000000 for blob in blobs: if min_size > blob[2]*blob[3] : min_blob=blob min_size = blob[2]*blob[3] return min_blob def find_max_c(circles): max_size=0 for circle in circles: if circle[3] > max_size: max_circle=circle max_size = circle[3] return max_circle def find_max_r(rects): max_size=0 for rect in rects: if rect[2]*rect[3] > max_size: max_rect=rect max_size = rect[2]*rect[3] return max_rect def capture_picture(): fps = time.clock() u1 = UART(UART.UART1, baudrate=115200, bits=UART.EIGHTBITS, parity=UART.PARITY_NONE, stop=UART.STOPBITS_ONE) fps.tick() try: os.exitpoint() global sensor img = sensor.snapshot() # `threshold` below should be set to a high enough value to filter out noise # rectangles detected in the image which have low edge magnitudes. Rectangles # have larger edge magnitudes the larger and more contrasty they are... for c in img.find_circles(threshold = 10000): #img.draw_circle([v for v in r.circle()], color = (255, 0, 0)) img.draw_circle(c.x(), c.y(), c.r(), color=(255,0,0)) #for p in r.corners(): img.draw_circle(p[0], p[1], 5, color = (0, 255, 0)) img.draw_cross(c.x(), c.y(),color = (255, 0, 0)) print(c) u1.write(f"{c.x()},{c.y()}") #for r in img.find_rects(threshold = 10000): # img.draw_rectangle([v for v in r.rect()], color = (255, 255, 255)) # #for p in r.corners(): img.draw_circle(p[0], p[1], 5, color = (0, 255, 0)) # print(r) rects=img.find_rects(threshold = 50) if rects: global max_rect max_rect= find_max_r(rects) img.draw_rectangle([v for v in max_rect.rect()], color = (255, 255, 255)) blobs = img.find_blobs([color_threshold],roi=max_rect.rect(),merge=True,pixels_threshold=2,area_threshold=2) if blobs: max_blob = find_min_b(blobs)#调用函数,返回最大色块 #img.draw_circle(80,60,5,color=200) img.draw_circle(max_blob.cx(),max_blob.cy(),10,color=200) img.draw_rectangle((max_blob.x(),max_blob.y(),max_blob.w(),max_blob.h()),color=(255,0,0))#用红色框出最大色块 img.draw_string(0,0, "(x,y) =") img.draw_string(max_blob.x()+40,max_blob.y(), str(max_blob.cx())) img.draw_string(max_blob.x()+60,max_blob.y(), str(max_blob.cy()))#在框图显示色块的中心坐标 img.draw_string(40,0, str(max_blob.cx())) img.draw_string(60,0, str(max_blob.cy()))#在框图左上角显示色块的中心坐标 # draw result to screen Display.show_image(img) img = None gc.collect() print(fps.fps()) #############################servo_function def servo_control(): try: if CONSTRUCT_WITH_FPIOA: # 使用FPIOA 配置引脚复用为PWM, 构造时传入 channel fpioa = FPIOA() fpioa.set_function(PWM_PIN, fpioa.PWM0 + PWM_CHANNEL) pwm = PWM(PWM_CHANNEL, freq=TEST_FREQ, duty=50) else: # 直接传入引脚 pwm1 = PWM(PWM1_PIN, freq=TEST_FREQ1, duty=0.025) pwm2 = PWM(PWM2_PIN, freq=TEST_FREQ2, duty=0.025) #except Exception: # print("FPIOA setup skipped or failed") def main(): os.exitpoint(os.EXITPOINT_ENABLE) camera_is_init = False try: print("camera init") camera_init() camera_is_init = True print("camera capture") while True: capture_picture() servo_control() except KeyboardInterrupt as e: print("user stop: ", e) break except BaseException as e: print(f"Exception {e}") break except Exception as e: print(f"Exception {e}") finally: if camera_is_init: print("camera deinit") camera_deinit() if __name__ == "__main__": main() 修改这段代码中的语法错误
最新发布
07-31
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值