2007年1月24日星期三

2007-1-23 星期二

临时计划改变,开始做项目了,有点赶时间的味道,从需求分析开始,昨天画了画用例图,没什么感觉呵呵。

2007年1月23日星期二

2007-1-22 星期一

今天基本上没干活 ,呵呵,上午做了个测试servlet的例子,感觉不爽,用了一个叫 仙人掌 的  web  测试一框架,闹半天还得找它自己的运行错误,不用说测试我自己的了,狗日的,不过测试技术还是很重要的,后天开始做项目,一定要设计一个好点的,哈哈,争取能够上线爽一爽。

发现google的搜索记录功能真是好用,可以将以前搜索的东西记录下来,可以找到很多以前找过的资料。

2007年1月22日星期一

2007-1-21 星期日

这两天,蒸腾了两个例子,听说一个叫struts-menu的框架可以实现基于struts的菜单,照着网上的例子,自己摆弄了一个,哈哈,这东西好,可以做出不同样式的菜单,然后又用struts\struts-menu\spring\hibernate\sqlserver2000实现一个从数据库读取的动态树形菜单,好家伙这可折腾死我了,代码早早的一口气写完了,剩下一堆错误,有些甚至莫名其妙的,大部分时间都在这上面了,这周在学junit,看来很重要,要养成测试的好习惯,按照模块来测试,不能一个程序写好了,再这找那找错,太浪费时间了,这次就是,上来就给我一个下马威,505错误(网络服务器错误)actionServlet不可用,检查struts-config.xml和applicationContext.xml的配置没有见检查出来不对,想必是spring或者hibernate的错误了,在struts-config.xml解除跟spring的关联,直接在action中调用,spring的dao方法,这下可好,哈哈,出来一堆错误,都是不小心的这错那错,一通改之后,最后卡在

