<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>wubaodan</title>
    <description></description>
    <link>http://wubaodan.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
          <item>
        <title>温故而知新(一)JDBC封装</title>
        <author>wubaodan</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://wubaodan.javaeye.com">wubaodan</a>&nbsp;
                    链接：<a href="http://wubaodan.javaeye.com/blog/246593" style="color:red;">http://wubaodan.javaeye.com/blog/246593</a>&nbsp;
          发表时间: 2008年09月25日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <pre name="code" class="java"><pre name="code" class="java">package com.JDBC.firstJDBC;

import java.util.*;
import java.io.*;
import java.sql.*;

/*此类用于封装Java程序链接数据库所需要配置的JDBC操作
 * 
 * */
public class SingletonJDBCUtil{
	private static Properties info=new Properties();
	private static Connection conn=null;
	
	static{
		try{
			//用于读取配置文件中的字节流
			//getResourceAsStream方法用于类加载器在加载的时候并加载制指定的资源。
			 InputStream is=JDBCUtil.class.getResourceAsStream("/com" +
			 		"/JDBC/firstJDBC/config.properties");
			 
			 info.load(is);
			 is.close();
		}catch(Exception e){
			//此处只能跑出此种异常，这种异常专门用来在初始化快中抛出的
			throw new ExceptionInInitializerError(e);
		}
	}
	
	//返回一个连接
	public static Connection getConnection()throws Exception{
		
      if(conn==null){
		Class.forName(info.getProperty("driver"));
		conn=DriverManager.getConnection(info.getProperty("url"),
				 info.getProperty("username"),info.getProperty("pwd"));	
		}
      return conn;
	}
	//释放一个资源
	public static void release(ResultSet rs,Statement stm,Connection cn){
		if(rs!=null) try{rs.close();}catch(Exception e){}
		if(stm!=null) try{stm.close();}catch(Exception e){}
		if(cn!=null) try{cn.close();}catch(Exception e){}
	} 

}</pre>
&nbsp; 但上述连接代码存在严重的资源浪费的情况，比如任何一个对象只要调用JDBCUtil的getConnection()方法，就会得到一个连接，这样大大的浪费了资源，以下通过singleton设计模式进行改进后的代码如下： <br /> &nbsp;
<pre name="code" class="java">package com.JDBC.firstJDBC;

import java.util.*;
import java.io.*;
import java.sql.*;

/*此类用于封装Java程序链接数据库所需要配置的JDBC操作
 * 
 * */
public class SingletonJDBCUtil{
	private static Properties info=new Properties();
	private static Connection conn=null;
	
	static{
		try{
			//用于读取配置文件中的字节流
			//getResourceAsStream方法用于类加载器在加载的时候并加载制指定的资源。
			 InputStream is=JDBCUtil.class.getResourceAsStream("/com" +
			 		"/JDBC/firstJDBC/config.properties");
			 
			 info.load(is);
			 is.close();
		}catch(Exception e){
			//此处只能跑出此种异常，这种异常专门用来在初始化快中抛出的
			throw new ExceptionInInitializerError(e);
		}
	}
	
	//返回一个连接
	public static Connection getConnection()throws Exception{
		
      if(conn==null){
		Class.forName(info.getProperty("driver"));
		conn=DriverManager.getConnection(info.getProperty("url"),
				 info.getProperty("username"),info.getProperty("pwd"));	
		}
      return conn;
	}
	//释放一个资源
	public static void release(ResultSet rs,Statement stm,Connection cn){
		if(rs!=null) try{rs.close();}catch(Exception e){}
		if(stm!=null) try{stm.close();}catch(Exception e){}
		if(cn!=null) try{cn.close();}catch(Exception e){}
	} 

}</pre>
&nbsp;这种代码仍然存在问题，当多个线程同时调用该连接的时候，当某一个线程关闭该连接后，其他线程由于还有某些操作没有提交而导致业务的错误.因此，需要一个线程一个连接，代码如下： </pre>
<p>&nbsp;&nbsp; </p>
<pre name="code" class="java">package com.JDBC.firstJDBC;

