catch(SQLException ex)
{
out.print(ex.getMessage());
}
}
}
%>
</body>
</html>
5.4Oracle大文本列的全文搜索
在Oracle中,大量的文本数据通常存储在大文本(CLOB)类型的列中,Oracle的全文搜索专门对它提供了支持。
5.4.1CLOB的读写方法
本节首先介绍如何读取CLOB中的内容,以及如何向其中写入内容。
首先,创建一个测试表,含有ID和body两个字段,其中body字段为CLOB类型,运行语句如下所示:
CREATE TABLE myclob
(
ID NUMBER PRIMARY KEY,
bodyCLOB
);
commit;
然后,向表格中写入数据。运行语句如下所示:
insert into myclob values(1,empty clob());
insert into myclob values(2,empty clob());
commit;
要注意,操作CLOB类型不同于varchar类型,要先插入emptyclob(),然后再修改这一列的值。
建立如下PL/SQL过程:
declare
v lobloc clob;
v text VARCHAR2(500):="我爱你!中国!古老伟大的祖国!′;
v amount INT;
v offset INT;
begin
select body into v lobloc from myclob where id=1for update;
v offset:=dbms lob.getlength(v lobloc)+1;
v amount:=length(v text);
dbms lob.write(v lobloc,v amount,v offset,v text);
commit;
end;
这是修改表中的第一行数据,向CLOB类型列中插入数据“我爱你!中国!古老伟大的祖国!”。
5.4.2CLOB的搜索
现在,创建索引,语句如下:
create index idx myclob on myclob(body)indextype is ctxsys.context;
commit;
使用CONTAINS函数测试索引,发出基于内容的文档查询,例如:
select id,body from myclob where contains(body,"中国")>0;
使用如下语句,运行的结果将更加明显:
select id ||substr(body,0,7)from myclob where contains(body,"中国")>0;
5.5Oracle大二进制列的全文搜索
在Oracle中,使用大二进制(BLOB)类型来存储二进制数据,比如Word文档,PDF文档,HTML文档等。Oracle对许多格式的数据都提供了很好的全文搜索支持。本节先介绍如何读写BLOB类型数据,然后介绍如何对它实现全文搜索。
5.5.1BLOB的读写方法
本节首先介绍如何读取CLOB中的内容,以及如何向其中写入内容。
首先,创建一个测试表,含有id,fname和fblob三个字段。id是文档序号,fname是文档的名称,fblob存储文档的二进制内容。运行语句如下所示:
create table myblob
(
id number,
fname varchar2(50),
fblob blob
);
现在,通过一个Java程序,实现向数据表中写入二进制数据。程序代码如下。
案例名称:二进制数据的写入
程序名称:OracleInput.java
import java.util.*;
import java.io.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.sql.*;
import oracle.jdbc.OracleResultSet;//使用Oracle的ResultSet对象
import oracle.sql.BLOB;//使用Oracle的BLOB对象,而不是Sun的Blob
public class OracleInput
{
public static void main(String[] args)
{
…Connection conn=null;
Statement stmt=null;
ResultSet rs=null;
try
{
Class.forName("oracle.jdbc.driver.OracleDriver");
}
catch(ClassNotFoundException ce)
{
System.out.println(ce.getMessage());
}
try
{
//获得Connection对象
String url="jdbc:oracle:thin:@ localhost:1521:yuanyuan";
conn=DriverManager.getConnection(url,"scott","tiger");
File file=new File("d:/test/大禹.doc");
conn.setAutoCommit(false);//取消Connection对象的auto commit属性
String fname=file.getName();
//使用EMPTYBLOB()成生一个空blob
int id=0;//每插入一行的时候需要修改这个值
String sql="INSERT INTO myblob(id,fname,fblob)VALUES("+id+",′"+fname+"",EMPTYBLOB())";
stmt=conn.createStatement();
int count=stmt.executeUpdate(sql);
sql="SELECT fblob FROM myblob WHERE id="+id+"FOR UPDATE";//使用FOR UPDATE得到表的写锁
rs=stmt.executeQuery(sql);
rs.next();
BLOB blob=((OracleResultSet)rs).getBLOB("fblob");//得到BLOB对象
OutputStream out=blob.getBinaryOutputStream();//建立输出流
InputStream in=new FileInputStream(file);//建立输入流
int size=blob.getBufferSize();
byte[] buffer=new byte[size];//建立缓冲区
int len;
while((len=in.read(buffer))!=-1)
{
out.write(buffer,0,len);
}
in.close();
out.close();
conn.commit();
System.out.print("二进制数据写入成功!");
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
finally
{
if(rs!=null)
{
try
{
rs.close();
}
catch(SQLException ee)
{
System.out.println(ee.getMessage());
}
}
if(stmt!=null)
{
try
{
stmt.close();
}
catch(SQLException ee)
{
System.out.println(ee.getMessage());
}
}
if(conn!=null)
{
try
{
conn.close();
}
catch(SQLException ee)
{
System.out.println(ee.getMessage());
}
}
}
}
}
重复执行刚才的过程,修改文件的名称和数据库id值。然后查看MYBLOB表格的内容。注意:在表格中没有显示出BLOB类型列,这是Oracle的设定。
现在读取BLOB列中的内容。以下程序读取了第一行数据,将“大禹.doc”的内容显示出来。
案例名称:二进制数据的读取
程序名称:showword.jsp
<%@ page contentType="text/html;charset=gbk"%>
<%@ page import="java.sql.*,java.io.*"%>
<%!
Connection conn=null;
Statement stmt=null;
ResultSet rs=null;
%>
<%
//安装驱动程序——
try
{
071做自己的搜索引擎——搜索引擎精解案例教程
Class.forName("oracle.jdbc.driver.OracleDriver");
}
catch(ClassNotFoundException ce)
{
out.println(ce.getMessage());
}
//执行——
try
{
//获得Connection对象
String url="jdbc:oracle:thin:@ localhost:1521:yuanyuan";
conn=DriverManager.getConnection(url,"scott","tiger");
stmt=conn.createStatement();
rs=stmt.executeQuery("SELECT*FROM myblob where id=0");
if(rs.next())
{
request.setCharacterEncoding("gb2312");
//提供下载
response.setHeader("Content-Disposition","attachment;filename=""+rs.getString("fname")
+""");
Blob blob=rs.getBlob("fblob");
byte[] buf=blob.getBytes(1,(int)blob.length());
response.setContentType("application/msword");
//图片的输出流
OutputStream wt=response.getOutputStream();
//将缓冲区的输入输出到页面
wt.write(buf);
//输入完毕,清除缓冲
wt.flush();
wt.close();
}
}
catch(SQLException e)
{
System.out.println(e.getMessage());
}
finally
{
if(rs!=null)
{
try
{
rs.close();
}
catch(SQLException ee)
{
System.out.println(ee.getMessage());
}
}
if(stmt!=null)
{
try
{
stmt.close();
}
catch(SQLException ee)
{
System.out.println(ee.getMessage());
}
}
if(conn!=null)
{
try
{
conn.close();
}
catch(SQLException ee)
{
System.out.println(ee.getMessage());
}
}
}
%>
需要注意的是,对于不同类型的文档,它们的读取方法相同,但显示的方法却不同。如下的案例用于读取图片数据并显示出来。
案例名称:图片数据的读取和显示
程序名称:BlobShow.java
import java.sql.*;
import javax.swing.*;
public classBlobShow
{
public static void main(String[] args)
{
…Connection conn=null;
Statement st=null;
ResultSet rs=null;
Blob blob=null;
try
{
Class.forName("oracle.jdbc.driver.OracleDriver");
}
catch(ClassNotFoundException ea)
{
ea.printStackTrace();
}
try
{
String url="jdbc:oracle:thin:@ localhost:1521:yuanyuan";
conn=DriverManager.getConnection(url,"scott","tiger");
conn.setAutoCommit(false);
st=conn.createStatement();