ZeroBlue

          留出時間,讓自己微笑。
          posts - 6, comments - 12, trackbacks - 0, articles - 0
             :: 首頁 ::  :: 聯(lián)系 ::  :: 管理

          2006年8月29日

          數(shù)據(jù)庫鎖的概念,類型,排鎖語句:
          鎖是數(shù)據(jù)庫中的一個非常重要的概念,它主要用于多用戶環(huán)境下保證數(shù)據(jù)庫完整性和一致性。 我們知道,多個用戶能夠同時操縱同一個數(shù)據(jù)庫中的數(shù)據(jù),會發(fā)生數(shù)據(jù)不一致現(xiàn)象。即如果沒有鎖定且多個用戶同時訪問一個數(shù)據(jù)庫,則當(dāng)他們的事務(wù)同時使用相同的數(shù)據(jù)時可能會發(fā)生問題。這些問題包括:丟失更新、臟讀、不可重復(fù)讀和幻覺讀。

          找出表A中M字段大于500,Y(日期)早于當(dāng)前數(shù)據(jù)庫一天,X字段取值不重復(fù)的記錄:
          select * from A where x in
          (select x from A group by x having count(x)=1)
          and m >500 and y < getdate()-1;

          從表A中統(tǒng)計X字段的不同取值數(shù)并只把記錄數(shù)多于5的找出:
          select * from A where x in (select x from A group by x having count(x)>5)

          設(shè)表B結(jié)構(gòu)與表A相同,將B中n字段值大于500的記錄插入A
          insert into?A select * from?B where n>500


          對表A,建立和刪除M,N字段聯(lián)合唯一索引:
          CREATE UNIQUE? INDEX myclumn_index ON A(x,y)
          DROP INDEX A.myclumn_index?
          ?注意:當(dāng)你的內(nèi)存容量或硬盤空間不足時,也許你不想給一個表增加索引。對于包含索引的數(shù)據(jù)庫,SQL Sever需要一個可觀的額外空間。例如,要建立一個聚簇索引,需要大約1.2倍于數(shù)據(jù)大小的空間。要看一看一個表的索引在數(shù)據(jù)庫中所占的空間大小,你可以使用系統(tǒng)存儲過程sp_spaceused,對象名指定為被索引的表名。

          posted @ 2007-03-01 20:32 zeroblue 閱讀(261) | 評論 (0)編輯 收藏

          節(jié)選自《程序員》2006年第9期《茶杯里的風(fēng)暴》一文,作者:金尹。如下:
            P2P網(wǎng)絡(luò)向傳統(tǒng)應(yīng)用的滲透,將對Ruby、Python這些新興的編程語言提出巨大的挑戰(zhàn)。首先在P2P網(wǎng)絡(luò)中單個運算節(jié)點上的程序并不需要像Web服務(wù)那樣保持24×7穩(wěn)定,也不需要支持大容量并發(fā)計算。Ruby、Python這些語言的快速開發(fā)優(yōu)勢得以顯著地體現(xiàn),他們將是未來桌面的主力開發(fā)語言。其次,為了共享P2P覆蓋網(wǎng)上分散的計算資源,分布式計算所需的容錯能力、分布式存儲格式、算法、支持庫乃至語言級別的支持都納入到新語言的規(guī)劃當(dāng)中;最后,到我們的計算機上出現(xiàn)越來越多的客戶端小程序時,為每一個程序開啟一個龐大的虛擬機將是一個非常糟糕的辦法,那么在共享虛擬機上,我們?nèi)绾翁峁Χ嗪说闹С郑慷@些多核的虛擬機特性又如何從語言層面、支持庫層面展現(xiàn)給開發(fā)者,同時又不失去語言的簡潔特性?這些都是我們不能回避的話題!
            AJAX、Ruby竄紅并非是一場茶杯里的風(fēng)暴,而是巨大冰山的一角。無論是服務(wù)端還是客戶端,并行/分布式計算的巨大需求都向編程語言提出嚴峻的挑戰(zhàn)。然而目前大多數(shù)的編程語言設(shè)計之初并不關(guān)注并行/分布式計算,這些語言中的許多經(jīng)典特性(比如OO)在并行/分布式計算上變成了捆住程序員的鎖鏈。工欲善其事,必先利其器。在并行/分布式計算領(lǐng)域中我們必須拋棄原有的經(jīng)驗、習(xí)慣、以一種新的思維面對新的世界。

            再回過頭來看看下面這篇文章:
          ?????????http://www.cnblogs.com/sharenet/archive/2006/05/18/403517.aspx

          posted @ 2006-09-01 14:49 zeroblue 閱讀(1607) | 評論 (7)編輯 收藏

          Step 1:配置web.xml
          <?xml?version="1.0"?encoding="UTF-8"?>
          <web-app?version="2.4"?xmlns="http://java.sun.com/xml/ns/j2ee"
          ????xmlns:xsi
          ="http://www.w3.org/2001/XMLSchema-instance"
          ????xsi:schemaLocation
          ="http://java.sun.com/xml/ns/j2ee?
          ????http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
          >

          ????
          <display-name>springapp</display-name>
          ????????
          ????
          <servlet>
          ????????
          <servlet-name>springMVC</servlet-name>
          ????????
          <servlet-class>
          ????????????org.springframework.web.servlet.DispatcherServlet
          ????????
          </servlet-class>
          ????????
          <load-on-startup>1</load-on-startup>
          ????
          </servlet>

          ????
          <servlet-mapping>
          ????????
          <servlet-name>springMVC</servlet-name>
          ????????
          <url-pattern>/page/*</url-pattern>
          ????
          </servlet-mapping>

          </web-app>
          servlet-mapping定義所有以/page/開頭的url請求都會被spring 的DispatcherServlet處理轉(zhuǎn)發(fā)。默認情況下DispatcherServlet會讀取<servlet-name>-servlet.xml文件的配置信息初始化,該文件中urlMapping的定義決定當(dāng)前請求轉(zhuǎn)發(fā)給哪個controller來處理。

          Step2:定義/WEB-INF/springMVC-servlet.xml
          ?
          <?xml?version="1.0"?encoding="UTF-8"?>
          <!DOCTYPE?beans?PUBLIC?"-//SPRING//DTD?BEAN//EN"?"http://www.springframework.org/dtd/spring-beans.dtd">

          <beans>
          ????
          <!--?方法名解析器?-->
          ????
          <bean?id="InternalPathMethodNameResolver"
          ????????class
          ="org.springframework.web.servlet.mvc.multiaction.InternalPathMethodNameResolver"?/>
          ????????
          ????
          <!--?視圖解析器?-->
          ????
          <bean?id="viewResolver"
          ????????class
          ="org.springframework.web.servlet.view.InternalResourceViewResolver">
          ????????
          <property?name="viewClass">
          ????????????
          <value>org.springframework.web.servlet.view.JstlView</value>
          ????????
          </property>
          ????
          </bean>
          ????
          ????
          <bean?id="controller"?class="com.controller.IndexController">
          ????????
          <property?name="methodNameResolver">
          ????????????
          <ref?bean="InternalPathMethodNameResolver"?/>
          ????????
          </property>
          ????
          </bean>

          ????
          <bean?id="urlMapping"
          ????????class
          ="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
          ????????
          <property?name="mappings">
          ????????????
          <props>
          ????????????????
          <prop?key="/controller/*">controller</prop>
          ????????????
          </props>
          ????????
          </property>
          ????
          </bean>
          </beans>
          urlMapping定義/controller/開頭的url請求由名字為controller的控制器來處理,因為是多動作處理器,所以要定義MethodNameResolver來告訴springMVC應(yīng)該調(diào)用controller的哪個方法,這里用的是InternalPathMethodNameResolver,該方法名解釋器會把整個URL中最后一個"/"和最后一個"."之間的部分作為要調(diào)用的方法名

          Step3:定義controller類并繼承MultiActionController?
          package?com.controller;

          import?java.io.IOException;
          import?java.util.HashMap;
          import?java.util.Map;

          import?javax.servlet.ServletException;
          import?javax.servlet.http.HttpServletRequest;
          import?javax.servlet.http.HttpServletResponse;

          import?org.springframework.web.servlet.ModelAndView;
          import?org.springframework.web.servlet.mvc.multiaction.MultiActionController;

          public?class?IndexController?extends?MultiActionController?{
          ????
          ????
          public?ModelAndView?method1(HttpServletRequest?request,
          ????????????HttpServletResponse?respnose)?
          throws?ServletException,?IOException?{
          ????????Map?model?
          =?new?HashMap();
          ????????model.put(
          "message",?"你調(diào)用的是方法1");
          ????????
          return?new?ModelAndView("/index.jsp",?"model",?model);
          ????}

          ????
          ????
          public?ModelAndView?method2(HttpServletRequest?request,
          ????????????HttpServletResponse?respnose)?
          throws?ServletException,?IOException?{
          ????????Map?model?
          =?new?HashMap();
          ????????model.put(
          "message",?"你調(diào)用的是方法2");
          ????????
          return?new?ModelAndView("/index.jsp",?"model",?model);
          ????}

          }


          通過配置文件,訪問上面這個controller中某個方法的url即為:localhost:8080/page/controller/方法名


          Step4:/index.jsp
          <%@?page?language="java"?pageEncoding="UTF-8"%>
          <%@?taglib?prefix="c"?uri="http://java.sun.com/jstl/core_rt"?%>
          <%@?taglib?prefix="fmt"?uri="http://java.sun.com/jstl/fmt"%>?


          <!DOCTYPE?HTML?PUBLIC?"-//W3C//DTD?HTML?4.01?Transitional//EN">

          <html>
          <head></head>??
          <body>

          ????
          <c:out?value="${model.message}"/>
          </body>
          </html>
          因為InternalPathMethodNameResolver方法名解釋器會把整個URL中最后一個"/"和最后一個"."之間的部分作為要調(diào)用的方法名,所以你可以在這個URL后面加任意文件格式的后綴,比如:
          localhost:8080/page/controller/method1.jsp

          localhost:8080/page/controller/method2.html
          很爽吧,和真實的URL地址一樣。


          另:開發(fā)環(huán)境:MyEclipse5.0M2+tomcat5.5
            需要用到spring.jar和jstl.jar兩個包。

          附:源代碼下載

          posted @ 2006-08-31 13:39 zeroblue 閱讀(10053) | 評論 (3)編輯 收藏

          ?

          package ?com.schedule;

          import ?java.io.BufferedReader;
          import ?java.io.FileOutputStream;
          import ?java.io.IOException;
          import ?java.io.InputStreamReader;
          import ?java.io.OutputStreamWriter;
          import ?java.net.HttpURLConnection;
          import ?java.net.MalformedURLException;
          import ?java.net.URL;
          import ?java.util.HashMap;
          import ?java.util.Iterator;
          import ?java.util.Map;

          public ? class ?StaticPageService? {
          ????
          private ?Map < String,?String > ?urlMap;

          ????
          private ?String?realPath;

          ????
          public ? void ?createFile()? {
          ????????
          if ?(urlMap? == ? null )? {
          ????????????
          throw ? new ?NullPointerException( " The?url?map?is?should?not?be?null! " );
          ????????}

          ????????Iterator
          < String > ?keys? = ?urlMap.keySet().iterator();
          ????????String?inputLine;
          ????????String?enter?
          = ? " \n " ;
          ????????StringBuffer?buffer?
          = ? new ?StringBuffer();
          ????????
          try ? {
          ????????????
          while ?(keys.hasNext())? {
          ????????????????String?key?
          = ?keys.next();
          ????????????????URL?url?
          = ? new ?URL(key);
          ????????????????HttpURLConnection?uc?
          = ?(HttpURLConnection)?url.openConnection();
          ????????????????BufferedReader?in?
          = ? new ?BufferedReader( new ?InputStreamReader(uc.getInputStream()));
          ????????????????
          if (buffer.length() > 0 )buffer.delete( 0 ,buffer.length());
          ????????????????
          while ?((inputLine? = ?in.readLine())? != ? null )? {
          ????????????????????buffer.append(inputLine);
          ????????????????????buffer.append(enter);
          ????????????????}

          ????????????????String?file?
          = ?realPath? + ?urlMap.get(key);
          ????????????????OutputStreamWriter?fw?
          = ? new ?OutputStreamWriter(
          ????????????????????????
          new ?FileOutputStream(file),? " GBK " );
          ????????????????fw.write(buffer.toString());
          ????????????????in.close();
          ????????????????fw.close();
          ????????????}

          ????????}
          ? catch ?(MalformedURLException?e)? {
          ????????????e.printStackTrace();
          ????????}
          ? catch ?(IOException?e)? {
          ????????????e.printStackTrace();
          ????????}

          ????}


          ????
          /**
          ?????*?
          @param ?urlMap
          ?????*????????????the?urlMap?to?set
          ?????
          */

          ????
          public ? void ?setUrlMap(Map < String,?String > ?urlMap)? {
          ????????
          this .urlMap? = ?urlMap;
          ????}


          ????
          /**
          ?????*?
          @param ?realPath
          ?????*????????????the?realPath?to?set
          ?????
          */

          ????
          public ? void ?setRealPath(String?realPath)? {
          ????????
          this .realPath? = ?realPath;
          ????}


          ????
          public ? static ? void ?main(String[]?args)? {
          ????????StaticPageService?service?
          = ? new ?StaticPageService();
          ????????Map
          < String,?String > ?urlMap? = ? new ?HashMap < String,?String > ();
          ????????
          // map的key為要生成靜態(tài)頁面的url,value為生成后的靜態(tài)文件保存的路徑
          ????????urlMap.put( " http://localhost:8080/index.jsp " ,? " /temp/index1.html " );
          ????????urlMap.put(
          " http://www.yahoo.com.cn/ " ,? " /temp/index2.html " );
          ????????
          // 此參數(shù)用來設(shè)置當(dāng)前Web應(yīng)用的真實路徑
          ????????service.setRealPath( " d: " );
          ????????service.setUrlMap(urlMap);
          ????????service.createFile();
          ????}


          }

          posted @ 2006-08-30 11:33 zeroblue 閱讀(1037) | 評論 (2)編輯 收藏

            最近學(xué)習(xí)的興趣很濃,昨夜本想look look專業(yè)方面的東東。打開筆記本發(fā)現(xiàn)沒聲音,初以為是軟件故障,故重裝驅(qū)動,不靈。懷疑中了病毒,于是升級最新補丁、殺毒。果然報告有病毒,操刀殺之,依舊不靈。嗯,是不是因為病毒破壞了系統(tǒng)文件?干脆Ghost恢復(fù),我做了系統(tǒng)備份,哇哈哈。
            一番折騰,重新啟動電腦,……濤聲依舊……。此時方才大悟,是硬件本身出了問題,不會修,只有對著哭的份了。
            算了,用臺式機。丫竟然一到windows畫面就重啟!!打開機箱,細細檢查了一通,把零件拔下重插,開機,照舊。此時我已經(jīng)有點腦充血了。
            拿出手頭的工具盤,檢查磁盤時提示有N處數(shù)據(jù)錯誤,無法恢復(fù)。只好忍痛格掉C盤,進行磁盤檢查,然后Ghost恢復(fù)。誰知Ghost恢復(fù)后的系統(tǒng)竟然無法啟動。徹底崩潰。
            只好全新安裝操作系統(tǒng),以下的動作全然是幽靈附體,本人毫無知覺。
            此時凌晨一點,萬籟寂靜,只余一男子獨立桌前,欲哭無淚……

          posted @ 2006-08-30 11:20 zeroblue 閱讀(272) | 評論 (0)編輯 收藏

          web.xml中定義的過濾器:
          ??????? (注:Appfuse的構(gòu)建網(wǎng)上有豐富的資料,在此不再贅述)

          1、securityFilter

          < filter >
          ????????
          < filter-name > securityFilter </ filter-name >
          ????????
          < filter-class >
          ????????????org.acegisecurity.util.FilterToBeanProxy
          ????????
          </ filter-class >
          ????????
          < init-param >
          ????????????
          < param-name > targetClass </ param-name >
          ????????????
          < param-value >
          ????????????????org.acegisecurity.util.FilterChainProxy
          ????????????
          </ param-value >
          ????????
          </ init-param >
          </ filter >

            此過濾器定義Acegi Security 應(yīng)用。Acegi Security 被廣泛應(yīng)用于Spring社區(qū),在基于Spring的項目中提供全面的安全服務(wù)。它包含了一組接口和類,可以直接在Spring IoC容器中進行配置。Acegi Security 完全基于接口設(shè)計實現(xiàn),為用戶定制和擴展提供了極大的空間。基于SpringAOP,Acegi Security 可以完成方法級的權(quán)限管理。
          (
          文檔
          ?下載)

          2、cacheFilter

          < filter >
          ????????
          < filter-name > cacheFilter </ filter-name >
          ????????
          < filter-class >
          ????????????com.opensymphony.oscache.web.filter.CacheFilter
          ????????
          </ filter-class >
           
          </ filter >

            OSCache是一個基于javaEE架構(gòu)的緩存解決方案,主要針對頁面緩存。由OpenSymphony設(shè)計,它是一種開創(chuàng)性的JSP定制標記應(yīng)用,提供了在現(xiàn)有JSP頁面之內(nèi)實現(xiàn)高速緩存的機制。 其提供了內(nèi)存和磁盤緩存兩種機制,這種緩存機制使你的Web應(yīng)用具備了一定程度的容錯性,比如當(dāng)數(shù)據(jù)庫因某些原因當(dāng)?shù)魰r,遠程用戶仍能訪問緩存中的內(nèi)容。
          ???
          但有意思的是,Appfuse并沒用使用這個頁面緩存機制。這個過濾器的filter-mapping被注釋掉了。如下:

          ?? <!-- ?Commented?out? for ? 2 ?reasons:?
          ??????????????????????????????????????????1 )?it ' s?a?pain?when?developing?JSPs,?and

          ?????????????????????????????????????? 2 )?it?causes?the?Signup?webtest?to?fail?
          ???????????????????????????????????????? 大意是說這東西使開發(fā)Jsp頁面變得很痛苦,并且無法測試(英文水平有限 ^_^)。
          ??????-->

          ????
          <!-- filter - mapping >
          ????????
          < filter - name > cacheFilter </ filter - name >
          ????????
          < url - pattern >* .jsp </ url - pattern >
          ????
          </ filter - mapping -->

          ( 文檔與下載? ?)

          3、clickstream

          < filter >
          ????
          < filter - name > clickstream </ filter - name >
          ????
          < filter - class > com.opensymphony.clickstream.ClickstreamFilter </ filter - class >
          </ filter >

          < filter - mapping >
          ????
          < filter - name > clickstream </ filter - name >
          ????
          < url - pattern >* .jsp </ url - pattern >
          </ filter - mapping >

          < filter - mapping >
          ????
          < filter - name > clickstream </ filter - name >
          ????
          < url - pattern >* .html </ url - pattern >
          </ filter - mapping >

          < listener >
          ????
          < listener - class > com.opensymphony.clickstream.ClickstreamListener </ listener - class >
          </ listener >


            又是opensymphony的東西,clickstream用來跟蹤用戶的頁面操作。其功能非常強大,通過過濾器我們可以跟蹤用戶的每一次點擊信息。并且在用戶的Session結(jié)束時,可以將用戶的跟蹤信息輸出到文件或形成一個輸出流以便處理。當(dāng)用戶的Session開始時listener開始一次跟蹤,filter捕捉每一次請求。
          文檔與下載

          4、hibernateFilter

          ???? < filter >
          ????????
          < filter-name > hibernateFilter </ filter-name >
          ????????
          < filter-class >
          ????????????org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
          ????????
          </ filter-class >
          ????
          </ filter >

          ??
          < filter > ?
          ????????
          < filter-name > opensession </ filter-name >
          ?
          ????????
          < filter-class > org.springframework.orm.hibernate3.support.OpenSessionInViewFilter </ filter-class >
          ?
          ????????
          < init-param >
          ?
          ????????????
          < param-name > singleSession </ param-name >
          ?
          ????????????
          < param-value > false </ param-value >
          ?
          ????????
          </ init-param >
          ?
          ????
          </ filter > ?

            當(dāng)使用hibernate的延遲加載時,你必須保證是在同一個Session中使用結(jié)果集,否則會拋出異常。而HibernateTemplate試圖每次執(zhí)行時打開和關(guān)閉Session。這時就應(yīng)該采用 OpenSessionInViewFilter模式。
          相關(guān)文檔
          5、UrlRewriteFilter

          ? < filter >
          ?  
          < filter-name > rewriteFilter </ filter-name >
          ??   
          < filter-class >
          ???    org.tuckey.web.filters.urlrewrite.UrlRewriteFilter
          ??   
          </ filter-class >
          ??  
          < init-param >
          ??? 
          < param-name > logLevel </ param-name >
          ???   
          < param-value > commons </ param-value >
          ? ?
          </ init-param >
          ?
          </ filter >
          < filter-mapping >
          ??
          < filter-name > rewriteFilter </ filter-name >
          ??
          < url-pattern > /* </ url-pattern >
          ??
          <!-- dispatcher>REQUEST</dispatcher>
          ???<dispatcher>FORWARD</dispatcher
          -->

          ?
          </ filter-mapping >

            Url重寫,通過配置文件改寫你的URL,將輸入的URL映射到真實的URL地址來達到URL美化的作用。
          文檔與下載

          6、sitemesh

          ? < filter >
          ??
          < filter-name > sitemesh </ filter-name >
          ??
          < filter-class >
          ???com.opensymphony.module.sitemesh.filter.PageFilter
          ??
          </ filter-class >
          ?
          </ filter >

            sitemesh是由一個基于web頁面布局、裝飾以及與現(xiàn)存web應(yīng)用整合的框架。它能幫助我們在由大量頁面構(gòu)成的項目中創(chuàng)建一致的頁面布局和外觀,?如一致的導(dǎo)航條,一致的banner,一致的版權(quán),等等。它不僅僅能處理動態(tài)的內(nèi)容,如jsp,php,asp等產(chǎn)生的內(nèi)容,它也能處理靜態(tài)的內(nèi)容,?如htm的內(nèi)容,使得它的內(nèi)容也符合你的頁面結(jié)構(gòu)的要求。甚至于它能將html文件象include那樣將該文件作為一個面板的形式嵌入到別的文件中去。
          文檔與下載 )( 學(xué)習(xí)

          7、Display Tag Lib標簽庫

          < filter >
          ????????
          < filter-name > exportFilter </ filter-name >
          ????????
          < filter-class >
          ????????????org.displaytag.filter.ResponseOverrideFilter
          ????????
          </ filter-class >
          </ filter >

            Display Tag Lib是一個標簽庫,用來處理jsp網(wǎng)頁上的Table,功能非常強,可以對的Table進行分頁、數(shù)據(jù)導(dǎo)出、分組、對列排序等等,??而且使用起來非常的方便。能夠大大減少代碼量。
          文檔與下載

          8、GZIPFilter

          ???? < filter >
          ????????
          < filter-name > compressionFilter </ filter-name >
          ????????
          < filter-class > com.lady.webapp.filter.GZIPFilter </ filter-class >
          ????
          </ filter >

          將輸出流壓縮為GZIP格式,據(jù)說壓縮比率可達70%-80%,這樣輸出到客戶端的數(shù)據(jù)量大大減少,可以顯著的提高性能。這是一個Appfuse自定義的過濾器,詳情見下面鏈接。
          文檔

          最后一個是I18N應(yīng)用的過濾器,不多說了。

          還有一個監(jiān)聽器非常重要,即IntrospectorCleanupListener:

          ???? < listener >
          ????????
          < listener-class >
          ????????????org.springframework.web.util.IntrospectorCleanupListener
          ????????
          </ listener-class >
          ????
          </ listener >

          有現(xiàn)成的資料,COPY過來:
          spring中的提供了一個名為org.springframework.web.util.IntrospectorCleanupListener的監(jiān)聽器。它主要負責(zé)處理由??JavaBeans Introspector的使用而引起的緩沖泄露。
          (引用:劉文濤的BLOG

          posted @ 2006-08-29 13:48 zeroblue 閱讀(1917) | 評論 (0)編輯 收藏

          主站蜘蛛池模板: 上高县| 璧山县| 济南市| 松桃| 敖汉旗| 长兴县| 肥乡县| 东丰县| 巴马| 周宁县| 和田市| 五大连池市| 集安市| 昌乐县| 儋州市| 南皮县| 永吉县| 凌源市| 来凤县| 柳江县| 广丰县| 靖宇县| 松江区| 武安市| 抚宁县| 崇信县| 团风县| 徐州市| 定日县| 永顺县| 海阳市| 玛曲县| 松潘县| 宝清县| 福泉市| 孙吴县| 张掖市| 余干县| 冕宁县| 永登县| 棋牌|