﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>语源科技BlogJava-atlantic</title><link>http://www.blogjava.net/atlantic23/</link><description>final</description><language>zh-cn</language><lastBuildDate>Sat, 25 Apr 2026 04:05:37 GMT</lastBuildDate><pubDate>Sat, 25 Apr 2026 04:05:37 GMT</pubDate><ttl>60</ttl><item><title>mysql的操作大全</title><link>http://www.blogjava.net/atlantic23/archive/2008/10/24/236326.html</link><dc:creator>chencj</dc:creator><author>chencj</author><pubDate>Fri, 24 Oct 2008 01:43:00 GMT</pubDate><guid>http://www.blogjava.net/atlantic23/archive/2008/10/24/236326.html</guid><wfw:comment>http://www.blogjava.net/atlantic23/comments/236326.html</wfw:comment><comments>http://www.blogjava.net/atlantic23/archive/2008/10/24/236326.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/atlantic23/comments/commentRss/236326.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/atlantic23/services/trackbacks/236326.html</trackback:ping><description><![CDATA[<span id="ArticleContent1_ArticleContent1_lblContent"><font color="#000080" size="2">一、连接MYSQL。&nbsp;<br />
<br />
格式：&nbsp;mysql&nbsp;-h主机地址&nbsp;-u用户名&nbsp;－p用户密码&nbsp;<br />
<br />
1、例1：连接到本机上的MYSQL。&nbsp;<br />
<br />
首先在打开DOS窗口，然后进入目录&nbsp;mysqlbin，再键入命令mysql&nbsp;-uroot&nbsp;-p，回车后提示你输密码，如果刚安装好MYSQL，超级用户root是没有密码的，故直接回车即可进入到MYSQL中了，MYSQL的提示符是：mysql&gt;&nbsp;<br />
<br />
2、例2：连接到远程主机上的MYSQL。假设远程主机的IP为：110.110.110.110，用户名为root,密码为abcd123。则键入以下命令：&nbsp;<br />
<br />
mysql&nbsp;-h110.110.110.110&nbsp;-uroot&nbsp;-pabcd123&nbsp;<br />
<br />
（注:u与root可以不用加空格，其它也一样）&nbsp;<br />
<br />
3、退出MYSQL命令：&nbsp;exit&nbsp;（回车）&nbsp;<br />
<br />
二、修改密码。&nbsp;<br />
<br />
格式：mysqladmin&nbsp;-u用户名&nbsp;-p旧密码&nbsp;password&nbsp;新密码&nbsp;<br />
<br />
1、例1：给root加个密码ab12。首先在DOS下进入目录mysqlbin，然后键入以下命令&nbsp;<br />
<br />
mysqladmin&nbsp;-uroot&nbsp;-password&nbsp;ab12&nbsp;<br />
<br />
注：因为开始时root没有密码，所以-p旧密码一项就可以省略了。&nbsp;<br />
<br />
2、例2：再将root的密码改为djg345。&nbsp;<br />
<br />
mysqladmin&nbsp;-uroot&nbsp;-pab12&nbsp;password&nbsp;djg345&nbsp;<br />
<br />
三、增加新用户。（注意：和上面不同，下面的因为是MYSQL环境中的命令，所以后面都带一个分号作为命令结束符）&nbsp;<br />
<br />
格式：grant&nbsp;select&nbsp;on&nbsp;数据库.*&nbsp;to&nbsp;用户名@登录主机&nbsp;identified&nbsp;by&nbsp;\"密码\"&nbsp;<br />
<br />
例1、增加一个用户test1密码为abc，让他可以在任何主机上登录，并对所有数据库有查询、插入、修改、删除的权限。首先用以root用户连入MYSQL，然后键入以下命令：&nbsp;<br />
<br />
grant&nbsp;select,insert,update,delete&nbsp;on&nbsp;*.*&nbsp;to&nbsp;test1@\"%\"&nbsp;Identified&nbsp;by&nbsp;\"abc\";&nbsp;<br />
<br />
但例1增加的用户是十分危险的，你想如某个人<a class="channel_keylink" href="http://zhidao.baidu.com/" target="_blank">知道</a>test1的密码，那么他就可以在internet上的任何一台<a class="qs_highlight1" id="hl_1" onmouseover="window.clearTimeout(_ht[1]);qs_show_frame(event,this,1);" style="font-size: 1em" onmouseout="_on_div[1]=false;_ht[1]=window.setTimeout('qs_is_on_div(1)',1000);" href="javascript:void(0)">电脑</a><img style="border-right: 0px; padding-right: 0px; border-top: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; border-left: 0px; padding-top: 0px; border-bottom: 0px" height="12" src="http://web.qunsee.com/script/images/i.gif" width="11"  alt="" />上登录你的mysql数据库并对你的数据可以为所欲为了，解决办法见例2。&nbsp;<br />
<br />
例2、增加一个用户test2密码为abc,让他只可以在localhost上登录，并可以对数据库mydb进行查询、插入、修改、删除的<a class="qs_highlight1" id="hl_4" onmouseover="window.clearTimeout(_ht[4]);qs_show_frame(event,this,4);" style="font-size: 1em" onmouseout="_on_div[4]=false;_ht[4]=window.setTimeout('qs_is_on_div(4)',1000);" href="javascript:void(0)">操作</a><img style="border-right: 0px; padding-right: 0px; border-top: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; border-left: 0px; padding-top: 0px; border-bottom: 0px" height="12" src="http://web.qunsee.com/script/images/i.gif" width="11"  alt="" />（localhost指本地主机，即MYSQL数据库所在的那台主机），这样用户即使用<a class="channel_keylink" href="http://zhidao.baidu.com/" target="_blank">知道</a>test2的密码，他也无法从internet上直接访问数据库，只能通过MYSQL主机上的web页来访问了。&nbsp;<br />
<br />
grant&nbsp;select,insert,update,delete&nbsp;on&nbsp;mydb.*&nbsp;to&nbsp;test2@localhost&nbsp;identified&nbsp;by&nbsp;\"abc\";&nbsp;<br />
<br />
如果你不想test2有密码，可以再打一个命令将密码消掉。&nbsp;<br />
<br />
grant&nbsp;select,insert,update,delete&nbsp;on&nbsp;mydb.*&nbsp;to&nbsp;test2@localhost&nbsp;identified&nbsp;by&nbsp;\"\";&nbsp;<br />
<br />
在上篇我们讲了登录、增加用户、密码更改等问题。下篇我们来看看MYSQL中有关数据库方面的操作。注意：你必须首先登录到MYSQL中，以下操作都是在MYSQL的提示符下进行的，而且每个命令以分号结束。&nbsp;<br />
<br />
一、操作<a class="qs_highlight1" id="hl_5" onmouseover="window.clearTimeout(_ht[5]);qs_show_frame(event,this,5);" style="font-size: 1em" onmouseout="_on_div[5]=false;_ht[5]=window.setTimeout('qs_is_on_div(5)',1000);" href="javascript:void(0)">技巧</a><img style="border-right: 0px; padding-right: 0px; border-top: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; border-left: 0px; padding-top: 0px; border-bottom: 0px" height="12" src="http://web.qunsee.com/script/images/i.gif" width="11"  alt="" />&nbsp;<br />
<br />
1、如果你打命令时，回车后发现忘记加分号，你无须重打一遍命令，只要打个分号回车就可以了。也就是说你可以把一个完整的命令分成几行来打，完后用分号作结束标志就OK。&nbsp;<br />
<br />
2、你可以使用光标上下键调出以前的命令。但以前我用过的一个MYSQL旧版本不支持。我现在用的是mysql-3.23.27-beta-win。&nbsp;<br />
<br />
二、<a class="qs_highlight1" id="hl_2" onmouseover="window.clearTimeout(_ht[2]);qs_show_frame(event,this,2);" style="font-size: 1em" onmouseout="_on_div[2]=false;_ht[2]=window.setTimeout('qs_is_on_div(2)',1000);" href="javascript:void(0)">显示</a><img style="border-right: 0px; padding-right: 0px; border-top: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; border-left: 0px; padding-top: 0px; border-bottom: 0px" height="12" src="http://web.qunsee.com/script/images/i.gif" width="11"  alt="" />命令&nbsp;<br />
<br />
1、显示数据库列表。&nbsp;<br />
<br />
show&nbsp;databases;&nbsp;<br />
<br />
刚开始时才两个数据库：mysql和test。mysql库很重要它里面有MYSQL的系统信息，我们改密码和新增用户，实际上就是用这个库进行操作。&nbsp;<br />
<br />
2、显示库中的数据表：&nbsp;<br />
<br />
use&nbsp;mysql；&nbsp;／／打开库，学过FOXBASE的一定不会陌生吧&nbsp;<br />
<br />
show&nbsp;tables;&nbsp;<br />
<br />
3、显示数据表的结构：&nbsp;<br />
<br />
describe&nbsp;表名;&nbsp;<br />
<br />
4、建库：&nbsp;<br />
<br />
create&nbsp;database&nbsp;库名;&nbsp;<br />
<br />
5、建表：&nbsp;<br />
<br />
use&nbsp;库名；&nbsp;<br />
<br />
create&nbsp;table&nbsp;表名&nbsp;(字段设定列表)；&nbsp;<br />
<br />
6、删库和删表:&nbsp;<br />
<br />
drop&nbsp;database&nbsp;库名;&nbsp;<br />
<br />
drop&nbsp;table&nbsp;表名；&nbsp;<br />
<br />
7、将表中<a class="qs_highlight1" id="hl_3" onmouseover="window.clearTimeout(_ht[3]);qs_show_frame(event,this,3);" style="font-size: 1em" onmouseout="_on_div[3]=false;_ht[3]=window.setTimeout('qs_is_on_div(3)',1000);" href="javascript:void(0)">记录</a><img style="border-right: 0px; padding-right: 0px; border-top: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; border-left: 0px; padding-top: 0px; border-bottom: 0px" height="12" src="http://web.qunsee.com/script/images/i.gif" width="11"  alt="" />清空：&nbsp;<br />
<br />
delete&nbsp;from&nbsp;表名;&nbsp;<br />
<br />
8、显示表中的记录：&nbsp;<br />
<br />
select&nbsp;*&nbsp;from&nbsp;表名;&nbsp;<br />
<br />
三、一个建库和建表以及插入数据的实例&nbsp;<br />
<br />
drop&nbsp;database&nbsp;if&nbsp;exists&nbsp;school;&nbsp;//如果存在SCHOOL则删除&nbsp;<br />
<br />
create&nbsp;database&nbsp;school;&nbsp;//建立库SCHOOL&nbsp;<br />
<br />
use&nbsp;school;&nbsp;//打开库SCHOOL&nbsp;<br />
<br />
create&nbsp;table&nbsp;teacher&nbsp;//建立表TEACHER&nbsp;<br />
<br />
(&nbsp;<br />
<br />
id&nbsp;int(3)&nbsp;auto_increment&nbsp;not&nbsp;null&nbsp;primary&nbsp;key,&nbsp;<br />
<br />
name&nbsp;char(10)&nbsp;not&nbsp;null,&nbsp;<br />
<br />
address&nbsp;varchar(50)&nbsp;default&nbsp;&#8217;深圳&#8217;,&nbsp;<br />
<br />
year&nbsp;date&nbsp;<br />
<br />
);&nbsp;//建表结束&nbsp;<br />
<br />
//以下为插入字段&nbsp;<br />
<br />
insert&nbsp;into&nbsp;teacher&nbsp;values(&#8217;&#8217;,&#8217;glchengang&#8217;,&#8217;深圳一中&#8217;,&#8217;1976-10-10&#8217;);&nbsp;<br />
<br />
insert&nbsp;into&nbsp;teacher&nbsp;values(&#8217;&#8217;,&#8217;jack&#8217;,&#8217;深圳一中&#8217;,&#8217;1975-12-23&#8217;);&nbsp;<br />
<br />
注：在建表中（1）将ID设为长度为3的数字字段:int(3)并让它每个记录自动加一:auto_increment并不能为空:not&nbsp;null而且让他成为主字段primary&nbsp;key（2）将NAME设为长度为10的字符字段（3）将ADDRESS设为长度50的字符字段，而且缺省值为深圳。varchar和char有什么区别呢，只有等以后的文章再说了。（4）将YEAR设为日期字段。&nbsp;<br />
<br />
如果你在mysql提示符键入上面的命令也可以，但不方便调试。你可以将以上命令原样写入一个文本文件中假设为school.sql，然后复制到c:\\下，并在DOS<a class="qs_highlight1" id="hl_6" onmouseover="window.clearTimeout(_ht[6]);qs_show_frame(event,this,6);" style="font-size: 1em" onmouseout="_on_div[6]=false;_ht[6]=window.setTimeout('qs_is_on_div(6)',1000);" href="javascript:void(0)">状态</a><img style="border-right: 0px; padding-right: 0px; border-top: 0px; padding-left: 0px; padding-bottom: 0px; margin: 0px; border-left: 0px; padding-top: 0px; border-bottom: 0px" height="12" src="http://web.qunsee.com/script/images/i.gif" width="11"  alt="" />进入目录\\mysql\\bin，然后键入以下命令：&nbsp;<br />
<br />
mysql&nbsp;-uroot&nbsp;-p密码&nbsp;&lt;&nbsp;c:\\school.sql&nbsp;<br />
<br />
如果<a class="channel_keylink" href="http://www.chenzhixin.com/Article/bin/joke/2007-01-18/Article_20070118172650_1273.html" target="_blank">成功</a>，空出一行无任何显示；如有错误，会有提示。（以上命令已经调试，你只要将//的注释去掉即可使用）。&nbsp;<br />
<br />
四、将文本数据转到数据库中&nbsp;<br />
<br />
1、文本数据应符合的格式：字段数据之间用tab键隔开，null值用\\n来代替.&nbsp;<br />
<br />
例：&nbsp;<br />
<br />
3&nbsp;rose&nbsp;深圳二中&nbsp;1976-10-10&nbsp;<br />
<br />
4&nbsp;mike&nbsp;深圳一中&nbsp;1975-12-23&nbsp;<br />
<br />
2、数据传入命令&nbsp;load&nbsp;data&nbsp;local&nbsp;infile&nbsp;\"文件名\"&nbsp;into&nbsp;table&nbsp;表名;&nbsp;<br />
<br />
注意：你最好将文件复制到\\mysql\\bin目录下，并且要先用use命令打表所在的库。&nbsp;<br />
<br />
五、备份数据库：（命令在DOS的\\mysql\\bin目录下执行）&nbsp;<br />
mysqldump&nbsp;--opt&nbsp;school&gt;school.bbb&nbsp;<br />
</font></span><span><br />
<font color="#000080" size="2">注释:将数据库school备份到school.bbb文件，school.bbb是一个文本文件，文件名任取，打开看看你会有新发现。</font></span> 
<img src ="http://www.blogjava.net/atlantic23/aggbug/236326.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/atlantic23/" target="_blank">chencj</a> 2008-10-24 09:43 <a href="http://www.blogjava.net/atlantic23/archive/2008/10/24/236326.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ibatis入门</title><link>http://www.blogjava.net/atlantic23/archive/2008/08/01/219269.html</link><dc:creator>chencj</dc:creator><author>chencj</author><pubDate>Fri, 01 Aug 2008 03:17:00 GMT</pubDate><guid>http://www.blogjava.net/atlantic23/archive/2008/08/01/219269.html</guid><wfw:comment>http://www.blogjava.net/atlantic23/comments/219269.html</wfw:comment><comments>http://www.blogjava.net/atlantic23/archive/2008/08/01/219269.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/atlantic23/comments/commentRss/219269.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/atlantic23/services/trackbacks/219269.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 最简单的 iBatis 入门例子&nbsp; &nbsp;&nbsp; &nbsp;iBatis 是一个 O/R Mapping 解决方案， iBatis 最大的特点就是小巧，上手很快。如果你不需要太多复杂的功能， iBatis 是能满足你的要求又足够灵活的最简单的解决方案。下面我们看一个最简单的入门例子，是《 ibatis 开发指南》上的例子改的，不过上面讲的不仔细，我开始学的时候搞了一个晚...&nbsp;&nbsp;<a href='http://www.blogjava.net/atlantic23/archive/2008/08/01/219269.html'>阅读全文</a><img src ="http://www.blogjava.net/atlantic23/aggbug/219269.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/atlantic23/" target="_blank">chencj</a> 2008-08-01 11:17 <a href="http://www.blogjava.net/atlantic23/archive/2008/08/01/219269.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>自动登陆程序事例</title><link>http://www.blogjava.net/atlantic23/archive/2008/07/21/216354.html</link><dc:creator>chencj</dc:creator><author>chencj</author><pubDate>Mon, 21 Jul 2008 06:58:00 GMT</pubDate><guid>http://www.blogjava.net/atlantic23/archive/2008/07/21/216354.html</guid><wfw:comment>http://www.blogjava.net/atlantic23/comments/216354.html</wfw:comment><comments>http://www.blogjava.net/atlantic23/archive/2008/07/21/216354.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/atlantic23/comments/commentRss/216354.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/atlantic23/services/trackbacks/216354.html</trackback:ping><description><![CDATA[www.x158.cn这是一个信息发布网站，他的登陆页面是在www.x158.cn/bg/login.asp<br />
以下是利用httpclient做的一个自动登陆程序。<br />
package test;<br />
<br />
import java.io.IOException;<br />
<br />
import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;<br />
import org.apache.commons.httpclient.Header;<br />
import org.apache.commons.httpclient.HttpClient;<br />
import org.apache.commons.httpclient.HttpException;<br />
import org.apache.commons.httpclient.HttpStatus;<br />
import org.apache.commons.httpclient.NameValuePair;<br />
import org.apache.commons.httpclient.methods.GetMethod;<br />
import org.apache.commons.httpclient.methods.PostMethod;<br />
import org.apache.commons.httpclient.params.HttpMethodParams;<br />
<br />
public class PostForm {<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;public static void main(String[] args) throws HttpException, IOException {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UserPwd userpwd = new UserPwd("ucanhealth", "1234567");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Zh zh = new Zh();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(zh.iso2utf(userpwd.getInfo())); // 打印返回结果<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}<br />
<br />
class UserPwd {<br />
&nbsp;&nbsp;&nbsp;&nbsp;String user, pwd;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;public UserPwd(String user, String pwd) // 构造函数<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.user = user;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.pwd = pwd;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;public String getInfo() {<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HttpClient client = new HttpClient();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;client.getHostConfiguration().setHost("www.x158.cn", 80, "http"); // url的地址，端口，协议<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PostMethod post = new PostMethod("/bg/login.asp"); // 执行查询的网页<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;post.addParameter(new NameValuePair("username", user));// 传递文本框的name及values<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;post.addParameter("password", pwd);// 传递文本框的pwd及values<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String s = null;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try {<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int i = client.executeMethod(post);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("record statuscode:" + i);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s = post.getResponseBodyAsString();<br />
<br />
///////////////////////////////////////////////////////////////////////////&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//检查是否重定向<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int statuscode = post.getStatusCode();<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ((statuscode == HttpStatus.SC_MOVED_TEMPORARILY) ||<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(statuscode == HttpStatus.SC_MOVED_PERMANENTLY) ||<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(statuscode == HttpStatus.SC_SEE_OTHER) ||<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(statuscode == HttpStatus.SC_TEMPORARY_REDIRECT))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
<br />
//&nbsp;&nbsp;&nbsp;&nbsp;读取新的URL地址<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Header header = post.getResponseHeader("location");<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (header != null) {<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String newurl = header.getValue();<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ((newurl == null) || (newurl.equals("")))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;newurl = "/";<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GetMethod redirect = new GetMethod(newurl);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;client.executeMethod(redirect);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("Redirect:"+ redirect.getStatusLine().toString());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;redirect.releaseConnection();<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} else<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("Invalid redirect");<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
<br />
//////////////////////////////////////////////////////////////////////////&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} catch (HttpException e) {<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} catch (IOException e) {<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return s;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;class GetInfo {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private String url;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GetInfo(String url) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.url = url;<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;void getInfo() throws IOException {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String html = null;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HttpClient hc = new HttpClient();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// create get method instance<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GetMethod gm = new GetMethod(url);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 使用系统提供的默认的恢复策略<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gm.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new DefaultHttpMethodRetryHandler());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int statuscode = hc.executeMethod(gm);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (statuscode != HttpStatus.SC_OK) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.err.print("method failed:" + gm.getStatusLine());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;byte[] responseBody = gm.getResponseBody();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;html = new String(responseBody);<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} catch (HttpException e) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("Please check your provided http address!");<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(html);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
}<br />
<br />
<img src ="http://www.blogjava.net/atlantic23/aggbug/216354.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/atlantic23/" target="_blank">chencj</a> 2008-07-21 14:58 <a href="http://www.blogjava.net/atlantic23/archive/2008/07/21/216354.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[导入]iBatis框架batch处理优化 (转)</title><link>http://www.blogjava.net/atlantic23/archive/2008/07/18/215828.html</link><dc:creator>chencj</dc:creator><author>chencj</author><pubDate>Fri, 18 Jul 2008 07:37:00 GMT</pubDate><guid>http://www.blogjava.net/atlantic23/archive/2008/07/18/215828.html</guid><wfw:comment>http://www.blogjava.net/atlantic23/comments/215828.html</wfw:comment><comments>http://www.blogjava.net/atlantic23/archive/2008/07/18/215828.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/atlantic23/comments/commentRss/215828.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/atlantic23/services/trackbacks/215828.html</trackback:ping><description><![CDATA[		<strong>为什么要做batch处理</strong>&#160;&#160;&#160;&#160;<br /><br />&#160;&#160;&#160;&#160;这个问题我就不解释了，因为我想你们肯定能比<br /><br />我解释的更好！如果你真的不知道，那就到Google上去搜<br /><br />索一下吧☻<br /><br /><b>Oracle回滚段</b><br /><br />&#160;&#160;&#160;&#160;这个问题偶也不很明白，只是大概有个了解，如<br /><br />果你是这方面的专家，或者对这方面有比较深的理解，<br /><br />别忘了跟偶分享哦☻<br /><br /><b>在JDBC中如何做batch处理</b><br /><br />&#160;&#160;&#160;&#160;JDBC提供了数据库batch处理的能力，在数据大批量操作（新增、删除等）的情况下可以大幅度提升系统的性能。我以前接触的一个项目，在没有采用batch处理时，删除5万条数据大概要半个小时左右，后来对系统进行改造，采用了batch处理的方式，删除5万条数据基本上不会超过1分钟。看一段JDBC代码：<br /><div class="codeStyle"><ol><li><i><font color="#339900">//&#160;关闭自动执行</font></i></li><li>con.setAutoCommit(<b><font color="#0000ff">false</font></b>); 
</li><li><font color="#ff0000">Statement</font>&#160;stmt&#160;=&#160;con.createStatement(); 
</li><li></li><li>stmt.addBatch(<font color="#ff33ff">"INSERT&#160;INTO&#160;employees&#160;VALUES&#160;(1000,&#160;'Joe&#160;Jones')"</font>); 
</li><li>stmt.addBatch(<font color="#ff33ff">"INSERT&#160;INTO&#160;departments&#160;VALUES&#160;(260,&#160;'Shoe')"</font>); 
</li><li>stmt.addBatch(<font color="#ff33ff">"INSERT&#160;INTO&#160;emp_dept&#160;VALUES&#160;(1000,&#160;260)"</font>); 
</li><li></li><li><i><font color="#339900">//&#160;提交一批要执行的更新命令</font></i></li><li><b><font color="#0000ff">int</font></b>[]&#160;updateCounts&#160;=&#160;stmt.executeBatch(); </li></ol></div><br /><br /><br />&#160;&#160;&#160;&#160;本例中禁用了自动执行模式，从而在调用&#160;Statement.executeBatch()&#160;时可以防止&#160;JDBC&#160;执行事务处理。禁用自动执行使得应用程序能够在发生错误及批处理中的某些命令不能执行时决定是否执行事务处理。因此，当进行批处理更新时，通常应该关闭自动执行。<br /><br />&#160;&#160;&#160;&#160;在JDBC&#160;2.0&#160;中，Statement&#160;对象能够记住可以一起提交执行的命令列表。创建语句时，与它关联的命令列表为空。Statement.addBatch()&#160;方法为调用语句的命令列表添加一个元素。如果批处理中包含有试图返回结果集的命令，则当调用&#160;Statement.&#160;executeBatch()&#160;时，将抛出&#160;SQLException。只有&#160;DDL&#160;和&#160;DML&#160;命令（它们只返回简单的更新计数）才能作为批处理的一部分来执行。如果应用程序决定不提交已经为某语句构<br />造的命令批处理，则可以调用方法&#160;Statement.clearBatch()（以上没有显示）来重新设置批处理。<br /><br />&#160;&#160;&#160;&#160;Statement.executeBatch()&#160;方法将把命令批处理提交给基本&#160;DBMS&#160;来执行。命令的执行将依照在批处理中的添加顺序来进行。ExecuteBatch()&#160;为执行的命令返回更新计数数组。数组中对应于批处理中的每个命令都包含了一项，而数组中各元素依据命令的执行顺序（这还是和命令的最初添加顺序相同）来排序。调用executeBatch()&#160;将关闭发出调用的&#160;Statement&#160;对象的当前结果集（如果有一个结果集是打开的）。executeBatch()&#160;返回后，将重新将语句的内部批处理命令列表设置为空。<br /><br />&#160;&#160;&#160;&#160;如果批处理中的某个命令无法正确执行，则&#160;ExecuteBatch()&#160;将抛出BatchUpdateException。可以调用BatchUpdateException.getUpdateCounts()&#160;方法来为批处理中成功执行的命令返回更新计数的整型数组。因为当有第一个命令返回错误时，Statement.executeBatch()&#160;就中止，而且这些命令是依据它们在批处理中的添加顺序而执行的。所以如果&#160;BatchUpdateException.getUpdateCounts()&#160;所返回的数组包含&#160;N&#160;个元素，这就意味着在调用&#160;executeBatch()&#160;时批处理中的前&#160;N&#160;个命令被成功执行。用PreparedStatement&#160;可以象下面这样写代码：<br /><br /><div class="codeStyle"><ol><li><i><font color="#339900">//&#160;关闭自动执行</font></i></li><li>con.setAutoCommit(<b><font color="#0000ff">false</font></b>); 
</li><li><font color="#ff0000">PreparedStatement</font>&#160;stmt&#160;=&#160;con.prepareStatement(<font color="#ff33ff">"INSERT&#160;INTO&#160;employees&#160;VALUES&#160;(?,&#160;?)"</font>); 
</li><li></li><li>stmt.setInt(1,&#160;2000); 
</li><li>stmt.setString(2,&#160;<font color="#ff33ff">"Kelly&#160;Kaufmann"</font>); 
</li><li>stmt.addBatch(); 
</li><li>??? 
</li><li></li><li><i><font color="#339900">//&#160;提交要执行的批处理</font></i></li><li><b><font color="#0000ff">int</font></b>[]&#160;updateCounts&#160;=&#160;stmt.executeBatch(); </li></ol></div><br /><br /><br /><b>iBatis框架对batch处理的支持</b><br /><br />&#160;&#160;&#160;&#160;iBatis框架对batch处理提供了很好的支持，底层的实现方式就是JDBC。下面看一段示例代码：<br /><br /><div class="codeStyle"><ol><li>&#160;&#160;&#160;&#160;<b><font color="#0000ff">private</font></b>&#160;<b><font color="#0000ff">void</font></b>&#160;execute(SqlMapClient&#160;client){ 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<b><font color="#0000ff">if</font></b>(log.isDebugEnabled()){ 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;log.debug(<font color="#ff33ff">"execute&#160;start..."</font>); 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;} 
</li><li></li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;client.startBatch(); 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<b><font color="#0000ff">for</font></b>(<b><font color="#0000ff">int</font></b>&#160;i=0;i&lt;2000;i++){ 
</li><li></li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;client.delete(<font color="#ff33ff">"delete&#160;from&#160;order&#160;where&#160;id=?"</font>,i); 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;} 
</li><li></li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;client.executeBatch(); 
</li><li></li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<b><font color="#0000ff">if</font></b>(log.isDebugEnabled()){ 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;log.debug(<font color="#ff33ff">"execute&#160;end..."</font>); 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;} 
</li><li>&#160;&#160;&#160;&#160;} </li></ol></div><br /><br /><b>iBatis框架做batch处理的问题</b><br /><br />&#160;&#160;&#160;&#160;在一个batch中只能对一个表进行操作，例如插入或删除。当有多个表需要处理时，只能放在多个batch中进行处理。看下面的一段代码：<br /><div class="codeStyle"><ol><li>&#160;&#160;&#160;&#160;<b><font color="#0000ff">private</font></b>&#160;<b><font color="#0000ff">void</font></b>&#160;execute(<b><font color="#0000ff">int</font></b>&#160;from,<b><font color="#0000ff">int</font></b>&#160;to,<font color="#ff0000">List</font>&#160;list){ 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<b><font color="#0000ff">if</font></b>(log.isDebugEnabled()){ 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;log.debug(<font color="#ff33ff">"STRGHousekeepTask&#160;execute&#160;start..."</font>); 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;} 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;HKSqlMapWrapper&#160;sqlWrapper&#160;=&#160;HKSqlMapWrapper.newInstance(); 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;sqlWrapper.startBatch(); 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<b><font color="#0000ff">for</font></b>(<b><font color="#0000ff">int</font></b>&#160;i=from;i&lt;to;i++){ 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;sqlWrapper.delete(STRGHousekeepConstants.DELETE_STRG_CNTR_BL,list.get(i)); 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;sqlWrapper.delete(STRGHousekeepConstants.DELETE_STRG_CNTR,list.get(i)); 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;sqlWrapper.delete(STRGHousekeepConstants.DELETE_CNTR,list.get(i)); 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;} 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;sqlWrapper.execBatch(); 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<b><font color="#0000ff">if</font></b>(log.isDebugEnabled()){ 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;log.debug(<font color="#ff33ff">"STRGHousekeepTask&#160;execute&#160;end..."</font>); 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;} 
</li><li>&#160;&#160;&#160;&#160;} </li></ol></div>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;代码1<br /><br />&#160;&#160;&#160;&#160;这段代码的目的就是要删除数据库中3个表的数据，sqlWrapper是iBatis的SqlMapClient的一个包装器，主要是封状对事物的控制。当批次（既to-from的值）很小的时候，这样写是没有问题的。尽管这段代码的本意是要享受batch处理带来的好处，但是事实上这段代码并不会真正达到预期的效果，至于原因，我们一会在进行分析☻。我们先来看下面一段代码：<br /><div class="codeStyle"><ol><li>&#160;&#160;&#160;&#160;<b><font color="#0000ff">private</font></b>&#160;<b><font color="#0000ff">void</font></b>&#160;execute(<b><font color="#0000ff">int</font></b>&#160;from,<b><font color="#0000ff">int</font></b>&#160;to,<font color="#ff0000">List</font>&#160;list){ 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<b><font color="#0000ff">if</font></b>(log.isDebugEnabled()){ 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;log.debug(<font color="#ff33ff">"STRGHousekeepTask&#160;execute&#160;start..."</font>); 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;} 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;HKSqlMapWrapper&#160;sqlWrapper&#160;=&#160;HKSqlMapWrapper.newInstance(); 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;sqlWrapper.startBatch(); 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<b><font color="#0000ff">for</font></b>(<b><font color="#0000ff">int</font></b>&#160;i=from;i&lt;to;i++){ 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;sqlWrapper.delete(STRGHousekeepConstants.DELETE_STRG_CNTR_BL,list.get(i)); 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;} 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<b><font color="#0000ff">for</font></b>(<b><font color="#0000ff">int</font></b>&#160;i=from;i&lt;to;i++){ 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;sqlWrapper.delete(STRGHousekeepConstants.DELETE_STRG_CNTR,list.get(i)); 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;} 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<b><font color="#0000ff">for</font></b>(<b><font color="#0000ff">int</font></b>&#160;i=from;i&lt;to;i++){ 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;sqlWrapper.delete(STRGHousekeepConstants.DELETE_CNTR,list.get(i)); 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;} 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;sqlWrapper.execBatch(); 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<b><font color="#0000ff">if</font></b>(log.isDebugEnabled()){ 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;log.debug(<font color="#ff33ff">"STRGHousekeepTask&#160;execute&#160;end..."</font>); 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;} 
</li><li>&#160;&#160;&#160;&#160;} </li></ol></div><br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;代码2<br /><br />&#160;&#160;&#160;&#160;正如你所看到的，和代码1相比它只是做了3次循环，每个循环执行一个表的操作。虽然麻烦，但是却真正的享受到了batch处理的好处！下面是时候解释一下这两段代码幕后的秘密了☻。<br />&#160;&#160;&#160;&#160;在前面的章节里已经解释了JDBC如何做batch处理，如果还不清楚的话请查看前面的章节。要解释这两段代码里面的玄机，还得看一段代码☻下面的代码是从iBatis源码中提取的：<br /><div class="codeStyle"><ol><li>&#160;&#160;&#160;&#160;<b><font color="#0000ff">public</font></b>&#160;<b><font color="#0000ff">void</font></b>&#160;addBatch(RequestScope&#160;request,&#160;<font color="#ff0000">Connection</font>&#160;conn,&#160;<b><a href="http://www.javaresearch.org/source/jdk142/java/lang/String.java.html" target="_blank"><font class="classLink"><u>String</u></font></a></b>&#160;sql,&#160;<b><a href="http://www.javaresearch.org/source/jdk142/java/lang/Object.java.html" target="_blank"><font class="classLink"><u>Object</u></font></a></b>[]&#160;parameters&#160;&#160;)&#160;{ 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;<font color="#ff0000">PreparedStatement</font>&#160;ps&#160;=&#160;<b><font color="#0000ff">null</font></b>; 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;<b><font color="#0000ff">if</font></b>&#160;(currentSql&#160;!=&#160;<b><font color="#0000ff">null</font></b></li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&amp;&amp;&#160;sql.hashCode()&#160;==&#160;currentSql.hashCode() 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&amp;&amp;&#160;sql.<b><font color="#0000ff">length</font></b>()&#160;==&#160;currentSql.<b><font color="#0000ff">length</font></b>())&#160;{ 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;<b><font color="#0000ff">int</font></b>&#160;last&#160;=&#160;statementList.size()&#160;-&#160;1; 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;ps&#160;=&#160;(<font color="#ff0000">PreparedStatement</font>)&#160;statementList.get(last); 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;}&#160;<b><font color="#0000ff">else</font></b>&#160;{ 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;ps&#160;=&#160;conn.prepareStatement(sql); 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;currentSql&#160;=&#160;sql; 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;statementList.add(ps); 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;} 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;request.getParameterMap().setParameters(request,&#160;ps,&#160;parameters); 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;ps.addBatch(); 
</li><li>&#160;&#160;&#160;&#160;&#160;&#160;size++; 
</li><li>&#160;&#160;&#160;&#160;} </li></ol></div><br />&#160;&#160;&#160;&#160;这就是iBatis中batch处理的做法，在这里不想对这段代码做一一解释，有兴趣的可以自己查看一下iBatis的源码，我们只关心它如何对一条语句进行处理。参数sql是要进行batch处理的语句，parameters是sql的参数列表，如果sql和实例变量currentSql相等，则从statementList列表里面得到一个PreparedStatement，然后进行batch处理，如果不等就新生成一个PreparedStatement对象，并把它加到statementList列表里面，并把当前sql的值附给currentSql，下次传递来sql的时候就会和这个新的currentSql比较。这就是为什么在一个循环里面只对一个表进行处理的原因了。如果在一个循环里面对多个表进行处理，每次传给addBatch方法的sql都是新的，都会生成一个新的PreparedStatement，所以也就享受不到batch处理带来的好处了！&#160;&#160;&#160;&#160;<br /><br />&#160;&#160;&#160;按照代码1的方式执行程序，当batch&#160;size很小的时候尽管享受不到batch处理带来的好处，但是也不至于会出什么大问题，但是当batch&#160;size值很大的时候（我在程序中试验过1000-5000范围），数据库就会报错了！错误是"too&#160;many&#160;courses"，原因是每生成一个PreparedStatement实例，就会相应的生成一个course。假设batch&#160;size是5000，要删除10个表的数据，那么产生的course的数目就是5000*10=50000，这对数据库来说是不能接受<br />的，所以就会报错。<br /><br />&#160;&#160;&#160;&#160;如果按照代码2的的方式写程序肯定是没有问题的，只会生成10个PreparedStatement实例，相应的也只会生成10个course，这样就真正的享受到了batch处理带来的好处。但是，作为一名&#8220;挑剔&#8221;的程序员，我们怎么能容忍这样的写法呢？明明一个循环就可以搞定，现在要分成10个循环来做，非但效率上存在问题，大量重复的代码也让我们的程序显得很没&#8220;水准&#8221;。<br /><br />&#160;&#160;&#160;&#160;既然第一种方式不能享受batch处理带来的好处，并且还会出错，第二种方式代码又非常的丑陋，那么我们就得想个办法来解决这个问题了。请记住：解决问题的过程就是一种享受☻。<br /><br /><b>修改底层代码，支持多表batch处理</b><br /><br />&#160;&#160;&#160;&#160;既然出问题的地方找到了，那么解决它就很容易了。什么,你说还不知道问题出在哪？My&#160;God!&#160;Kill&#160;me&#160;,pleale☻！&#160;<br /><br />&#160;&#160;&#160;&#160;在这里分享一下我的思路，把每次传近来的sql作为key、把生成的PreparedStatement实例作为value放在一个Map里以后每次传来sql时先判断在Map里有没有这个key，如果有就直接拿到它的value作为PreparedStatement实例，如果没有就新生成一个PreparedStatement实例并把它放到Map里。这样有几个sql就有几个PreparedStatement<br />实例，和写多个循环效果是一样的。但写一个循环会更爽☻！&#160;<br /><br /><font color="#ff0000"><strong>后记：<br /><br /></strong></font><font face="Verdana" color="#000000">&#160;&#160;&#160;&#160;&#160;&#160;在一般的项目中做batch处理的地方似乎都是先取得一个条件列表list，然后直接根据这个list的大小作为batch　size做一个循环。如果你在这个循环里同时进行多个表的ＣＵＤ操作，那么这里就有一个安全隐患存在。当你的list不太大的时候，你怎么测试程序它都不会出问题，尽管可能会有执行效率上的问题，但是当突然有一天这个list变的很大的时候，你的程序可能就突然&#8220;罢工&#8221;了。&#160;<br /><br />　　对于这个问题，我在上面的文档里提出了改进batch处理的方法，另外还有需要注意的一个问题就是这个list的大小的问题。如果这个list的size有可能会很大，那么我们应该考虑根据这个list的大小&#8220;分批&#8221;执行。因为并不是batch　size越大效果就越好，如果batch的size很大的话很可能产生效率和性能上的问题。至于这个batch　size的值为多少比较合适就没有一个固定的说法，这个可能要取决于你所使用的服务器和数据库的性能了，另外不同厂商的ＪＤＢＣ驱动也会有不同的性能表现，你可以向ＤＢＡ咨询相关的问题。&#160;<br /><br />　　我们应该尽可能把问题扼杀在摇篮之中。除了改进iＢatis的batch处理机智外，还应该适当的规划batch　size大小，以避免发生问题，提高执行效率。&#160;<br /><br />　　上述是我个人的观点，有些地方可能不是很准确。如果你的程序中存在类似的问题，可以适当参考一下我的意见，最好还是向专业人士咨询。</font><img src ="http://www.blogjava.net/pdw2009/aggbug/88554.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pdw2009/" target="_blank">有猫相伴的日子</a> 2006-12-18 15:11 <a href="http://www.blogjava.net/pdw2009/archive/2006/12/18/88554.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div><br>文章来源:<a href='http://www.blogjava.net/pdw2009/archive/2006/12/18/88554.html'>http://www.blogjava.net/pdw2009/archive/2006/12/18/88554.html</a> <img src ="http://www.blogjava.net/atlantic23/aggbug/215828.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/atlantic23/" target="_blank">chencj</a> 2008-07-18 15:37 <a href="http://www.blogjava.net/atlantic23/archive/2008/07/18/215828.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[导入]Ibatis学习随笔</title><link>http://www.blogjava.net/atlantic23/archive/2008/07/18/215827.html</link><dc:creator>chencj</dc:creator><author>chencj</author><pubDate>Fri, 18 Jul 2008 07:37:00 GMT</pubDate><guid>http://www.blogjava.net/atlantic23/archive/2008/07/18/215827.html</guid><wfw:comment>http://www.blogjava.net/atlantic23/comments/215827.html</wfw:comment><comments>http://www.blogjava.net/atlantic23/archive/2008/07/18/215827.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/atlantic23/comments/commentRss/215827.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/atlantic23/services/trackbacks/215827.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &lt;
				person
				&gt;
				&#160;&#160;&#160;&#160;
				&lt;
				id
				&gt;
				1
				&lt;/
				id
				&gt;
				
						&#160;&#160;&#160;
				&lt;
				firstName
				&gt;
				Clinton
				&lt;/
				firstName
				&gt...&nbsp;&nbsp;<a href='http://www.blogjava.net/pdw2009/archive/2007/01/04/91844.html'>阅读全文</a><img src ="http://www.blogjava.net/pdw2009/aggbug/91844.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pdw2009/" target="_blank">有猫相伴的日子</a> 2007-01-04 21:31 <a href="http://www.blogjava.net/pdw2009/archive/2007/01/04/91844.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div><br>文章来源:<a href='http://www.blogjava.net/pdw2009/archive/2007/01/04/91844.html'>http://www.blogjava.net/pdw2009/archive/2007/01/04/91844.html</a> <img src ="http://www.blogjava.net/atlantic23/aggbug/215827.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/atlantic23/" target="_blank">chencj</a> 2008-07-18 15:37 <a href="http://www.blogjava.net/atlantic23/archive/2008/07/18/215827.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[导入]hibernate复习随记</title><link>http://www.blogjava.net/atlantic23/archive/2008/07/18/215826.html</link><dc:creator>chencj</dc:creator><author>chencj</author><pubDate>Fri, 18 Jul 2008 07:37:00 GMT</pubDate><guid>http://www.blogjava.net/atlantic23/archive/2008/07/18/215826.html</guid><wfw:comment>http://www.blogjava.net/atlantic23/comments/215826.html</wfw:comment><comments>http://www.blogjava.net/atlantic23/archive/2008/07/18/215826.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/atlantic23/comments/commentRss/215826.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/atlantic23/services/trackbacks/215826.html</trackback:ping><description><![CDATA[1、hibernate集合映射击与集体映射的区别在集合映射的表没有主键ID，从hibernate角度来说就是没有ID属性，hibernate不会赋予它ID值，映射的从表要有主键ID，就必须要在集合映射用到实体映射<br />
<img src ="http://www.blogjava.net/pdw2009/aggbug/157613.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pdw2009/" target="_blank">有猫相伴的日子</a> 2007-11-01 22:27 <a href="http://www.blogjava.net/pdw2009/archive/2007/11/01/157613.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div><br>文章来源:<a href='http://www.blogjava.net/pdw2009/archive/2007/11/01/157613.html'>http://www.blogjava.net/pdw2009/archive/2007/11/01/157613.html</a> <img src ="http://www.blogjava.net/atlantic23/aggbug/215826.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/atlantic23/" target="_blank">chencj</a> 2008-07-18 15:37 <a href="http://www.blogjava.net/atlantic23/archive/2008/07/18/215826.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>