Jdbc Mybatis自定义类型处理程序:在执行查询后调用FileInputStream.close()

Jdbc Mybatis自定义类型处理程序:在执行查询后调用FileInputStream.close(),jdbc,mybatis,Jdbc,Mybatis,我正在尝试使用FileInputStream为文件实现MyBatis自定义类型处理程序 以下是我的设置代码: @MappedJdbcTypes(JdbcType.LONGVARBINARY) public class FileByteaHandler extends BaseTypeHandler<File> { @Override public void setNonNullParameter(PreparedStatement ps, int i, File file,

我正在尝试使用FileInputStream为文件实现MyBatis自定义类型处理程序

以下是我的设置代码:

@MappedJdbcTypes(JdbcType.LONGVARBINARY)
public class FileByteaHandler extends BaseTypeHandler<File> {
  @Override
  public void setNonNullParameter(PreparedStatement ps, int i, File file, JdbcType jdbcType) throws SQLException{
    try {

        FileInputStream  fis = new FileInputStream(file);
        ps.setBinaryStream(1, fis, (int) file.length());           

    } catch(FileNotFoundException ex) {
        Logger.getLogger(FileByteaHandler.class.getName()).log(Level.SEVERE, null, ex);
    }
  }
@MappedJdbcTypes(JdbcType.LONGVARBINARY)
公共类FileByteHandler扩展了BaseTypeHandler{
@凌驾
public void setNonNullParameter(PreparedStatement ps,int i,File File,JdbcType JdbcType)引发SQLException{
试一试{
FileInputStream fis=新的FileInputStream(文件);
ps.setBinaryStream(1,fis,(int)file.length());
}捕获(FileNotFoundException ex){
Logger.getLogger(FileByteaHandler.class.getName()).log(Level.SEVERE,null,ex);
}
}
}

我的问题是:

我无法在此方法结束时关闭此FileInputStream,否则MyBatis将无法从中读取数据。事实上,我不知道在哪里可以关闭FileInputStream。在MyBatis中执行查询后,是否有方法调用close()

提前感谢,

更新

谢谢贾兰迪诺的帮助。这是我的这个类型处理程序的代码。希望它能帮助某人:

@MappedJdbcTypes(JdbcType.LONGVARBINARY)
public class FileByteaHandler extends BaseTypeHandler<File> {

@Override
public void setNonNullParameter(PreparedStatement ps, int i, File file, JdbcType jdbcType) throws SQLException {
    try {
        AutoCloseFileInputStream fis = new AutoCloseFileInputStream(file);
        ps.setBinaryStream(1, fis, (int) file.length());

    } catch(FileNotFoundException ex) {
        Logger.getLogger(FileByteaHandler.class.getName()).log(Level.SEVERE, null, ex);
    }
}

@Override
public File getNullableResult(ResultSet rs, String columnName) throws SQLException {
    File file = null;

    try(InputStream input = rs.getBinaryStream(columnName)) {
        file = getResult(rs, input);
    } catch(IOException e) {
        System.out.println(e.getMessage());
    }
    return file;
}

public File creaetFile() {
    File file = new File("e:/target-file");    //your temp file path
    return file;
}

private File getResult(ResultSet rs, InputStream input) throws SQLException {
    File file = creaetFile();

    try(OutputStream output = new FileOutputStream(file)) {
        int bufSize = 0x8000000;
        byte buf[] = new byte[bufSize];
        int s = 0;
        int tl = 0;

        while( (s = input.read(buf, 0, bufSize)) > 0 ) {
            output.write(buf, 0, s);
            tl += s;
        }
        output.flush();
    } catch(IOException e) {
        System.out.println(e.getMessage());
    }
    return file;
}

@Override
public File getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
    File file = null;

    try(InputStream input = rs.getBinaryStream(columnIndex)) {
        file = getResult(rs, input);
    } catch(IOException e) {
        System.out.println(e.getMessage());
    }

    return file;
}

@Override
public File getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
    throw new SQLException("getNullableResult(CallableStatement cs, int columnIndex) is called");
}

private class AutoCloseFileInputStream extends FileInputStream {

    public AutoCloseFileInputStream(File file) throws FileNotFoundException {
        super(file);
    }

    @Override
    public int read() throws IOException {
        int c = super.read();
        if(available() <= 0) {
            close();
        }
        return c;
    }

    public int read(byte[] b) throws IOException {
        int c = super.read(b);
        if(available() <= 0) {
            close();
        }
        return c;
    }

    public int read(byte[] b, int off, int len) throws IOException {
        int c = super.read(b, off, len);
        if(available() <= 0) {
            close();
        }
        return c;
    }
}
}


    public AutoCloseFileInputStream(File file) throws FileNotFoundException {
        super(file);
    }

    @Override
    public int read() throws IOException {
        int c = super.read();
        if( c == -1 ) {
            close();
        }
        return c;
    }

    public int read(byte[] b) throws IOException {
        int c = super.read(b);
        if( c == -1 ) {
            close();
        }
        return c;
    }

    public int read(byte[] b, int off, int len) throws IOException {
        int c = super.read(b, off, len);
        if(available() <= 0) {
            close();
        }
        return c;
    }
}
@MappedJdbcTypes(JdbcType.LONGVARBINARY)
公共类FileByteHandler扩展了BaseTypeHandler{
@凌驾
public void setNonNullParameter(PreparedStatement ps,int i,File File,JdbcType JdbcType)引发SQLException{
试一试{
AutoCloseFileInputStream fis=新的AutoCloseFileInputStream(文件);
ps.setBinaryStream(1,fis,(int)file.length());
}捕获(FileNotFoundException ex){
Logger.getLogger(FileByteaHandler.class.getName()).log(Level.SEVERE,null,ex);
}
}
@凌驾
公共文件getNullableResult(ResultSet rs,String columnName)引发SQLException{
File=null;
try(InputStream输入=rs.getBinaryStream(columnName)){
文件=获取结果(rs,输入);
}捕获(IOE异常){
System.out.println(e.getMessage());
}
返回文件;
}
公共文件creaetFile(){
File File=new File(“e:/target File”);//临时文件路径
返回文件;
}
私有文件getResult(ResultSet rs,InputStream input)引发SQLException{
File=creaetFile();
try(OutputStream输出=新文件OutputStream(文件)){
int bufSize=0x8000000;
字节buf[]=新字节[bufSize];
int s=0;
int-tl=0;
而((s=input.read(buf,0,bufSize))>0){
输出写入(buf,0,s);
tl+=s;
}
output.flush();
}捕获(IOE异常){
System.out.println(e.getMessage());
}
返回文件;
}
@凌驾
公共文件getNullableResult(ResultSet rs,int columnIndex)引发SQLException{
File=null;
try(InputStream输入=rs.getBinaryStream(columnIndex)){
文件=获取结果(rs,输入);
}捕获(IOE异常){
System.out.println(e.getMessage());
}
返回文件;
}
@凌驾
公共文件getNullableResult(CallableStatement cs,int columnIndex)引发SQLException{
抛出新的SQLException(“调用getNullableResult(CallableStatement cs,int columnIndex));
}
私有类AutoCloseFileInputStream扩展FileInputStream{
公共AutoCloseFileInputStream(文件文件)引发FileNotFoundException{
超级(文件);
}
@凌驾
public int read()引发IOException{
int c=super.read();

if(available()我不知道在查询执行后关闭流的好方法

方法1: 将文件读取到字节[] (注意:在jdk 7中,您可以使用
文件.readAllBytes(path.get(file.getPath());
) 和使用:
ps.setBytes(i,字节);

2:或创建从
FileInputStream
继承的您自己的类,并重写
public native int read()抛出IOException;
方法,当到达文件末尾时,关闭流:

@覆盖
public int read()引发IOException{
int c=super.read();
如果(c==-1){
super.close();
}
返回c;
}
也许您应该重写并
public int read(byte[]b)抛出IOException
, 这取决于jdbc实现

3:您可以更改您的
FileByteaHandler
: 1) 添加
FileInputStream
字段列表; 2) 将打开的InputStream放入
setNonNullParameter
中的该列表; 3) 添加
closeStreams()
方法,在其中关闭并从列表中删除所有InputStream。 并在调用映射器方法后调用此方法:
session.getConfiguration().getTypeHandlerRegistry().getMappingTypeHandler(fileByteHandler.class).closeStreams();

或者使用mybatis插件系统运行上述命令。

我不知道在查询执行后关闭流的好方法

方法1: 将文件读取到字节[] (注意:在jdk 7中,您可以使用
文件.readAllBytes(path.get(file.getPath());
) 和使用:
ps.setBytes(i,字节);

2:或创建从
FileInputStream
继承的您自己的类,并重写
public native int read()抛出IOException;
方法,当到达文件末尾时,关闭流:

@覆盖
public int read()引发IOException{
int c=super.read();
如果(c==-1){
super.close();
}
返回c;
}
也许您应该重写并
public int read(byte[]b)抛出IOException
, 这取决于jdbc实现

3:您可以更改您的
FileByteaHandler
: 1) 添加
FileInputStream
字段列表; 2) 将打开的InputStream放入
setNonNullParameter
中的该列表; 3) 添加
closeStreams()
方法,在其中关闭并从列表中删除所有InputStream。 并在调用映射器方法后调用此方法:
session.getConfiguration().getTypeHandlerRegistry().getMappingTypeHandler(fileByteHandler.class).closeStreams();
或者使用mybatis插件系统运行