Sybase JDBC驱动的改进 2

Sun J2SE(1.4) 的实现对于字符集转换非常缓慢,我用 Jfluid 做 Profile 发现一个简单的数据库程序花费在字符集转换上的时间竟然占用了 60% 以上,因此有必要对转换结果缓存:

** package ** com.sybase.jdbc2.jdbc;

** import ** java.io.UnsupportedEncodingException;

** import ** java.util.*;

** public ** class CachedCharset {

public String convertTo(String src) {

try {

String dest = (String)cacheConvertTo.get(src);

if (dest == null ) {

byte [] bytes = src.getBytes(destCharset);

dest = new String(bytes, RAW);

if (cacheConvertTo.size() > EXPIRE_EVERY)

cacheConvertTo.clear();

cacheConvertTo.put(src, dest);

}

return dest;

} catch (UnsupportedEncodingException e) {

throw new RuntimeException(e.getMessage(), e);

}

}

public String castFrom(String dest) {

try {

String src = (String)cacheCastFrom.get(dest);

if (src == null ) {

byte [] bytes = dest.getBytes(RAW);

src = new String(bytes, destCharset);

if (cacheCastFrom.size() > EXPIRE_EVERY)

cacheCastFrom.clear();

cacheCastFrom.put(dest, src);

}

return src;

} catch (UnsupportedEncodingException e) {

throw new RuntimeException(e.getMessage(), e);

}

}

public static String convertTo(String src, String charset) {

if (charset == null ) return src;

if (src == null ) return null ;

CachedCharset cc = (CachedCharset)poolCC.get(charset);

if (cc == null ) {

cc = new CachedCharset(charset);

poolCC.put(charset, cc);

}

return cc.convertTo(src);

}

public static String castFrom(String dest, String charset) {

if (charset == null ) return dest;

if (dest == null ) return null ;

CachedCharset cc = (CachedCharset)poolCC.get(charset);

if (cc == null ) {

cc = new CachedCharset(charset);

poolCC.put(charset, cc);

}

return cc.castFrom(dest);

}

public CachedCharset(String charset) {

this .destCharset = charset;

}

public static final String RAW = "ISO-8859-1" ;

String destCharset = null ;

public static final int EXPIRE_EVERY = 100000;

public Map cacheConvertTo = new HashMap();

public Map cacheCastFrom = new HashMap();

/* Map: destCharset -> CachedCharset */

public static Map poolCC = new HashMap();

}

对于各种 Statement ,我们给它加上 getGeneratedKeys ,并给所有的 sql 加入字符集预处理。 Sybase 获得自动编号的方法是 SELECT @@identity ,因为获取自动编号总在插入、更新等操作之后,所以无需担心 SELECT 操作会破坏上一次的查询结果。(注意,如果自动编号从存储过程产生,而存储过程返回多个 ResultSet ,且其中某个 ResultSet 正被程序访问中,那么根据 JDBC 的一个缺陷, SELECT 将会破坏前面的 ResultSet 。尽管如此,总能返回自动编号。)

对于 ResultSet ,我们给所有返回的 String 加上后处理。

对于 Connection ,它负责解析 URL 中的新增属性,并建立各种 Statement 的包装。

Published At
Categories with Web编程
Tagged with
comments powered by Disqus