We read the world wrong and say that it deceives us.

Parameter index out of range (1 > number of parameters, which is 0).

今天调数据库课程设计(Java+MySql)的时候通过Tomcat测试的时候总是抛出“Parameter index out of range (1 > number of parameters, which is 0).”的异常,系统提示出错的行是如下标示“抛出异常”的行。

  1. public List<Book> searchBorrowed(String id) throws Exception {
  2. List<Book> allBooks = new ArrayList<Book>();
  3. PreparedStatement pstmt = null;
  4. ResultSet rs = null;
  5. String sql = "select b.name as name,b.author as author,b.category as category,borr.btime as btime,borr.rtime as rtime from borrowed borr,books b where borr.bid=b.id and isreturn=0 and pid=?";
  6. pstmt = conn.prepareStatement(sql);
  7. pstmt.setString(1, id);//抛出异常!
  8. rs = pstmt.executeQuery();
  9. while (rs.next()) {
  10. Book book = new Book();
  11. book.setName(rs.getString("name"));
  12. book.setAuthor(rs.getString("author"));
  13. book.setCategory(rs.getString("category"));
  14. book.setBtime(Long.getLong(rs.getString("btime")));
  15. book.setRtime(Long.getLong(rs.getString("rtime")));
  16. allBooks.add(book);
  17. }
  18. return allBooks;
  19. }

 

经过多次测试,甚至编写了一个测试用的类直接本地运行调用这个函数却没有出错,Google搜索了下,大家出现这个问题大部分都是ParparedStatement的用法有问题或者Sql语句写的有问题,查了很久,也没找到原因,而最后看到 这里 最后一段话,令我恍然大悟:

Please forget about it. I found why the error was occurring.
I was actually using one single PreparedStatement for two different
methods (silly me), and when the flow returned from the called method,
it still was the first preparedstatement rather than the new one,
hence it couldn't found the parameter in the proper indexed position.

 

大体意思是说他使用同一个pstmt执行了两条查询以后出现了这个问题,仔细查看源代码,发现我使用了数据库连接之后没有释放,再次调用的时候,系统就没有再实例化新的pstmt而是直接把刚才用过的这个实例返回给我了,而那个测试用的类没有出现这个问题是因为他仅仅执行了一个SQL查询就退出了,不像我实际中使用的前面还执行了一个登录的过程。知道了问题所在解决起来也便简单的多了,使用代理模式重构代码,通过代理来访问这个具体的数据库操作,从代理中来对数据库的连接与关闭进行处理,这样即更好的解耦,又使得我不用去关注数据库的连接与关闭操作,直接交给代理完成就可以了 :)

一口“盐汽水”喷死你!

我想看过《爱情公寓》的人对标题中的这句话一定不会陌生,而今天我竟然在学校的超市内看到了“盐汽水”哈哈……不过话说回来,这个柠檬味的盐汽水果然不怎么好喝哎……感觉有一股薄荷的味道……不过,这下,一口盐汽水喷死你终于可以变成现实了……

2011 - 05 - 23分享心得

2条评论
390 views

你会出这样的错误么?

public class Hello{
	public static final String DBDRIVER="org.gjt.mm.mysql.Driver";
		public static void main(String[] args) {
		try{
		Class.forName("DBDRIVER");
	}catch(Exception e){
		e.printStackTrace();}
	}
}

今天为了连接mysql数据库写了这样一段java代码,无奈却总是报错:

F:\Java>java Hello
java.lang.ClassNotFoundException: DBDRIVER
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Unknown Source)
        at Hello.main(Hello.java:5)

大家看了这段异常会不会认为我是配置”classpath”配置错误了,可是,并不是那样的,我确信我的classpath没有配置错误,你知道他为什么会出这样的错误么……

继续阅读 »

2011 - 05 - 21胡思乱想

4条评论
488 views

转载:帅哥与蟑螂的故事

1
小蟑螂趴在碗柜上偷窥。
那个帅哥哼着小曲儿在洗碗,嗯哼嗯哼,哗啦哗啦。
帅哥洗碗都这么好听吗。小蟑螂爱屋及乌了,帅哥干什么都好看。
小蟑螂黑黑的小脸儿红了。
2
小蟑螂今年一岁多,是三个月前搬到这户人家的。
没办法,上一家的药太厉害了,一下子就把妹妹药死了。
小蟑螂好难过,看着妹妹被纸巾包住,丢进垃圾桶。
小蟑螂再也不敢在那家偷吃东西,饿着肚子逃出来,来到帅哥家。
帅哥大大咧咧,懒得买蟑螂药。帅哥妈妈曾经来帮忙撒药,却不知道撒的都是过期货。
帅哥根本就不怕蟑螂。小蟑螂就住了下来。
3
小蟑螂溜到水槽下的垃圾桶,偷吃里面过期的面包。
帅哥买的面包是蛋奶味的,小蟑螂很喜欢,甜甜的好好吃。
帅哥家的厨房没有蟑螂药。
小蟑螂觉得好开心。
但是帅哥倒垃圾很勤快,如果不抓紧吃掉的话,食物很快就会不见啦。
帅哥还是挺爱干净的。
小蟑螂难过起来,爱干净的帅哥不会喜欢脏乎乎的小蟑螂。 继续阅读 »

