与lucene亲密接触第二集,关于jdbc的一个疑惑

继续咱们的lucene之旅,

今天结合jdbc把数据库中的内容建到倒排序索引文件去。使用jdbc的时候出现了一个疑惑,调了半天也没明白。

 

我有一个类 Db负责与数据库交互,在构造的时候建立数据库连接池,然后通过这个类的其他方法对数据库进行交互。

我有大概20万条表记录需要插到lucene的倒排序文件中,

然后思路很简单,我直接遍历数据库。

 

由于内存有限,我不可能直接读出整个数据库来索引,于是采取的分块进行。每次读出若干条,建索引,释放,然后读出下N条……

问题出现了,我发现不一会儿,java就内存溢出了!

仔细找了几遍代码,发现该释放的都释放了。。只是没有释放数据库连接池,于是我怀着很怀疑的态度,在每次处理一个块之后重建连接池,居然就没有溢出了!

 

按道理说数据库连接池不释放掉应该是不占查询内容的,只要将数据库查询的result释放就可以了,于是这个问题。。百思不得其解,先将代码贴上来,以后持续关注该问题。(这是每次释放,不会内存溢出的代码)

 

Db.class

 

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import com.mysql.jdbc.*;

//用于封装对数据库操作
public class Db {
	
	private Connection conn = null;
	
	private static String userName = "cg";
	private static String password = "XXXXXX";
	private static String databaseIP = "192.168.25.152";
	private static String databaseName = "medias";
	//数据库查询结果
	//private ResultSet rset = null;
	PreparedStatement pstmt = null;
	
	
	///初始化数据库链接
	public Db()
	{
		this.Init();
	}
	
	public void Init()
	{
		try{
	        String url = "jdbc:mysql://"+ databaseIP + "/" + databaseName;
	        Class.forName ("com.mysql.jdbc.Driver").newInstance();
	        conn = DriverManager.getConnection (url, userName, password);
	        System.out.println ("数据库初始化成功");
	        
		}
		catch( Exception e){
			e.printStackTrace();
			System.err.println(e.toString());
		}
	}
	
	
	public ResultSet Begin( long start,long size )
	{
		String exec = "select * from media limit " + String.valueOf(start) 
			+ "," + String.valueOf(size);
		ResultSet rset=null;
		try
		{
			pstmt = 
				conn.prepareStatement(exec);
			rset=pstmt.executeQuery();
			
		}
		catch( Exception e ){}
		return rset;
	}
	
	
	
	public Movie Next(ResultSet rset) throws SQLException{
		Movie result = new Movie();
		if( rset.next())
		{
			result.title = rset.getString("title");
			String id = rset.getString("media_id");
			String exec = "select * from media_source where movie_id=" + id;
			try
			{
				PreparedStatement pstmt = 
					conn.prepareStatement(exec);
				ResultSet rset2=pstmt.executeQuery();
				
				//对media_source操作
				while( rset2.next() )
				{
					MovieTip tip = new MovieTip();
					tip.url = rset2.getString("source_url");
					result.AddTip(tip);
				}
				rset2.close();
			}
			catch( Exception e )
			{
				System.err.println(e.toString());
			}
			
			return result;
		}
		else
		{
			pstmt.close();
			result.isFinish = true;
			return result;
		}
	}
	
	//关闭数据库
	public void Close()
	{
	 	if (conn != null)
	 	{
            try
            {
                conn.close ();
                System.out.println ("数据库关闭");
            }
            catch (Exception e) { /* ignore close errors */ }
        }
	}
}

 

 

调用相关代码

 

		try
		{
			System.out.println("正在添加第"+start+"到"+(start+size)+"条记录");
			
			indexWriter = new IndexWriter(indexDir, luceneAnalyzer,
					false, IndexWriter.MaxFieldLength.LIMITED);
			Db dbQueryer = new Db();//初始化数据库连接器
			//dbQueryer.Init();
			ResultSet rs=dbQueryer.Begin(start, size);
			while( true )
			{
				Movie movie = dbQueryer.Next(rs);
				if( movie.isFinish == true )
					break;
				else 
				{
					Document document = new Document();
					String urllist = "";
					for(int i=0;i<movie.sources.size();i++)
					{
						MovieTip tip = (MovieTip)(movie.sources.get(i));
						urllist += tip.url + "<br>";
					}
					
					Field FieldTitle = new Field("title", movie.title, Field.Store.YES,
							Field.Index.ANALYZED,
							Field.TermVector.WITH_POSITIONS_OFFSETS);
					Field FieldUrl = new Field("url", urllist, Field.Store.YES,
							Field.Index.ANALYZED,
							Field.TermVector.WITH_POSITIONS_OFFSETS);
					//System.out.println(movie.title);
					document.add(FieldTitle);
					document.add(FieldUrl);
					indexWriter.addDocument(document);
				}
			}

			rs.close();
			
			indexWriter.optimize();
			indexWriter.close();
			dbQueryer.Close();
			System.out.println("添加成功");

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值