hibernate java.lang.ClassCastException: [Ljava.lang.Object

上,是hibernate报的错误,发现在查询后得到的List不知道里面是什么类型,不能强制转换成我的持久类,不能转换成map,那是什么呢,因为我的查询语句是复合查询,最后发现List是Object[],是个Object类型的数组,我见过List里面是Map,持久类,Object[]了,Map是在spring里面通过spring的jdbcTemplete返回的List,里面是Map集合,Map的键是数据库表的字段名,后两个是在hibernate里,一个表查询可能就是返回持久类类型,多个表查询就是Object[]类型了?但Object[]里面是什么,我这里发现里面是每条记录的值,在网上查到,还有可能是多个持久类(多表查询,这个说法我没试过呢),这样把List里取出的转换成Object[],这个错误算是通过了,还有个hibernate java.lang.ClassCastException: java.lang.Integer

[org.apache.struts.action.RequestProcessor] - <Unhandled Exception thrown: class java.lang.NullPointerException>

2007年1月19日星期五

2007-1-18 星期四

哈哈,下午没上课,今天开始的Junit,上午睡了一半的觉,下午无意中看到一个利用google翻译实现的控制台程序,拿过来,刚学的ajax,复制粘贴添加删除,哈哈就成了,但是有个小bug,中文翻译成英文是乱码,其他语言倒是基本没问题,哈哈,可能是编码的问题。还不知道怎么解决。

javascript脚本

       function doTranslate()

{

    var text = document.getElementById("source").value;

    var langpair = document.getElementById("langpair_t").value;

    if(text=="")

    {

       return;

    }

    alert(text);

    var requestURL = "http://translate.google.com/translate_t?langpair="+langpair+"&text=" + text;

    httpRequest = getHttpRequestObject();

    httpRequest.onreadystatechange = processHttpResponse;

    httpRequest.open("GET",requestURL,true);

    httpRequest.send(null);

}

 

function parseXMLResponseInText()

{

    if(httpRequest.responseText!="")

    {

       var content = httpRequest.responseText;

       var s1 = "<div id=result_box dir=ltr>";

       var s2 = "</div>";

       var begin = content.indexOf(s1);

       var end = content.indexOf(s2,begin);

       var restr = content.substring(begin + s1.length,end);

       document.getElementById("result_box").innerText = restr;

   }

}

function processHttpResponse()

{

    if(httpRequest.readyState == 4)

    {

       if(httpRequest.status == 200)

       {

           parseXMLResponseInText();

      }

    }

    else

    {

       document.getElementById("result_box").innerText = "正在翻译...";

    }

}

 

function getHttpRequestObject()

{

    var httpRequestObject;

    if (window.XMLHttpRequest)

    {

       httpRequestObject = new XMLHttpRequest();

    }

    else

    {

       if (window.ActiveXObject)

       {

           try

           {

              httpRequestObject = new ActiveXObject("Microsoft.XMLHTTP");

           }

           catch (e)

           {

              try

              {

                  httpRequestObject = new ActiveXObject("Msxml2.XMLHTTP");

              }

              catch (e2)

              {

                  alert("您的浏览器有问题!");

              }

           }

       }

    }

    return httpRequestObject;

}

明天接着Junit,呵呵。

对了,刚听说一个struts-menu,回去研究研究,好像以前在.net里见过一个实现类似树形框架的控件,还可以实现权限控制,这个也差不多,在网上搜了搜,有好多介绍,等做了例子出来。

2007年1月18日星期四

2007-1-17 星期三

    为了一个用jbuilder2006+weblogic部署webservices,老师弄不出来,而且运行jbuilder再加上weblogic机器慢的要死,一次一次的重试,时间啊。就是不动,哈哈。

最后在网上搜到下面的问题。说是因为jbuilder和weblogic的lib文件版本兼容问题,还有就是weblogic8.1sp3以前的版本不支持sourcerootforupload,所幸重装了weblogic,原来是的,现在装了个9.2的,结果在经过漫长的等待后,终于成功部署了,但是还是由于机器太慢,没看效果,明天再试一试吧。

 

 

Why am I getting the error Unrecognized option or flag, -sourcerootforupload ?

   In order to maintain compatibility between the 8.1 and 9.0 version of the plugin I used a new flag on the deployment engine. 

   The flag was added with service pack 4 on 8.1.  If you are not on service pack 4 or later you will see this error.  If you send a note

   to the mojo mailing list I can create a special version for service pack 3 and earlier.

 

 

还有就是如果出现

Build Failed: The failure is due to a known compatibility issue with WebLogic and Ant 1.6 as WebLogic includes an older version of

的错误就删除WebLogic安装目录下的weblogic81/server/lib/ant下的ant.jar和optional.jar就行了,而我重装成了weblogic9.2以后也没报这样的错误。晕,真让人晕头转向。

 

 

昨天看effective java第二条,建立单立模式,有两种方式,两者都需要构造函数是私有的,一种是,声明一个public static final的属性初始化为这个类的实例,然后直接用类名.属性名返回这个对象,另一种是声明一个private static final的属性,在静态方法中返回这个static final 的对象,这么做的好处就是有回旋的余地,比如不想永远只返回一个相同的对象了,容易修改。在效率上,两种方式应该是不相上下的,因为好的编译器能够监测到内联。

 

时间在一天一天的过,快过年了,这个年不好过啊。

2007年1月17日星期三

2007-1-17 星期三

被熊猫烧香病毒折腾了一中午,我被间接传染了,我的移动硬盘里查到了五个,还好没有在我的电脑里感染,在网上下了个专杀,专杀链接

    另:怎样预防熊猫烧香系列病毒?

转自:金山毒霸信息安全网

最近那个熊猫烧香病毒让所有用电脑的人很生气,熊猫这个国宝似乎不再可爱,而成了人人喊打的过街老鼠。熊猫变种实在太多,中招后的损失很严重,杀毒软件一直在救火中。以下几招很简单易行,帮你预防熊猫烧香病毒,至少能明显减少你中招的几率。

1.立即检查本机administrator组成员口令,一定放弃简单口令甚至空口令,安全的口令是字母数字特殊字符的组合,自己记得住,别让病毒 猜到就行。修改方法,右键单击我的电脑,选择管理,浏览到本地用户和组,在右边的窗格中,选择具备管理员权限的用户名,单击右键,选择设置密码,输入新密 码就行。

2.利用组策略,关闭所有驱动器的自动播放功能。

步骤:单击开始,运行,输入gpedit.msc,打开组策略编辑器,浏览到计算机配置,管理模板,系统,在右边的窗格中选择关闭自动播 放,该配置缺省是未配置,在下拉框中选择所有驱动器,再选取已启用,确定后关闭。最后,在开始,运行中输入gpupdate,确定后,该策略就生效了。

3.修改文件夹选项,以查看不明文件的真实属性,避免无意双击骗子程序中毒。

步骤:打开资源管理器(按windows徽标键+E),点工具菜单下文件夹选项,再点查看,在高级设置中,选择查看所有文件,取消隐藏受保护的操作系统文件,取消隐藏文件扩展名。

4.时刻保持操作系统获得最新的安全更新,建议用毒霸的漏洞扫描功能,汗,很可惜,现在光缆还没修好,网不通,不好修复。

5.启用windows防火墙保护本地计算机。

2007-1-16 星期二

Today,webservice,axis,jbuilder2006

       今天做了两个基于Tomcat的webservice,Tomcat本身不支持webservice,需要有一个axis的插件,说白了就是jar包来支持,webservice利用xml基于soap协议传输来调用远程方法,在客户端和服务器端都有业务提供类的一个接口,他们通过wsdl语言来定义提供的哪些服务,客户端解析服务器端提供的wsdl生成业务类的接口,这样客户端就可以远程调用了。

       利用jbuilder2006构建webservice是很简单的,所有复杂的都自动生成了,但其中还是有些一些bug,比如今天遇到的,建立了一个web应用程序用来提供服务,在通过向导添加webservice服务器端的时候,就是不出现先前建好的web应用,最后在网上查原来是:在JBuilder 2006中建立WebService的服务器端程序的时候,不管怎么试都是卡在建立WEB MODULE这个地方了。主要是JB2006自带的TOMCAT的问题--------把建立WEB MODULE时的 SERVLET版本改成SERVLET 2.3,JSP版本改成JSP1.2就不会卡住了。晕。

       昨天看effective java,第一条,试着用静态工厂方法替代构造函数,原因有:

1、静态工厂方法有名字,可以让人知道这个对象构造出来是什么,比如一个类需要提供几个构造函数,它们有不同的函数原形(函数原型包括函数名和函数的参数但不包括函数的返回类型),这样很可能让用户不能清楚地知道每个构造函数是做什么用的,除非去看文档,而将其中几个构造函数用静态工厂方法代替,解决了这个问题。

2、静态工厂方法可以返回不同的对象,这特别适用于面向接口编程,按照提供的参数可以返回接口的不同的实现。

3、静态工厂方法可以不象构造函数那样每次都创建新的对象,可以是单立的,也可以不创建重复的对象,也就是如果两个对象的属性值相等就不创建新的返回已经存在的。

另外,还提到了静态工厂方法的缺点,1、如果一个类将构造函数设成了private的,用静态工厂方法来创建对象,那么这个类将不能被继承,因为子类不能调用父类的构造方法(已设成私有)。2、静态工厂方法跟其它静态方法没有任何区别,所以必须给它们起一个合适的名字,比如getInstance().,这种说法破坏了已有的规则,但规则,对象都是由构造函数创建的,但使用静态工厂方法又有它的独到的好处。所以在取舍上,作者这样说,在实际开发中,如果没有足够的理由,还是老老实实的使用构造方法来创建对象,毕竟这是已有的规则。

2007年1月16日星期二

2007-1-15 星期一

今天练习了dwr与struts和spring集成,其中与struts集成有点小错误还没查出来,在网上找资料也没有解决。Spring集成倒是挺爽的,顺便回顾了spring的设置,如果spring和strtus集成,首先无论哪种方式都需要在struts-config.xml中以插件方式引入spring的一个加载类ContextLoaderPlugin

<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">

   <set-property property="contextConfigLocation"  value="/WEB-INF/applicationContext.xml" />

</plug-in>

可以用spring的一个接口DelegatingRequestProcessor替换org.apache.struts.action.RequestProcessor类,在web.xml中设置.

 还可以将struts的Action类交给spring的代理类来处理。

还有就是如果只是简单web应用,不用struts,那么在web.xml配置文件中配置一个spring监听器或者servlet,例如

<context-param>

    <param-name>contextConfigLocation</param-name>

    <param-value>/WEB-INF/classes/applicationContext.xml</param-value>

  </context-param>

 

  <listener>

   <listener-class>org.springframework.web.context.ContextLoaderListener

</listener-class>

  </listener>

这样在用到spring Ioc中的对象时就用WebApplicationContextUtils来加载。

2007年1月13日星期六

2007-1-12 星期五

在IBM的developerworks网站上看java的基础教程,将编写修良java代码的建议

         1是保持类最小,如果你的类有100个方法,可能就要考虑考虑是不是要设计成几个对象。呵呵,100个,还没写过,不过想象中应该有,大型的复杂系统。

         2是保持方法最小,一个方法只做一件事。

         3是给方法取个好名字,好名字用处太大了,呵呵呵,特别是别人看别人的代码时,特别是过了一段时间以后,再来看写的代码,特别是系统比较大比较复杂时,我们的脑子没计算机好使。

         4是保持类的数量最小,有时间看看极限编程的东西。这句话好象和第一句话有点矛盾,类的数量少了,类就变大了,类变小了,类的数量多了,呵呵,这可能具体情况具体分析吧,让它们之间达到个平衡点,教程上一句话说的好:在不影响清晰度的情况下尽量的减少类。

         5是保持注释的数量最少,我刚刚看到这一点的时候,有点吃惊,因为我遇到的老师都鼓励我们有良好的注释习惯,而且是边写代码边加注释,而不是写完代码后统一再加注释,总之是强烈建议写注释的,因为这样便于阅读代码,而这里建议我们保持注释最少,理由是,当更新代码时维护代码时还要同时更新注释,因为那些注释同时也过期了,这回徒增工作量,解决办法是尽可能的使代码清晰。经可能的,想尽一切办法的。

         6是一致的代码风格,C# C++的代码风格好象和java的不太一样。有人喜欢习惯这样有人喜欢那样。

        7是避免switch.优先用if,然后再switch.

        8是public的,有足够的理由不是public的,呵呵/作者把最有争议性的放在了最后.

        9是追随Fower,这是个人名,写了本书叫Refactoring,因式分解呵呵,查了查chinpub,中文版叫《重构:改善既有代码的设计》,明天去逛逛书店。

引用作者的一句话

"

编写 Java 代码相当简单。编写优良的 Java 代码则是一门手艺。倾力成为一个手艺人。

"

 

   

2007-1-12 星期五

    继续作dwr的练习,做了个动态显示用户信息,最后因为一个相对路径问题郁闷了我半天,原来在用eclipse新建jsp页的时候它给自动加了个<base href="<%=basePath%>">,以至于我的图片一直显示不出来,找相对路径,想了好多法,最后发现原来症结在这,删了它,皆大欢喜,哈哈,图片读出来了,哈哈,是个小人儿鞠躬的小图片,一列小人在那鞠躬,哈哈,有成就感,要不早出来了,以为这么个小小的问题,耽误了那么多时间,还有,小郭的那个更简单的错误,找了半天,最后发现一个单词错了,display写成display了,好家伙,不仔细看,还真看不出来。

明天又休息了,租的房子该到期了,刚在跳蚤市场上转了转,有点胆怯,哈哈,怕掉进陷阱,呵呵,再有手头的资金也不宽裕,钱啊。

2007年1月12日星期五

2007-1-11 星期四

DWR,哈哈,又是一个框架,的确让开发者少写了很多代码,又是配置配置,哈哈,一路的东西,dwr的配置,首先引入dwr.jar这个包,还有两个用于生成日志的两个包,然后在web.xml中配置启动dwr的servlet,并且配置dwr.xml的路径,跟struts配置一样,在dwr.xml文件中配置要映射的类以及方法,然后启动服务器,在<webroot>/dwr中查看是否配置正确,在这个页面中dwr告诉我们每映射一个类,就要添加一个相应的js文件引用,之后在自己的js文件中调用映射的文件就可以了。

    今天注册中国移动的那个飞信,气死我了,说我验证码不正确,打客服,接电话的小姐真实嘴皮子利落,都不给我插嘴的机会,移动怎么培训的,个人性格问题,先头打得那个就比较老实,呵呵呵。

2007年1月11日星期四

2007-1-10 星期三

    今天做了两个ajax的简单小例子,领略到javascript查找错误的困难了,呵呵,真是想象不出那些大型网站的应用,那么多的javascript脚本代码,是怎么调试的呢,明天看看那个DWR,看看这能不能带来惊喜,呵呵呵,ajax确实能给用户带来极爽的用户体验,但是编码麻烦了许多,代码多了许多,体验了几个ajax应用的网站,google的在线office,Gmail,yahoo的email也是ajax的了。

    以为今天周四了呢,哈哈,过的真慢,有时候嫌过的快,有时候嫌过的慢,真难伺候,有人说我挺快乐的还,那语气好像我正常情况下应该是郁闷的,没错,我就是沉浸在那些代码里的时候,暂时忘掉暂时不去想那些只能叹气的事,所以不想出来,出来了发现现实还是现实,呵呵,我佛保佑,平平静静。

       看编程思想去。

写了这么多,回过头,也不知所云。

呵呵

快乐的秘诀

想快乐一点吗?美国加州大学心理学家桑雅‧柳柏莫斯基在几经研究之后,提出八点具体可行的做法:
心存感激:
拿一本「感恩簿」,将三至五件你目前心存感激的事项记下来。这些可以是俗事(养的牡丹花盛开了),可以是惊喜之事(小孩开始学走路了)。每周记录一次(例如,固定星期日晚间),保持鲜活,内容愈常更换愈好。

时时行善:
可分随机的(排队时,让赶时间的人排前面),有系统的(每周日固定拿晚餐给邻居那位老人)。对朋友或陌生人仁慈一点,会产生积极效果,让自己感觉很慷慨、很有能力,也会赢得别人笑容、赞许及仁慈回馈。这些都会让人感觉快乐。

品尝乐趣:
多注意那些能让人短暂快乐及惊喜之事,例如草莓的甜味、阳光的和煦。心理学家建议,不妨将快乐时光如照相一般「印存脑海中」,在痛苦时翻出来回味。

感谢贵人:
如果有人在你人生走到十字路时,提携或指导过你,要赶快向他答谢。越详尽越好,最好是亲自答谢。

学习谅解:
如果有人伤害你、误会你,就写封信给他表示原谅,也让自己怒气怨恨得以发泄。无法谅解他人会让自己积怨、心怀报复,谅解则会让你大步往前。

珍惜亲友:
对生活满意与否,其实与钱财、头衔、甚至健康关系不大。最大因素是人际关系的和谐。多花点时间及精力在朋友亲人身上。

照顾身体:
充足睡眠、运动、伸展四肢、笑口常开都可短时间内改善心情。常做这些动作会提升生活满意度。

因应难关:
人生不免有难。宗教信仰可助你度过。不过一些平凡无奇信条也可。例如「事情总会过去。这次也一样!」、「任何打不死我的事,会让我变得更坚强。」关键就在,你必须相信这些信条。


    不知道什么时候,也重新关注起这些来了,呵呵,我想回到从前...,我要回到从前,即便前面的路并不好走,那才是我自己,呵呵,好了不说了。

 

2007年1月10日星期三

2007-1-9 星期二

做了个应用ajax的小练习,最后部署看结果的时候出了莫名其妙的问题。

    引用js文件出错的问题

       将javaScript单独放在一个js文件里,执行没反应,把javaScript直接放在jsp页中正常。

js代码都是复制的,用得都是一样的,疯了都,让旁边几个人看了甚至老师也看不出问题,代码上没有任何问题,无奈在qq群里问,大伙给出了好多注意,也都不行,有人认为是文件路径问题,有人为使大小写问题,经检查都没错,真疯了,在网上搜,google翻了五页,看到一哥们的blog写类似的问题,正合我的症状,原来是编码的问题,要把js文件保存成和其他jsp文件保存成相同的编码,否则就不认,我晕,问题总算解决了,原来我的js文件为了不使中文变成乱码用EditPlus保存成UTF-8了,而我的jsp页用eclipse建的是ISO-8859-1编码。

       哈哈,问题解决了,甚感轻松。

昨天晚上看编程思想的类型检查,关于RTTI运行时类型检查的原理,在每个类编译成class的时候,就会产生一个特殊的对象,Class对象,被保存在.class文件中,这个Class对象来标识这个类,当要生成这个类的对象的时候,JVM虚拟机会查找这个类的Class对象是否存在,若不存在就查找这个类的.calss文件,并将其加载,看来这个Class对象就像这个类的一个标识,也可以从Class对象得知这个类的类型(当一个类被加载的时候,static代码块被执行,如果有,这让我理解了在jdbc中初始化数据源的时候,为什么要用Class.forName()来加载驱动程序类,可能是就是为了执行驱动程序中的静态语句块吧)

2007年1月9日星期二

2007-1-8 星期一

开始了一门新课,也是个新东西,ajax,这东西,刚开始,简单的接触,由javascript、xml实现的一种无刷新技术。

       Javascript是一种解释型脚本语言,所谓脚本语言,区别于编程语言,它不需要一个完成的程序文件的形式就能存在,只需要一组代码就能运行,这是跟编程语言的最大区别,编程语言必须有一个完整的程序文件。

       Javascript的内置对象,String、Math、Date、Array、Screen、

       浏览器内置对象window,navigator

       Window下有location\history\document

       Navigator主要提供一些浏览器信息。

今天不知怎么的了,老困,今天早点睡,呵呵!

 

2007年1月6日星期六

学习Spring的事务管理(三)

最后一种方式就是声明控制的事务处理了,这里面基本上都是在xml文件中配置,在代码中见不到任何有关事务的类型,实现了非侵入。其原理用到了Ioc对象反转控制和AOP,到现在我还没弄清楚Aop是怎么个玩意儿,哈哈,还得好好学。

在spring的配置文件中设置一个代理类对象,其中的属性包括,要代理类的接口,要代理的哪个类,事务的处理方式,这样在数据实现类中调用数据库的方法中就像没有用事务一样写代码,另外在控制器中调用这个处理方法的时候,以前是要通过Ioc获得一个数据实现类的对象,现在,这个实现类被代理的,我们只需得到这个代理类的对象,然后用这个代理类的对象调用相应的数据处理方法。

Xml配置文件中的部分配置:

<bean id="userDAOProxy"  class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">

    <property name="proxyInterfaces">

      <list>

        <value>springmvcwebapp.UserLoginInterface</value>

      </list>

    </property>

    <property name="transactionManager">

      <ref bean="transactionManager"/>

    </property>

    <property name="target">

      <ref bean="oneUserLoginImple"/>

    </property>

    <property name="transactionAttributes">

      <props>

        <prop key="doUpdateUserInfo*">PROPAGATION_REQUIRED</prop>

        <prop key="*">PROPAGATION_REQUIRED, readOnly</prop>

      </props>

    </property>

  </bean>

<bean id="dataSource"

      class="org.springframework.jdbc.datasource.DriverManagerDataSource">

      <property name="driverClassName">

        <value>com.microsoft.jdbc.sqlserver.SQLServerDriver</value>

      </property>

      <property name="url">

         <value>jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=WebStudyDB</value>

      </property>

      <property name="username">

        <value>sa</value>

      </property>

      <property name="password">

        <value>123456</value>

      </property>

    </bean>

<bean id="transactionManager"  class="org.springframework.jdbc.datasource.DataSourceTransactionManager">

   <property name="dataSource">

      <ref bean="dataSource"/>

    </property>

  </bean>

学习Spring的事务管理(二)

用代码控制实现事物管理的另一种方式,就是通过使用TransactionTemplate模板类,TransactionTemplate封装了事务管理的功能,包括异常时的事务回滚,以及操作成功后的事务提交。和JdbcTemplate一样,它使得我们无需在琐碎的try/catch/finally代码中徘徊---也就是为我们省去了部分事务提交、回滚代码。

将上面的用户信息插入方法修改成下面这样:

TransactionTemplate类的构造器需要一个TransactionCallback接口类型的参数,而抽象类TransactionCallbackWithoutResult实现了TransactionCallback接口,抽象类TransactionCallbackWithoutResult中有一个()方法,该方法以 为参数。所以就有了下面的用内部类的实现方式。

public boolean doUpdateUserInfo(UserInfoVO oneUserInfo)

    {

        //定义两个sql插入语句

        String sql = "update userinfo set userPassword=? where userName=?";

        String sql2 = "update userinfo1 set userPassword=? where userName=?";

 

    TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);

    transactionTemplate.execute(new TransactionCallbackWithoutResult()

               {

                  public void doInTransactionWithoutResult(TransactionStatus status)

                  {

                     this.jdbcTemplate.update(sql, new Object[]

                                     {oneUserInfo.getUserName(),

                                     oneUserInfo.getUserPassword()});

                      this.jdbcTemplate.update(sql2, new Object[]

                                     {oneUserInfo.getUserName(),

                                     oneUserInfo.getUserPassword()});

                  }

              });

 

       return true;

    }