动易SiteFactory前台调用工作量统计

最近有这样一个需求,需要在SiteFactory的前台调用作者的工作量统计,发现系统自身并没有提供这样的一个功能,作为一个Programer,这哪能难得住我,嘿嘿,仔细查询了SiteFactory提供的“数据结构”文档,发现在“PE_CommonModel”表中存放了大家发表的各种类型的内容。我想要实现的是统计当月每个人的发文数量(不含未通过审核的)并且按照发文数量进行排序,这样一分析SQL查询语句就出来了:

SELECT  Editor,count(*) AS Num
	FROM PE_CommonModel
		WHERE ModelID=1
			AND NodeID=10
			AND datepart(mm,UpdateTime)=datepart(mm,getdate())
			AND datepart(yy,UpdateTime)=datepart(yy,getdate())
			AND STATUS=99
		GROUP BY Editor
		ORDER BY num DESC;

简单对上面的SQL做下解释,select后面的Editor这个是要统计“作者”,如果大家需要统计“输入者”,可以将此换为“Inputer”,后面的count(*) as Num 是计算发文数量,并用Num表示,这里用Num表示也是为了后面排序时引用方便。

ModelID这一项表示了文章模型,在我的SiteFactory中,ModelID=1代表是文章模型,而NodeID代表了需要统计的小类名称,如果想要统计全部,可以去掉“and NodeID=10”这一行。后面detepart()函数为SqlServer内置的函数,用以格式化时间类型的字段,通过这两句就将查询的文章时间限定在“当月”,当然,你也可以将这两句合为一句:

AND datepart(yymm,UpdateTime)=datepart(yymm,getdate())

后面的status=99代表了所有审核通过的文章,具体的status代码,请自行查询SiteFactory的相关文档。

最后的Group By以及Order By决定了分组及排序的字段,学过Sql的人一定都能明白,这里就不废话了。最后我将我的这个标签导出了,供大家导入测试。当然,如果你有心的话还可以将我所说的那些内容都替换成变量,然后调用标签的时候就能以参数的形式传递进去了,我嘛比较懒,嘿嘿,就不搞啦~~

当月工作量统计标签,单击下载。

联通WLAN使用VPN就掉线的解决方案

联通的WLAN活动对于后付费用户还在依然免费中,这确实让我觉得很爽,不过因为种种原因,经常需要使用VPN,而联通的WLAN使用VPN的时候大约1分钟左右就会掉线,小小研究了下下,发现原来基于Web验证的这个页面每隔一分钟左右就会跟服务器联系一次(心跳),如果联系不到或者超时,就会强迫用户下线~~

既然知道了原理,想要解决也变得相当容易,首先需要收集最近的路由表,我们手动把这些路由写入到本机路由,通过命令:

route add IP地址 mask 子网掩码 网关 metric 优先级

这样的顺序即可。

附件为自动识别网关,并作为当前默认网关的批处理,大家可以再增加任意多条route命令来调整本地路由 :)

当然,这样的好处还有一个:可以让VPN流量走VPN网关,而其他的流量还是走自己的网关,降低VPN的负载,增加安全性与本地网站的访问速度。

附件:Route-Test

2011 - 04 - 21分享心得

2条评论
724 views

ESX挂载NAS存储

之前部署了几台Esx Server,通过VC进行集中控管,这几天需要挂载NAS存储,连上去看了看,发现他们已经用得很好了,甚至还部署出了“Server Cluster”,在云技术突出的今天,这种应用可能是最贴近企业的了。

好了,废话不多说,我们步入正题,挂载NAS存储有什么好处呢?好处之一,提高了整个虚拟机系统的HA特性(High Availability 高可用性),这样可以在某一台虚拟机/宿主机down掉的情况下自动迁移到其他的虚拟机/宿主机,可以最大程度提高业务连续工作的时间,此外,由于挂载了存储,使得宿主机的硬盘得到了解放,甚至可以做到unlimited~~但是如果把所有的虚拟机都放在存储上,一旦存储出现问题,那造成的影响也是灾难性的,所以,如果对此有较高要求的公司或企业,可以搞NAS热备,哈哈哈 那成本,就不在本文讨论范围之列了吧 :) 继续阅读 »

人人网竟然也在电子邮件领域插了一只脚

今天忽然想起淫淫网网的个性域名还是用的以前我的真实姓名的拼音,觉得想要改成Kaisir这样比较统一,嘿嘿,于是就兴冲冲的跑到淫淫网去改。

就说Kaisir我观察细致嘛~~这一改不要紧,意外的发现了这样的一行小字:

咦,这里竟然有一个个性邮箱,是以@renren.com这个域结尾的,难道人人网进军E-mail领域了?试探性的访问了http://mail.renren.com,结果页面跳转到了http://msg.renren.com这才意识到,果然淫淫网提供了邮件服务,过了一会儿,收到一封站内信,提示我已经开通了淫淫网的邮件系统,不过这个邮件系统很特别,只接收通讯录里的好友邮件以及你通过淫淫网发送出去的邮件,说是这样是为了屏蔽垃圾邮件……汗死,那不认识的人完全不能用这个Mail咯,哈哈 可能淫淫网关注的是熟人之间的联络吧:)