import java.util.*;
import java.io.*;
import java.sql.*;

/*此类用于封装Java程序链接数据库所需要配置的JDBC操作
 * 
 * */
public class BestUtil{
	
	private static Properties info=new Properties();
	
	
	static{
		try{
			//用于读取配置文件中的字节流
			//getResourceAsStream方法用于类加载器在加载的时候并加载制指定的资源。
			 InputStream is=JDBCUtil.class.getResourceAsStream("/com" +
			 		"/JDBC/firstJDBC/config.properties");
			 
			 info.load(is);
			 is.close();
		}catch(Exception e){
			//此处只能跑出此种异常，这种异常专门用来在初始化快中抛出的
			throw new ExceptionInInitializerError(e);
		}
	}
	//返回一个连接
	private static final ThreadLocal&lt;Connection&gt; tl=new ThreadLocal&lt;Connection&gt;(); 
	public static Connection getConnection()throws Exception{
	  Connection conn=tl.get();
	  if(conn==null){
		Class.forName(info.getProperty("driver"));
		conn=DriverManager.getConnection(info.getProperty("url"),
				 info.getProperty("username"),info.getProperty("pwd"));	
		         tl.set(conn);
	  }
	  return conn;
	}
	//释放一个资源
	public static void release(ResultSet rs,Statement stm,Connection cn){
		if(rs!=null) try{rs.close();}catch(Exception e){}
		if(stm!=null) try{stm.close();}catch(Exception e){}
		if(cn!=null) try{cn.close();}catch(Exception e){}
	}
}</pre>
<p>&nbsp;</p>
<p>这种模式解决了在前面出现并发操作的问题，是一种你比较优秀的数据连接封装操作，其中用到了ThreadLocal类，每一个线程都有一个用于存储线程的局部变量（线程独占数据，用Map对象来存储数据）：由于线程的局部变是属于java.lang包的 defalut类型，因此，要访问该对象就必须用调用ThreadLocal对象来获的里面的对象。 </p>
          <br/><br/>
          <span style="color:red;">
            <a href="http://wubaodan.javaeye.com/blog/246593#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 25 Sep 2008 10:55:41 +0800</pubDate>
        <link>http://wubaodan.javaeye.com/blog/246593</link>
        <guid>http://wubaodan.javaeye.com/blog/246593</guid>
      </item>
          <item>
        <title>开博一周年纪念日</title>
        <author>wubaodan</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://wubaodan.javaeye.com">wubaodan</a>&nbsp;
                    链接：<a href="http://wubaodan.javaeye.com/blog/199528" style="color:red;">http://wubaodan.javaeye.com/blog/199528</a>&nbsp;
          发表时间: 2008年06月02日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          太快了，一年过去了
          <br/><br/>
          <span style="color:red;">
            <a href="http://wubaodan.javaeye.com/blog/199528#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 02 Jun 2008 20:00:51 +0800</pubDate>
        <link>http://wubaodan.javaeye.com/blog/199528</link>
        <guid>http://wubaodan.javaeye.com/blog/199528</guid>
      </item>
          <item>
        <title>以前的Bolg分类去哪儿了，看到好的文章页面还不能&quot;另存为&quot;</title>
        <author>wubaodan</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://wubaodan.javaeye.com">wubaodan</a>&nbsp;
                    链接：<a href="http://wubaodan.javaeye.com/blog/152553" style="color:red;">http://wubaodan.javaeye.com/blog/152553</a>&nbsp;
          发表时间: 2008年01月03日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          强烈要求JavaEye2.5恢复2.0的老功能!!!
          <br/><br/>
          <span style="color:red;">
            <a href="http://wubaodan.javaeye.com/blog/152553#comments" style="color:red;">已有 <strong>1</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 03 Jan 2008 10:27:25 +0800</pubDate>
        <link>http://wubaodan.javaeye.com/blog/152553</link>
        <guid>http://wubaodan.javaeye.com/blog/152553</guid>
      </item>
          <item>
        <title>当PreparedStatement中的参数遇到大字符串</title>
        <author>wubaodan</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://wubaodan.javaeye.com">wubaodan</a>&nbsp;
                    链接：<a href="http://wubaodan.javaeye.com/blog/85672" style="color:red;">http://wubaodan.javaeye.com/blog/85672</a>&nbsp;
          发表时间: 2007年06月01日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p><font face="Courier New">今天在JavaEye上看大牛们的博客突然看到一篇文章标题为:&quot;<a href="http://onho.javaeye.com/blog/85389" title="永久链接：PreparedStatement中setString方法的异常">PreparedStatement中setString方法的异常</a>&quot;让我大喜，以前在项目中遇到这个问题，一直没有得到解决今天终于明白了！</font></p>