这种方式,代码量少,少了try/catch/finally语句,全部被封装在了TransactionTemplate类里面,以内部类方式实现可能降低了代码的可读性。

学习Spring的事务管理(一)

哈哈,有人在我的blog上留言说也在学习spring,能不能传个例子共同学习一下spring的事物管理,我也是学了个一知半解,刚刚研究了研究。将其中的一点自己的理解写下来,共同学习。

Spring的事物管理有两种,一种是代码控制事物,一种是声明控制实现事物管理(也就是xml配置),咱先来说用代码控制实现事物管理,这种方式又分为两类,一种是实现PlatformTransactionManager接口的方法

查了一下帮助文档,实现了PlatformTransactionManager接口的有好多类,下面的例子代码是用的其中的DataSourceTransactionManager.

这是模拟用户注册的一个例子,下面的类实现于自定义接口UserLoginInterface(spring提倡的面向)该类里面定义了两个属性,一个是Spring的jdbc模版类,一个是事务管理器,并都提供了set方法,这两个对象将在Ioc中自动初始化加载。其中有一个叫UserInfoVO的值对象类,用来传递用户注册信息

//用代码控制实现事务管理其中的实现PlatformTransactionManager接口的方法

import java.util.*;

import org.springframework.context.*;

import org.springframework.jdbc.core.*;

