程序开发
iBATIS中LIKE的用法
在 iBATIS中使用 LIKE语句查询,%%会被替换成 ?,所以没法使用,可以通过以下的方式 Oracle: SELECT * FROM user WHERE username LIKE '%' || #username# || '%' Mysql: SELECT * FROM user WHERE username LIKE CONCAT('%', #username#, '%') SQLServer: SELECT * FROM user WHERE username LIKE '%' + #username# + '%'
JavaScript小记
1、关于class和className class属性在W3C DOM中扮演着很重要的角色,但由于浏览器差异性仍然存在。使用setAttribute("class", vName)语句动态设置Element的class属性在firefox中是行的通的,在IE中却不行。因为使用IE内核的浏览器不认识"class",要改用"className"; 同样,firefox 也不认识"className"。所以常用的方法是二者兼备: element.setAttribute("class", vName); element.setAttribute("className", vName); //for IE 2、setAttribute()的差异 我们经常需要在JavaScript中给Element动态添加各种属性,这可以通过使用setAttribute()来实现,这就涉及到了浏览器的兼容性问题。 var bar = document.getElementById("foo"); bar.setAttribute("onclick", "javascript:alert('This is a test!');"); 这里利用setAttribute指定e的onclick属性,简单,很好理解。但是IE不支持,IE并不是不支持setAttribute这个函数,而是不支持用setAttribute设置某些属性,例如对象属性、集合属性、事件属性,也就是说用setAttribute设置style和onclick这些属性在IE中是行不通的。为达到兼容各种浏览器的效果,可以用点符号法来设置Element的对象属性、集合属性和事件属性。 document.getElementById("foo").className = "fruit"; document.getElementById("foo").style.cssText = "color: #00f;"; document.getElementById("foo").style.color = "#00f"; document.getElementById("foo").onclick= function () { alert("This is a test!"); } 3、firefox中不能用 cursor:hand style="cursor:hand;" 在IE中能正常显示成手;在firefox中却不能正常显示如果改用 style="cursor:pointer;" 则在两个浏览器下都能正常显示
Servlet映射地址形式
众所周知,Servlet在编写完毕后,必须先在web.xml中配置才能访问。在配置时,需要指定一个Servlet的访问地址。Servlet映射地址不是随便怎么写都可以,必须要遵从一定的规则,这个规则在Servlet的规范中有详细的说明。按照Servlet规范的要求,Servlet映射地址形式只能有四种,即: 第一种、以“/”开头,以“/*”结束的地址,这种地址映射称为路径映射。这种映射中使用了通配符,代表访问这个目录下的任意一个地址都将调用这个Servlet。比如,一个Servlet映射的地址是“/admin/*”,那么当访问/admin这个目录下的任意一个地址,都会映射到这个Servlet上,除非这个地址已经明确地映射到其它的Servlet上了。也即,当另外一个Servlet映射的地址是“/admin/listUser”,那么当访问这个地址时,请求还是会被映射到这人Servlet上。 第二种、以“*.”开头的地址,这种地址映射称为扩展名映射。这也是一种模糊映射,代表访问相同扩展名的地址时,都会映射到这个Servlet上。这种地址映射在Struts中就得到了应用,即所有访问以.do结束的地址时,都会映射到ActionServlet上。但不能将第一种与第二种地址映射形式结合起来用,即如果写成“/admin/*.do”,这就错了。没有原因,因为这是规范。 第三种、只有一个“/”的地址映射,这种地址映射称为默认映射。也就是说,如果用户访问了一个地址,这个地址没有明确地在web.xml中映射,也不满足以上两种形式的模糊映射,这个时候就访问“/”映射的Servlet。这种地址映射,我们在实际开发中很少应用,但它对服务器来说是很重要的。以Tomcat为例,Tomcat实际上是一个纯粹的Servlet容器,也就是说,只有Servlet才能在Tomcat上运行。但有可能会说,我们将HTML文件部署到Tomcat上也运行得很好啊。没错,但真正运行的还是Servlet。什么意思呢?大家可以想一下,我们部署到服务器上所有的HTML文件,我们从来都不会到web.xml中去映射的,根据我们刚刚讲到的,如果访问了没有映射的地址,服务器会访问“/”所对应的Servlet,而正是这个Servlet帮我们找到HTML文件,并把它写到客户端的。也就是说,Tomcat预先定义了一个Servlet,并把它的地址映射为“/”。这样其它静态资源的访问实际上都是在访问这个Servlet,而它的职责则是简单地找到这个文件,并把它们写到响应中去。 第四种、明确的地址映射,这是我们最常用的一种地址映射形式。规范中没有对这种地址映射有特殊的要求,但在配置地址时,必须以“/”开头才可以,否则将报错。 总结以上几种地址形式,我们可以了解到服务器在接收到一个地址请求后的处理流程。以一个用户访问http://www.sodii.com/class_intro/viewClassIntro.htm?id=1这个地址为例: 第一步,服务器首先看/class_intro/viewClassIntro.htm这个地址有没有明确地映射,如果已经明确地映射了这个地址,则直接访问地址所对应的Servlet,处理请求生成响应。 第二步,如果没有明确映射这个地址,则看目录映射或扩展名映射中有没有满足这个地址的。也即有没有映射地址为“/class_intro/*”,或者“*.htm”的Servlet,如果有一个满足就访问其所对应的Servlet。如果两个都满足,则访问目录映射所对应的Servlet。 第三步,如果也不满足模糊映射,则访问“/”所对应的Servlet。
JSP学习小记
在调用javaBean的时候,javaBean一定要在包里,不能在默认的包里,这样会出现“The server encountered an internal error () that prevented it from fulfilling this request.”的错误,本人在这个问题上花了一个多小时,查了N多资料,总算是解决了。说到底还是在学java的时候养成的坏习惯,不喜欢用包。 在eclipse里调试好后,想要部署的时候,需要把jsp文件放到工作目录后,把编译好的.class文件放到工作目录里的WEB-INF\classes\包目录里,这样就可以正常运行了。 在编译.java文件的时候出错:软件包 javax.servlet 不存在,解决方法: 方法(1) 找到%tomcat%\common\lib目录下的servlet-api.jar,把这个路径添加到环境变量classpath当中,就可以了。(这个好像不是很管用,我重装了tomcat之后,再重新配置好像就不行了) 方法(2) 找到%tomcat%\common\lib目录下的servlet-api.jar,把这个jar添加到%java_home%/\jdk1.6.0\jre\lib\ext目录下面,不同的jdk版本都一样。 设置虚拟目录后,把已经做好的项目从TomCat主目录里剪到虚拟目录,发现不能运行,提示找不到javabean,原因是虚拟目录里面,不能有子目录。
JSP开发环境
开始一直在考虑用windows还是在linux下开发jsp,其实本质上是一样的,不过由于eclipse在linux下的超慢响应,还是决定在windows下搭建JSP开发环境。 下载jdk,tomcat,eclipse,均为最新版本。 首先安装jdk,并设置环境变量 JAVA_HOME=(安装目录) PATH=%PATH%;%JAVA_HOME%\bin CLASSPATH=.\;%JAVA_HOME%\lib\tools.jar 再安装tomcat,设置环境变量 TOMCAT_HOME=(安装目录) 打开浏览器,在地址栏中输入http://localhost:8080(Tomcat默认端口为8080),如果在浏览器中看到Tomcat的欢迎界面,表示Tomcat工作正常。 准备test.jsp <HTML> <HEAD> <TITLE>JSP测试页面</TITLE> </HEAD> <BODY> <%out.println("<h1>Hello World!</h1>");%> </BODY> </HTML> 放到安装目录的webapps\examples\jsp目录下在地址栏中输入http://localhost:8080/examples/jsp/test.jsp,如果浏览器中显示"Hello World!",则说明你的JSP环境配置成功了! eclipse的使用,建议下载eclipse jee版本,专门为web版定制的。 Tomcat虚拟目录设置 tomcat 安装好之后,只需要把你的程序包放到$Tomcat_Home$/webapps下就可以直接使用了。这样会使webapps越来越大就需要设置虚拟目录: 1.单个应用设置: 在和之间加上 参数:path 表示在浏览器中输入http://localhost:8080/site docBase表示你的程序包的物理绝对路径,默认的绝对路径是$Tomcat_Home$/webapps 这样设定了之后会在$tomcat_home$/conf/catalina/localhost目录下生成一个site.xml文件,此文件的内容就是刚才设置的内容。 2.通过前面我们知道了在$tomcat_home$/conf/catalina/localhost目录下会生成相应的配置文件,因此我们可以直接在$tomcat_home$/conf/catalina/localhost目录下写配置文件文件名任意取,最好是跟你的web应用相同便于管理,如site.xml内容同上 3.更改整个根目录: 找到 将appBase的设置成期望的路径(绝对路径) 出现的问题:输入:http://localhost:8080/没有出现默认的页面 原因当然是更改了路径造成的。解决也很简单了,把文件拷过来,或者再把原来默认的设成虚拟路径。
玩把中文编程
现在中文编程似乎很火,虽然没有接触过,但是既然是编程,原理肯定是一样的,因此突发奇想,也来玩把中文编程。 打开VS2008,新建一个win32控制台程序,在里面输入代码如下 是不是有点眼熟,其实秘密都在han.h里 现在了解了吧,其实中文编程就是这么回事。
Windows关机API
包含windows.h 然后调用ExitWindowsEx BOOL ExitWindowsEx( UINT uFlags, DWORD dwReason ); uFlags的值: EWX_LOGOFF,0,注销 EWX_SHUTDOWN,1,关机 EWX_REBOOT,2,重启 EWX_POWEROFF,8,断开电源 EWX_FORCE,4,强制终止所有程序 EWX_FORCEIFHUNG,16,强制终止未响应的程序 后面的dwReason一般不指定,具体内容可以去微软的MSDN站上查阅。 win9x 的话可以用ExitWindowEx直接关机,但是在WinNT内核系统下需要先获得特殊权限才能关机 用 OpenProcessToken 和 LookupPrivilegeValue 获得并制定特权,用AdjustTokenPrivileges启动特权,然后再用 ExitWindowsEx 关机 //Win2000&WinNT实现的代码 HANDLE hToken; TOKEN_PRIVILEGES tkp; if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, &hToken)) { LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid); tkp.PrivilegeCount = 1; tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0); ExitWindowsEx(EWX_SHUTDOWN|EWX_POWEROFF, 0); } //Win9x实现的代码 ExitWindowsEx(EWX_SHUTDOWN|EWX_POWEROFF, 0);
Linux下Unicode编程
直接输出中文 #include <iostream> using namespace std; int main() { wchar_t *dest=L"中文测试"; setlocale(LC_ALL,""); wcout<<dest<<endl; } 转换后输出中文 #include <iostream> using namespace std; int main() { char *src="中文" mce_src="中文"; wchar_t dest[10]; setlocale(LC_ALL,""); mbstowcs(dest,src,strlen(src)); wcout<<dest<<endl; }
Linux下的C++编译
以前在VC下写C++,一般只用包含h文件,不用包含cpp,但是发现用g++编译是时候不行,一定要包含cpp文件,找了些资料,发现是编译参数上的问题 假设有hello.h,hello.cpp,main.cpp三个文件,里面的内容就不写了,在main.cpp里#include "hello.h",直接用g++编译会报错,其实只要在编译时加参数-c就可以了,作用是编译成目标文件 g++ -c hello.cpp -o hello.o g++ main.cpp hello.o -o main 这样就可以了
WINDOWS钩子技术的补充
玩WINDOWS的钩子技术时发现,在DLL中用PostMessage发消息到主窗口(一个常规MFC程序)时,当主窗口为非焦点时无法接收消息,这不是我想要的。 在钩子处理函数中,用PostMessage(g_hwnd,WM_MY_MESSAGE,wParam,lParam),每当截获到一个消息就向主程序发送WM_MY_MESSAGE消息,并将所捕获的信息一同传送给主程序。而问题在于,发送WM_MY_MESSAGE消息时所用的窗口句柄上,即g_hwnd在原来的代码中仅将变量定义为 static HWND g_hwnd=NULL; 并在dll中导出一个函数SetWindowHandle(HWND hwnd){g_hwnd=hwnd;}用来设置该全局变量。 但是,实际上hook所在的dll将被映射进每个系统中的进程中(如果使用的是系统钩子),那么每次这样的映射都会使g_hwnd被重新制为NULL,因此hook即使截获了鼠标消息,也不能将他准确地传送给主程序。 解决办法是将g_hwnd定义为让所有的dll实例共享 #pragma data_seg("Shared") HWND g_hwnd=NULL; #pragma data_seg() #pragma comment(linker,"/section:Shared,rws") 修改后一切都如我所愿。