Jdbc Mybatis自定义类型处理程序:在执行查询后调用FileInputStream.close()
我正在尝试使用FileInputStream为文件实现MyBatis自定义类型处理程序 以下是我的设置代码: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,
@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插件系统运行