import org.springframework.transaction.*;

import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import org.springframework.transaction.support.DefaultTransactionDefinition;

public class UserLoginImple implements UserLoginInterface

{

       //Spring jdbc模版类

    private JdbcTemplate jdbcTemplate;  

    //事务管理器 PlatformTransactionManager是一个接口

    private PlatformTransactionManager transactionManager


 

    //jdbc模版类对象的set方法

    public void setJdbcTemplate(JdbcTemplate jdbcTemplate)

    {

        this.jdbcTemplate = jdbcTemplate;

    }

   

    //事务管理器的set方法

    public void setTransactionManager(PlatformTransactionManager transactionManager)

    {

        this.transactionManager = transactionManager;

    }

   

    //插入用户信息的方法

    public boolean doUpdateUserInfo(UserInfoVO oneUserInfo)

    {

    //定义两个sql插入语句

        String sql = "update userinfo set userPassword=? where userName=?";

        String sql2 = "update userinfo1 set userPassword=? where userName=?";

 

        DefaultTransactionDefinition dtf = new                                DefaultTransactionDefinition();//事务定义

        TransactionStatus status = this.transactionManager.getTransaction(dtf);//事务状态

        try

        {

            this.jdbcTemplate.update(sql, new Object[]

                                     {oneUserInfo.getUserName(),

                                     oneUserInfo.getUserPassword()});

            this.jdbcTemplate.update(sql2, new Object[]

                                     {oneUserInfo.getUserName(),

                                     oneUserInfo.getUserPassword()});

            this.transactionManager.commit(status);

        }

        catch(Exception ex)

        {

            this.transactionManager.rollback(status);

            return false;

        }

    

       return true;

    }

 

}

