隨筆-10  評(píng)論-22  文章-1  trackbacks-0
            2009年5月14日
          Annotation是JavaSE5開(kāi)始引入的,在Java的世界已是大行其道,各大開(kāi)源框架Hibernate、Spring等都對(duì)它無(wú)縫集成,足見(jiàn)其份量了。。
          其實(shí)很早就出現(xiàn)在程序員的視野,只是關(guān)注的比較少:@Override、@SuppressWarnings("unchecked"),開(kāi)始主要覺(jué)得沒(méi)什么用處,后來(lái)公司的框架用到它,感覺(jué)還不錯(cuò)。。于是來(lái)一記:

          在網(wǎng)上搜Annotation的學(xué)習(xí)資料不是很多,還是用的人不多,比較經(jīng)典的入門(mén)就是這個(gè):實(shí)戰(zhàn)篇:設(shè)計(jì)自己的Annotation,很清楚,通俗易懂,這里我就不贅述了。然而僅僅是弄懂它是怎么回事,具體還是沒(méi)什么用處,這也是大多數(shù)開(kāi)發(fā)人員的感覺(jué)。

          在現(xiàn)在的公司的經(jīng)歷兩次框架升級(jí),第一次沒(méi)有用到Annotation,xml配置文件大行其道:Action跳轉(zhuǎn)、Ibatis sqlmapper、Form表單(我們的表單都是從后臺(tái)生成的),整個(gè)項(xiàng)目xml眼花繚亂,每個(gè)模塊都有自己專(zhuān)屬的配置文件,然后集中到一起處理,而我們最痛苦的莫過(guò)于寫(xiě)那大量重復(fù)的配置文件。

          后來(lái)公司接了個(gè)ERP的單子,技術(shù)總監(jiān)馬上意識(shí)到框架該升級(jí)了,他技術(shù)很牛,我們公司的框架就是他一人寫(xiě)的,兩周之后,新框架出爐,xml只保留三分之一:Action跳轉(zhuǎn)、Form表單都不再使用xml配置,而是Annotation橫空出世,給我的感覺(jué):它就像一個(gè)救世主,讓我們的框架重生,它就是這次升級(jí)的最大亮點(diǎn),只有sqlmapper依然保留,這無(wú)可厚非,因?yàn)樗臼莍batis封裝的,Action控制器既不是Struts1,Struts2,也不是Webwork,是總監(jiān)自己封裝的Servlet,F(xiàn)orm表單都由后臺(tái)生成js組件拋到前端,通過(guò)反編譯看到源碼,其實(shí)還是很基礎(chǔ)的,貼些代碼上來(lái)看下吧:

          1.Action請(qǐng)求部分:
              /**
               * 顯示新增頁(yè)面
               * author YuWenLin
               * date 2010-5-13 上午10:31:57
               * 
          @param data
               
          */
              @Action(
          "/add.shtml")
              @Permission(
          "client.ContractType.add")
              
          public void add(ActionData data){
                  FormBuilder builder 
          = data.getService(FormBuilder.class);
                  builder.append(Type.
          class);
                  builder.setAction(
          "client/contract/type/add.do");
                  data.put(
          "script", builder);
                  
          //向頁(yè)面拋出cookie提示信息
                  MessageUtil.putMessage(data);
                  data.setResulter(
          "template");
                  data.setPath(
          "client/contract/type/type.shtml");
              }
          可能大家看得不太明白(每個(gè)公司都有自己框架),沒(méi)有關(guān)系,就兩句:
          @Action("/add.shtml")
          它就是負(fù)責(zé)請(qǐng)求顯示新增的頁(yè)面,就這一句,不需要像我們以前的action.xml(類(lèi)似Struts2的跳轉(zhuǎn)),干凈利索吧,當(dāng)然底層后臺(tái)有處理,但是公共的,不需我們管,至于
          @Permission("client.ContractType.add")
          就是用來(lái)處理權(quán)限管理的,也是Annotation的使用,就這一句。就權(quán)限管理,后面我也會(huì)記述。。。

          2.再來(lái)看看@Action底層的定義:
          package org.plugbase.action;

          import java.lang.annotation.Annotation;

          public interface Action
              
          extends Annotation
          {

              
          public abstract String value();
          }
          說(shuō)明下:extends Annotation跟 @interface是一樣的效果,只不過(guò)前者手動(dòng)extends,后者自動(dòng)的。
          怎么樣,很基礎(chǔ)吧,跟jdk源碼是一樣的。。。

          3.JavaBean生成表單:
              @Widget(value="TextBox")
              @Valider({
          "notempty","len(2,8)"})
              
          public void setName(String name) {
                  
          this.name = name;
              }
          給setter方法加Annotation,@Widget是組件,@Valider是驗(yàn)證
          意思就是給name字段生成TextBox組件,并做驗(yàn)證處理,后臺(tái)有相應(yīng)的公共js組件,驗(yàn)證控件庫(kù)調(diào)用,我們所有的表單組件都是這樣生成的,說(shuō)實(shí)話,這樣生成一個(gè)頁(yè)面真有點(diǎn)繁鎖,既要寫(xiě)js,又要寫(xiě)后臺(tái),前端還要配,還真是有技術(shù)含量,呵呵。。。但是它保證一致性,所有表單組件,驗(yàn)證控件,如TextBox我們只有一套,所有人都去調(diào)用這一套,不得再重造,因?yàn)樗强蚣堋!!?br />
          4.@Widget底層定義:
          import java.lang.annotation.Annotation;

          public interface Widget
              
          extends Annotation
          {

              
          public abstract String value();

              
          public abstract String defaultValue();

              
          public abstract String dataType();

              
          public abstract String dataSource();
          }
          @Valider類(lèi)似,當(dāng)然這些都只是定義、聲明,具體怎么用,這里就不貼了,畢竟是人家東西嘛

          怎么樣,看到這些,似乎覺(jué)得Annotation開(kāi)始起作用了,其實(shí)我一直覺(jué)得,Annotation就是為xml所生,因?yàn)樗鼈儌z是死對(duì)頭,不管單一地用誰(shuí),都有缺陷,
          只有結(jié)合才是完善,正所謂,沒(méi)有最好,只有更好,合理就行。

          在這里我可能沒(méi)有貼出什么@Annotation技術(shù)含量的東西,但是我想要表達(dá)的是一種思想,一種框架的思想,并不是什么地方都能用到Annotation,一般的中小型項(xiàng)目根本沒(méi)必要用它,因?yàn)閤ml就搞定,所以用在需要用的地方,將它的能量發(fā)揮到最大。。。

          以上僅為一家之言,歡迎拍磚。。。

          posted @ 2010-08-10 16:47 獨(dú)孤行 閱讀(1714) | 評(píng)論 (1)編輯 收藏
               摘要: 在項(xiàng)目中使用ibatis有一段時(shí)間了,之前一直用jdbc、hibernate。自我感覺(jué)ibatis是介于jdbc和hibernate之間的非常實(shí)用的輕量級(jí)框架,相信用過(guò)的人都有同感吧。對(duì)搞java的來(lái)說(shuō),上手是非常快的,只要你具備sql基礎(chǔ),再加一點(diǎn)ORM的思想,夏昕的《ibatis開(kāi)發(fā)指南》是不錯(cuò)的選擇。 今天項(xiàng)目搞完了,我就把所學(xué)的,以及在項(xiàng)目中用到拿來(lái)貼一番,也是對(duì)我個(gè)人技術(shù)的總結(jié)吧,怎樣...  閱讀全文
          posted @ 2010-04-01 11:35 獨(dú)孤行 閱讀(3355) | 評(píng)論 (0)編輯 收藏
          thickbox是jQuery的一個(gè)插件,其作用是彈出對(duì)話框、網(wǎng)頁(yè)框,使用戶(hù)體驗(yàn)度更加愉悅,下面就來(lái)簡(jiǎn)單介紹它的幾種用法。
          聲明一下:這只是個(gè)人的總結(jié)記載而已。
          準(zhǔn)備工作:你需要三個(gè)文件:thickbox.js、thickbox.css、jquery.js,網(wǎng)上到處可下
          具體使用:
          第一步:將這三個(gè)文件引入到你要使用thickbox的頁(yè)面
          <script type="text/javascript" src="jquery.js"></script> 
              
          <script type="text/javascript" src="thickbox.js"></script>
              
          <link rel="stylesheet" href="thickbox.css" type="text/css" />
          第二步:一般簡(jiǎn)單使用就是給<a>標(biāo)簽和Button添加樣式:class=thickbox
          還有就是通過(guò)thickbox函數(shù)調(diào)用:如tb_init()、tb_show();見(jiàn)下文。
          幾種不同用法:
          1.點(diǎn)擊顯示圖片:
           <a href="001.jpg" class="thickbox"><img src="001.jpg"/></a>
          ok,就這樣搞定
          2.點(diǎn)擊按鈕或鏈接:
          <input alt="#TB_inline?height=300&width=400&inlineId=div1" title="shawnliu" class="thickbox" type="button" value="Show" />   
             
          <a href="#TB_inline?height=155&width=300&inlineId=div2&modal=true" class="thickbox">Show hidden modal content.</a>
             
             
          <div id="div1" style="display:none">
             
          <P>
               這是一個(gè)非模式對(duì)話框。
             
          </P>
             
          </div>

             
          <div id="div2" style="display:none">
             
          <P>
               這是一個(gè)模式對(duì)話框。
               
          <p style="TEXT-ALIGN: center"><INPUT id="Login" onclick="tb_remove()" type="submit" value="  Ok  " /></p>
             
          </P>
             
          </div>
          說(shuō)明:給你要使用thickbox的<a>或button添加"#TB_inline?height=300&width=400&",#TB_inline是thickbox固定用法,height和width是顯示彈出對(duì)話框的大小參數(shù),inlineId是你要顯示的標(biāo)簽或組件,modal是模式與非模式的選擇,當(dāng)然你還可以接很多你自定義的參數(shù)
          3.一般在項(xiàng)目中用得比較多的就是加載form的頁(yè)面,如添加,編輯在同一個(gè)list列表頁(yè)面,這時(shí)我們就可以將添加和編輯都做成thickbox形式,如下圖:

          怎樣做呢一樣的,給添加鏈接加thickbox樣式:
          <a href="add.shtml?width=300&height=250" class="thickbox">新增</a>
          前提是你得將要顯示的頁(yè)面(add.shtml)做好,然后指定你要顯示的大小
          編輯同樣是一樣:先將原信息提取出來(lái),再讓用戶(hù)修改:

          代碼也一樣:
          <a href="edit.shtml?width=300&height=250&nid=item.nid" class="thickbox">編輯</a>
          4.能自己定位到需要用thickbox的元素,不使用樣式,可以用函數(shù),如:
          <div id="PicList">
          <a href="Pic01.jpg"><img src="Pic01s.jpg" border="0"/></a>
          <a href="Pic02.jpg"><img src="Pic01s.jpg" border="0"/></a>
          </div>

          $(function() {
          tb_init(
          "#PicList a[img]");});
          5.通過(guò)ajax加載的頁(yè)面,thickbox樣式會(huì)失效,解決辦法:
          只要在AJAX載入HTML并更新到頁(yè)面后執(zhí)行下以下代碼:
          tb_init('.thickbox');
          6.自定義函數(shù)調(diào)用:
          如點(diǎn)擊縮圖,要顯示大圖,縮略圖URL只不過(guò)在大圖URL的后綴前加了s:
          <div id="PicList">
          <img src="Pic01s.jpg" border="0"/>
          <img src="Pic01s.jpg" border="0"/>
          </div>

          $(function() {
          $(
          "#PicList img").click(function() {
          tb_show(
          "",this.src.substring(0,this.src.length-5)+'.jpg',false);
          });});
          另外,如果想用其它事件,還可以將click改成你想觸發(fā)thickbox的事件。
          下班勒,大概記錄到這,以后再加吧。。。


          posted @ 2010-03-26 17:47 獨(dú)孤行 閱讀(4645) | 評(píng)論 (2)編輯 收藏

          在域模型(實(shí)體域)中,關(guān)聯(lián)關(guān)系是類(lèi)與類(lèi)之間最普遍的關(guān)系。根據(jù)UML語(yǔ)言,關(guān)系是有方向的。下面以客戶(hù)(Customer)和訂單(Order)的關(guān)系為例,闡述一下ORM的中的一對(duì)多映射:
          我們知道,在關(guān)系數(shù)據(jù)庫(kù)中,只存在外鍵參照關(guān)系,而且總是由“many”方參照“one“方。
          1.建立多對(duì)一單向關(guān)聯(lián)——Order(many)--->Customer(one):
          -------------------------------Order.java--------------------------------

          pack mypack;
          import java.io.Serializable;
          public class Order implements Serializable{
             
          private int id;
             
          private String orderNumber;
             
          private Customer customer;
             
             
          //構(gòu)造方法及set方法get方法
             
          }
          在以上代碼中customer屬性要使用<many-to-one>來(lái)映射:
          多對(duì)一單向關(guān)聯(lián)(many方)
          <many-to-one>
              name 
          = "customer"   --待映射的持久化類(lèi)屬性名
              column 
          = "customer_Id"  --數(shù)據(jù)庫(kù)外鍵字段
              
          class = "mypack.Customer"  --持久化類(lèi)
              not
          -null = "true"/>
          a.  <many-to-one>的not-null屬性 
          not-null屬性會(huì)影響Hiberntae的運(yùn)行時(shí)行為,Hibernate在保存Order對(duì)象時(shí),會(huì)先檢查它的customer屬性是否為null:
          若為null:在執(zhí)行session.save(Order)時(shí)會(huì)拋出PropertyValueException異常;
          原因很簡(jiǎn)單:既然Customer為null,那么對(duì)應(yīng)的外鍵Customer_Id也為null,試問(wèn)外鍵都沒(méi)有,Order表的數(shù)據(jù)能插得進(jìn)去嗎
          若將not-null 屬性設(shè)為false:表示外鍵引用可以為null,試想一下,數(shù)據(jù)庫(kù)數(shù)據(jù)可以插進(jìn)去嗎?
          我們來(lái)看:在執(zhí)行session.save(Order)時(shí),發(fā)出了sql語(yǔ)句:insert into......
          但是當(dāng)Hibernate自動(dòng)清理(flush)緩存時(shí),拋出新的異常:TransientObjectException
          所謂清理是提交事務(wù)或手動(dòng)Flush,將session與數(shù)據(jù)庫(kù)保持同步,很顯然不可能同步嘛,Order對(duì)象雖然持久化,但Customer沒(méi)有.
              注:是否應(yīng)該把<many-to-one>的not-null屬性設(shè)為true,這根據(jù)實(shí)際業(yè)務(wù)而定。通常,訂單總是由客戶(hù)自己發(fā)出,因此建議設(shè)為true.
          b.  級(jí)聯(lián)保存與更新
          默認(rèn)情況下,Hibernate持久化一個(gè)對(duì)象,不會(huì)自動(dòng)持久化所關(guān)聯(lián)的其它臨時(shí)對(duì)象,因此會(huì)有TransientObjectException,
          想它關(guān)聯(lián)也可以,<many-to-one>中加個(gè)屬性cascade="save-update"即可.

          2.建立一對(duì)多關(guān)聯(lián)——Customer(one)--->Order(many):
          -----------------------------Customer.java-------------------------------
          package mypack;
          import 
          public calss Customer implements Serlizliab;e{
              
          private int id;
              
          private String name;
              
          private Set orders = new HsahSet();

              
          //構(gòu)造方法及set方法get方法
          }
          一對(duì)多關(guān)聯(lián)(one方)
          <set 
                name 
          = "orders"  --持久化對(duì)象的屬性
                cascade 
          = "save-update" --級(jí)聯(lián)操作
                
          <key cloumn = "customer_Id"/> --外鍵
                
          <one-to-many class = "mypack.Order"/> --持久化類(lèi)
          </set>
          a.  <set>元素的inverse屬性
            在映射一對(duì)多的雙向關(guān)聯(lián)時(shí),應(yīng)該在“one”方把inverse屬性設(shè)為true,這樣可提高應(yīng)用性能。
                              inverse:控制反轉(zhuǎn),為true表示反轉(zhuǎn),由它方負(fù)責(zé);反之,不反轉(zhuǎn),自己負(fù)責(zé);
                              如果不設(shè),one和many兩方都要負(fù)責(zé)控制,因此,會(huì)引發(fā)重復(fù)的sql語(yǔ)句以及重復(fù)添加數(shù)據(jù),
                  在建立兩個(gè)象的雙向關(guān)系時(shí),應(yīng)該同時(shí)修改關(guān)聯(lián)兩端的對(duì)象屬性:
                              customer.getOrders().add(order);
                              order.setCustomer(customer);

                  這樣做可提高業(yè)務(wù)邏輯的獨(dú)立性,使業(yè)務(wù)邏輯的程序代碼不受Hibernate實(shí)現(xiàn)的影響。同理解除雙向關(guān)系也一樣。
          b.  級(jí)聯(lián)刪除(從數(shù)據(jù)庫(kù)刪除相關(guān)表記錄)
                   當(dāng)刪除Customer對(duì)象時(shí),及聯(lián)刪除Order對(duì)象.只需將cascad屬性設(shè)為delete即可.
                    注:刪除后的對(duì)象,依然存在于內(nèi)存中,只不過(guò)由持久化態(tài)變?yōu)榕R時(shí)態(tài).
          c.  父子關(guān)系(邏輯刪除,只是解除了關(guān)聯(lián)關(guān)系)
                   自動(dòng)刪除不再和Customer對(duì)象關(guān)聯(lián)的Order對(duì)象.只需將cascade屬性設(shè)為delete-orphan.
                               customer.getOrders().remove(order);
                               order.setCustomer(null);
                    注:當(dāng)關(guān)聯(lián)雙方都存在父子關(guān)系,就可以把父方的cascade屬性設(shè)為delete-orphan,所謂父子關(guān)系,是由父方來(lái)控制子方的生命周期.
                               
                 


          posted @ 2009-10-16 00:29 獨(dú)孤行 閱讀(3347) | 評(píng)論 (2)編輯 收藏

          My97DatePicker是一款非常靈活好用的日期控件,在本次項(xiàng)目中我使用它暴露了很多問(wèn)題:

          首先來(lái)說(shuō)使用步驟:

          1.在My97DatePicker主頁(yè)下載控件,

          目前的版本是:4.2 正式版 發(fā)布于2008-12-03

          http://www.my97.net/dp/down.asp

          2.將文件解壓包(一個(gè)文件都不要?jiǎng)h除)拷貝到classpath/webroot下

          3.直接使用<script />引入:

          <script type="text/javascript" defer="defer" src="<%=request.getContextPath() %>/My97DatePicker/WdatePicker.js"></script>

          4.在<input type="text"/>中調(diào)用:

          <input type="text" name="time" onfocus="WdatePicker()">

          其次來(lái)說(shuō)一下我在使用中碰到的問(wèn)題:

          1.IE中 無(wú)法打開(kāi)internet站點(diǎn) 。。。。。已終止操作

          這個(gè)問(wèn)題搞了好半天,網(wǎng)上到處查,最后才在csdn上看到解決辦法:

          a.如果頁(yè)面有<base/>標(biāo)簽的:則要在第3步j(luò)s引入后添加<base target="_self" />;

          b.在<script/>中添加屬性defer="defer"; //就是這具屬性救了我

          2.在步驟4中調(diào)用了,結(jié)果不出來(lái):

          開(kāi)始以為是stuts1.2 標(biāo)簽的原因,結(jié)果不是,后來(lái)反復(fù)測(cè)試,才搞定了

          其實(shí)調(diào)用的時(shí)候有很多方法,然而有的方法不一定出得來(lái),所以要反復(fù)測(cè)試

          這是My97DatePicker的主頁(yè):http://www.my97.net

          里面有控件下載,使用演示,問(wèn)題解決等

          posted @ 2009-05-14 00:28 獨(dú)孤行 閱讀(10475) | 評(píng)論 (9)編輯 收藏
          主站蜘蛛池模板: 太康县| 邹平县| 华蓥市| 临武县| 札达县| 温泉县| 昌平区| 公主岭市| 桐庐县| 明水县| 甘南县| 平泉县| 会宁县| 晋宁县| 济源市| 斗六市| 湛江市| 砀山县| 拉孜县| 京山县| 隆子县| 泗水县| 呼图壁县| 盐津县| 奇台县| 闵行区| 西峡县| 金秀| 崇文区| 尤溪县| 湖北省| 南充市| 简阳市| 巴林右旗| 和平县| 醴陵市| 安福县| 红安县| 栖霞市| 瑞昌市| 静安区|