这个邮件系统速度还可以,与Gmail做了测试,之间确实是立刻就送达了,而且这个域还比较新,没被Gmail判别到垃圾邮件中去:)

无聊之中发现了淫淫网的一个小功能,随手一写,虽然不玩淫淫了,但还是跟部落格同步滴,还是欢迎大家没事来踩踩~~

我滴人人网地址:http://www.renren.com/kaisir

我滴部落格地址:http://Kaisir.Com

2011 - 04 - 14分享心得

没有评论
289 views

使用NVelocity出现的一则问题

这几天在做一款开源SNS的二次开发,这款基于.Net的SNS使用了Java平台上广泛使用的Velocity模板引擎的.Net版(看着有点像绕口令 哈哈),不过在调试的过程中,发现自己的含有中文部分的html代码全变成了乱码,第一反应就是编码不对,查看编码为Utf-8,而开源SNS中使用的编码也是utf-8,很无奈,打开那个SNS中自带的一个模板,另存时看了下,发现他保存的格式为“带签名的utf-8”把自己写的模板另存为“带签名的utf-8”,一切正常!

小知识:UTF-8与UTF-8带签名的区别
当带签名的UTF-8编码内容被浏览器解析时,浏览器直接根据签名即可判断出使用UTF-8编码来进行解析,当不带签名时,浏览器会根据内容的编码来进行判别。简而言之,带签名的将更容易被浏览器以正确的编码方式进行解析。(来源:Lucky的部落格

补充内容:
1)php UTF8 文件的签名问题
2)识别不带BOM(无签名)的UTF-8文件

自动词法分析器,LEX

编译原理作业——编制一个词法分析器。

显然做这个作业有两种途径,
1)自己编
2)google+biadu+others.

昨天Simon童鞋给我说他们让搞lex,好吧那我也正好凑凑热闹,嘿嘿。结果别说,还让我整出来了,lex简单应用语法还是很简单的,附上我的lex源程序,kaisir.l
(我这个wp的代码高亮不支持lex,大家凑合着看吧  我懒……)

%{
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
int lineno=1;
%}
letter [A-Z,a-z]
digit [0-9]
id ({letter}|_)({letter}|{digit}|_)*
error_id ({digit})+({letter})+
num {digit}+
whitespace [\t]+
enter [\n]+
%%
"int"|"if"|"else"|"return"|"void"|"while" {Upper(yytext,yyleng);
printf("%d 行  ",lineno);
printf("%s	reserved word\n",yytext);
}
{num} {
printf("%d 行  ",lineno);
printf("%s	NUM\n",yytext);
}
","|";"|"("|")"|"+"|"-"|"*"|"/"|"=="|"<="|">="|"!="|"=" {printf("%d 行  ",lineno);
printf("%s	special symbol\n",yytext);
}
{id} {printf("%d 行  ",lineno);
printf("%s	ID\n",yytext);
}
{error_id} {printf("%d 行  ",lineno);
printf("error:	%s\n",yytext);
}
{whitespace} {
}
{enter} {lineno++;
}
%%
Upper(char *s,int l){
int i;
for(i=0;i<l;i++)
{s[i]=toupper(s[i]);}
}
//Main
main(void)
{
  char filename[400];
  printf("file name:");
  scanf("%s",&filename);
  yyin=fopen(filename,"r");
  printf("Starting..\n");
  return yylex();
}

在ubuntu下使用

flex kaisir.l

顺利通过,之后使用gcc对flex生存的lex.yy.c进行编译,结果报错如下:

kaisir@Kaisir-ubuntu:~$ gcc -g lex.yy.c -o a.out
test.txt: In function 鈓ain?
test.txt:49: warning: format ?s?expects type 鈉har *? but argument 2 has type 鈉har (*)[400]?
/tmp/ccmK1ARZ.o: In function `yylex’:
/home/kaisir/lex.yy.c:902: undefined reference to `yywrap’
/tmp/ccmK1ARZ.o: In function `input’:
/home/kaisir/lex.yy.c:1237: undefined reference to `yywrap’
collect2: ld returned 1 exit status

大体看了下说是yylex这个函数找不到,baidu了下,编译的时候增加参数“–lfl” 顺利编译通过,写了个Test.C进行词法分析,No Problem!

kaisir@Kaisir-ubuntu:~$ ./a.out hellolex.c
file name:hellolex.c
Starting..
1 行  VOID      reserved word
1 行  main     ID
1 行  ( special symbol
1 行  ) special symbol
{3 行  INT      reserved word
3 行  a        ID
3 行  ; special symbol
4 行  a ID
4 行  = special symbol
4 行  10        NUM
4 行  ; special symbol
5 行  printf    ID
5 行  ( special symbol
5 行  a ID
5 行  ) special symbol
5 行  ; special symbol
}

返回顶部