关键看加粗的部分,首先定义一个事务,然后以这个事务为参数通过事务管理器创建一个事务状态,开始执行sql代码,最后事务管理器提交事务状态,完成。其间如果出现异常,事务管理器回滚事务状态。

我理解着,这里面用了设计模式中的一个叫Command命令的模式,首先定义一个执行者(事务对象),然后赋予执行者使命(事务状态),命令执行者执行其被赋予的使命,如果失败,命令执行者撤销执行的使命。

不知道理解的对不对,呵呵。

2007-1-5 星期五

看编程思想的异常处理这一章,Throwable是所有异常的基类,Error和Exception分别继承了Throwable,Error是虚拟机运行报告错误,一般我们不用关心,Exception 是所有编程异常的基类,它又分为被检查异常和不检查异常,不检查异常是所有继承于RuntimeException的异常,这些异常编译器在编译时不进行检查,也就是不用有异常声明,遇到错误会自动抛出,被检查异常时除RuntimeException的异常,必须有异常声明,编程思想里面的说法好像大家对强制异常声明不是很赞同,理由没能理解深刻,都是大师们说的话,哈哈。咱还不够那个级别。

    其中有这样一个问题,就是一个方法有一个异常必须作处理,可又不知道该如何处理,这里有个办法就是在catch里面将其转换成运行时异常RuntimeException,这样就不用异常声明了。

 

    哈哈,刚刚看了异常处理这一章,今天就用上了,编好了一段hibernate的代码,测试就是没有结果输出,并且没有异常出现,真是让人恼火,找阿找阿找,最后发现在初始化SessionFactory的静态语句块中虽然用了try…catch语句但是在catch里面只是将异常抛出,而在跳用这段代码的时候,并没有获取这个异常,所以造成异常丢失。

 