<p><font face="Courier New">以前项目中的代码如下：</font></p>
<div class="code_title"><font face="Courier New">java 代码</font></div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span>sql&nbsp;=&nbsp;</span><span class="string">&quot;INSERT&nbsp;INTO&nbsp;taw_attachment&nbsp;(attachmentname,&nbsp;attachmentfilename,&quot;</span><span>&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;+&nbsp;</span><span class="string">&quot;attachmentsize,cruser,crtime,info)&nbsp;VALUES&nbsp;(?,?,?,?,?,?)&quot;</span><span>; &nbsp;&nbsp;</span></li>
    <li class="alt"><span>pstmt.setString(&nbsp;</span><span class="number">6</span><span>,info);//info.length() &gt; 2000&nbsp;&nbsp;&nbsp;</span></li>
    <li class=""><span>pstmt.executeUpdate();&nbsp;&nbsp;</span></li>
</ol>
</div>
<p><font face="Courier New"></font></p>
<p><font face="Courier New">而数据库中对应的表Interface_log.info varchar2(4000);</font></p>
<p><font face="Courier New">在方法头加入如下代码：</font></p>
<div class="code_title"><font face="Courier New">java 代码</font></div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span class="keyword">if</span><span>&nbsp;(info!=</span><span class="keyword">null</span><span>&nbsp;&amp;&amp;&nbsp;info.length()&gt;</span><span class="number">2000</span><span>){ &nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nfo&nbsp;=&nbsp;info.substring(</span><span class="number">0</span><span>,</span><span class="number">2000</span><span>);&nbsp;</span><span class="comment">//给这个大文本截肢 </span><span>&nbsp;&nbsp;</span></li>
    <li class="alt"><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<p><font face="Courier New">当再次Debug时还是抛出：Java.sql.SQLException:数据大小超出此类型的最大值！</font></p>
<p><font face="Courier New">当使用原始的Statement接口后问题解决,郁闷啊！！！</font></p>
<p><font face="Courier New">今天在文章中看到：</font></p>
<div><font face="Courier New">现在通过Oracle提供的JDBC文档来详细看看问题的来由。<br />
我们都知道Oracle提供了两种客户端访问方式OCI和thin，<br />
在这两种方式下，字符串转换的过程如下：</font></div>
<div><font face="Courier New">&nbsp;</font></div>
<div><font face="Courier New">1、JDBC OCI driver：<br />
在JDBC文档中是这么说的：<br />
&ldquo;<br />
If the value of NLS_LANG is set to a character set other than US7ASCII or WE8ISO8859P1, then the driver uses UTF8 as the client character set. This happens automatically and does not require any user intervention. OCI then converts the data from the database character set to UTF8. The JDBC OCI driver then passes the UTF8 data to the JDBC Class Library where the UTF8 data is converted to UTF-16. &rdquo;</font></div>
<div><font face="Courier New">&nbsp;</font></div>
<div><font face="Courier New">2、JDBC thin driver:<br />
JDBC文档是这样的：</font></div>
<div><font face="Courier New">&ldquo;If the database character set is neither ASCII (US7ASCII) nor ISO Latin1 (WE8ISO8859P1), then the JDBC thin driver must impose size restrictions for SQL CHAR bind parameters that are more restrictive than normal database size limitations. This is necessary to allow for data expansion during conversion.</font></div>
<div><font face="Courier New">The JDBC thin driver checks SQL CHAR bind sizes when a setXXX() method (<strong>except for the setCharacterStream() method</strong>) is called. If the data size exceeds the size restriction, then the driver returns a SQL exception (<strong>SQLException: Data size bigger than max size for this type</strong>) from the setXXX() call. This limitation is necessary to avoid the chance of data corruption when conversion of character data occurs and increases the length of the data. This limitation is enforced in the following situations:<br />
(1)Using the JDBC thin driver <br />
(2)Using binds (not defines) <br />
(3)Using SQL CHAR datatypes <br />
(4)Connecting to a database whose character set is neither ASCII (US7ASCII) nor ISO Latin1 (WE8ISO8859P1) </font></div>
<div><font face="Courier New">When the database character set is neither US7ASCII nor WE8ISO8859P1, the JDBC thin driver converts Java UTF-16 characters to UTF-8 encoding bytes for SQL CHAR binds. The UTF-8 encoding bytes are then transferred to the database, and the database converts the UTF-8 encoding bytes to the database character set encoding.&rdquo;</font></div>
<div><font face="Courier New">&nbsp;</font></div>
<div><font face="Courier New">原来是JDBC在转换过程中对字符串的长度做了限制。这个限制和数据库中字段的实际长度没有关系。<br />
所以，setCharacterStream()方法可以逃过字符转换限制，也就成为了解决此问题的方案之一。<br />
而JDBC对转换字符长度的限制是为了转换过程中的数据扩展。<br />
根据实际测试结果，在ZHS16GBK字符集和thin驱动下，2000－4000长度的varchar字段都只能插入1333个字节（约666个汉字）。</font></div>
<div><font face="Courier New">&nbsp;</font></div>
<div><font face="Courier New">To sum，解决PreparedStatement的setString中字符串长度问题可以有两种办法：<br />
1、使用setCharacterStream()方法；</font></div>
<div><font face="Courier New">
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span>pstmt.setCharacterStream(index,</span><span class="keyword">new</span><span>&nbsp;InputStreamReader(myString,&nbsp;myString.length()); &nbsp;&nbsp;</span></span></li>
</ol>
</div>
<br />
2、使用OCI驱动连接Oracle数据库。</font></div>
          <br/><br/>
          <span style="color:red;">
            <a href="http://wubaodan.javaeye.com/blog/85672#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 01 Jun 2007 14:55:45 +0800</pubDate>
        <link>http://wubaodan.javaeye.com/blog/85672</link>
        <guid>http://wubaodan.javaeye.com/blog/85672</guid>
      </item>
          <item>
        <title>关注JavaEye好久，今天在这个属于世界儿童的节日里开博了</title>
        <author>wubaodan</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://wubaodan.javaeye.com">wubaodan</a>&nbsp;
                    链接：<a href="http://wubaodan.javaeye.com/blog/85652" style="color:red;">http://wubaodan.javaeye.com/blog/85652</a>&nbsp;
          发表时间: 2007年06月01日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <div>关注JavaEye估计有一年多了，今天终于忍不住想创建一个属于自己的博客，在以后的每一天里把自己的所学、所感以及工作中遇到的问题记录下来。顺便在此祝愿JavaEye越办越好！</div>
          <br/><br/>
          <span style="color:red;">
            <a href="http://wubaodan.javaeye.com/blog/85652#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">Windows7在微软WinHEC 2008上揭开神秘面纱</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 01 Jun 2007 13:39:48 +0800</pubDate>
        <link>http://wubaodan.javaeye.com/blog/85652</link>
        <guid>http://wubaodan.javaeye.com/blog/85652</guid>
      </item>
      </channel>
</rss>