另外,错误的原因是虚拟机找不到一个属性的get方法,换了个名字就好了,注意命名规则,一个小写字母然后接一个大写字母就不行,像这样sLive。注意/。

 

在执行Hibernate程序中出现下面错误

Could not read mappings from resource: DepartmentTwo.hbm.xml

检查也没错阿,找不到的文件老老实实在那呆着了阿,仔细检查异常信息,发现下面还有这么一句。

org.hibernate.DuplicateMappingException: Duplicate class/entity mapping com.hwebmapping.pojo.Department

原来一个持久类不能多次被映射,所以才出现这样的异常,原因是在做练习的时候为了省事,将原来做好的持久类想接着用一下,没想到Hibernate有意见,哈哈。

 

如果在调用session.save()方法的时候如果传入的对象所的类没有被映射,就会出现线面的异常信息。

uninitialized proxy passed to save()

未初始化的代理

 

不错,今天收获不小,哈哈。

2007年1月5日星期五

2007-1-4 星期四

转眼间跨到07年了,呵呵。

今天学习了Hibernate的List,Set,Map映射,它们都是应用类之间的内嵌方式,List和Set都是按数值索引,Set不能有重复值,List必须有一个Index字段,和主健形成联合主健,Map是以键值对形式的集合,也不允许重复,用那种方式取决于数据库表如何设计,和一对多不同的是,一对多采用关联方式,具体体现在持久类里面倒没看出什么差别,在配置文件上有差别,在实际应用中体会吧。

开始有就业的压力了。