<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="http://feeds.qzone.qq.com/rss.xsl" version="1.0"?>
<rss version="2.0" xmlns:qz="http://qzone.qq.com">
<channel>
<title><![CDATA[/tp鳎毪鍪蕾]]></title>
<description><![CDATA[极度郁闷的个人空间]]></description>
<link>http://344867279.qzone.qq.com</link>
<lastBuildDate>Sat, 28 Nov 2009 20:45:59 GMT</lastBuildDate>
<generator>Qzone</generator>
<language>zh-cn</language>
<copyright>Copyright (C), 2005-2008, Tencent Tech. Co., Ltd.</copyright>
<pubDate>Wed, 25 Nov 2009 01:12:10 GMT</pubDate>

<item>
<title><![CDATA[[转]“开心农场”给我们的20条人生启示]]></title>
<link>http://344867279.qzone.qq.com/blog/1259111530</link>
<description><![CDATA[1、在利益面前，没有亲情和道义可讲，任何人都可能成为对你背后下手的贼； <br>2、帮你除草、杀虫，对你示好的人，来你家的真实目的可能并不是这个，而是看你有没有可偷的东西； <br>3、越有钱的人赚钱的速度最快，温饱线上的人都在量入为出中挣扎； <br>4、很多事情都有捷径可走，有“背景”的人肯定升级快； <br>5、勤能补拙是有局限性的，每天靠除草、杀虫的经验只有那么多； <br>6、挖种子是排除人民币升级之外最快的升级方法，也就是说只要肯付出高昂的代价走歪门邪道，肯定能领先别人一步； <br>7、那种以“友情”为名义的化肥，是最不讲友情的东西； <br>8、想让狗干活，又不想给狗喂食，是不可能的，就算一条狗也会消极怠工； <br>9、狗会疯狂地咬穷人，当你身无分文，被咬的概率是100%； <br>10、广交朋友是硬道理，多个朋友就会多一条路； <br>11、有些时候我们期待着有人来搞一点小事端，从而获得想要的经验； <br>12、不遵守时间是要付出代价的； <br>13、没事的时候多出去转转，总会有意想不到的收获； <br>14、未必撒下昂贵的种子就一定赚更多的钱，但被盗时种贵菜的损失肯定会更多； <br>15、任何活动都是有目的的，不管是促销化肥还是促销打狗棒； <br>16、集体的力量是巨大的，可以瞬间让一个人破产； <br>17、当有人告诉你快去某某的菜地偷菜时，不要把他当成最亲密的战友，因为当你成熟的时候，他也一定会这么告诉别人； <br>18、大地主都是排在前面的； <br>19、很多级别高而且地多的人在种白萝卜，不是他们傻，而是因为他们想升职，而且不差钱儿； <br>20、早晨很早就起床，并不是不可能的。<br> <!--v:3.2--> ]]></description>
<category><![CDATA[个人日记]]></category>
<author><![CDATA[344867279@qq.com(/tp鳎毪鍪蕾)]]></author>
<comments>http://344867279.qzone.qq.com/blog/1259111530#comment</comments>
<qz:effect>134218240</qz:effect>
<pubDate>Wed, 25 Nov 2009 01:12:10 GMT</pubDate>
<guid>http://344867279.qzone.qq.com/blog/1259111530</guid>
</item>

<item>
<title><![CDATA[extjs登录实例]]></title>
<link>http://344867279.qzone.qq.com/blog/1239971378</link>
<description><![CDATA[先看一下截图<wbr /><a href="http://b17.photo.store.qq.com/http_imgload.cgi?/rurl4_b=f208e5970be1aec5e9f46fe33a17f77e8e6f75fbc41a447dfefc1ba287c3d27cc12a61229e585565d46e6edb332ade3147ebef2b8a2d5c2d317240406c3b0a3551885d65d07c256fad86d68f74be170da6a5de54" target="_blank"><img style="border:0;" src="http://b17.photo.store.qq.com/http_imgload.cgi?/rurl4_b=f208e5970be1aec5e9f46fe33a17f77e8e6f75fbc41a447dfefc1ba287c3d27cc12a61229e585565d46e6edb332ade3147ebef2b8a2d5c2d317240406c3b0a3551885d65d07c256fad86d68f74be170da6a5de54" /></a><wbr /><br>Ext.QuickTips.init();<br>LoginWindow = Ext.extend(Ext.Window,{<br> title:&quot;系统登录&quot;,<br> width:275,<br> height:155,<br> collapsible:true,<br> defaults:{<br>  border:false<br> },<br> buttonAlign:&quot;center&quot;,<br> <br> createFormPanel : function(){<br>  <br>  //表单重组函数<br>  function reset(){<br>   myform.form.reset();<br>  };<br>  <br>  //表单提交函数<br>   function surely() {<br>            if(myform.getForm().isValid())<br>            {<br>                myform.form.submit({<br>                    waitMsg : &quot;正在登录......&quot;,<br>                    url : &quot;#&quot;,<br>                    timeout: 30000,<br>                    success : function(form, action) {<br>                        if(action.result.type == 0)//OP<br>                        window.location.href = &quot;index.jsp&quot;;<br>                        else//CP<br>                        window.location.href = &quot;login.jsp&quot;;<br>                    },<br>                    failure : function(form, action) {<br>                        form.reset();<br>                        if (action.failureType == Ext.form.Action.SERVER_INVALID)<br>                        Ext.MessageBox.alert(&quot;警告&quot;, action.result.errors.msg);<br>                    }<br>                });<br>            }<br>        };<br>  <br>  var myform = new Ext.form.FormPanel({<br>   bodyStyle:&quot;padding-top:6px&quot;,<br>   defaultType:&quot;textfield&quot;,<br>   labelAlign:&quot;right&quot;,<br>   labelWidth:55,<br>   labelPad:2,<br>   method:'POST',<br>   //增加表单键盘事件<br>   keys:[<br>   {<br>    key:[10,13],<br>    fn:surely<br>   }],<br>   defaults:{<br>    allowBlank:false,<br>    width:158<br>   },<br>   items:[{<br>    cls:&quot;user&quot;,<br>    name:&quot;username&quot;,<br>    fieldLabel:&quot;帐 号&quot;,<br>    blankText:&quot;帐号不能为空！&quot;<br>   },<br>   {<br>    cls:&quot;key&quot;,<br>    name:&quot;password&quot;,<br>    fieldLabel:&quot;密 码&quot;,<br>    blankText:&quot;密码不能为空！&quot;<br>   },<br>   {<br>    cls:&quot;key&quot;,<br>    name:&quot;randCode&quot;,<br>    id:&quot;randCode&quot;,<br>    fieldLabel:&quot;验证码&quot;,<br>    width:70,<br>    blankText:&quot;验证码不能为空！&quot;<br>   }],<br>   buttons:[<br>   {<br>    text:&quot;确 定&quot;,<br>    id:&quot;sure&quot;,<br>    handler:surely<br>   },<br>   {<br>    text:&quot;重 置&quot;,<br>    id:&quot;clear&quot;,<br>    handler:reset<br>   }]<br>  });<br>  return myform;<br> },<br>   <br>      initComponent : function(){<br>        LoginWindow.superclass.initComponent.call(this);<br>        this.fp=this.createFormPanel();<br>        this.add(this.fp);<br>   }<br>});<br><br>Ext.onReady(function()<br>{<br>   var win=new LoginWindow();<br>   win.show();<br>   var bd = Ext.getDom(&quot;randCode&quot;);<br>   var bd2 = Ext.get(bd.parentNode);<br>   bd2.createChild({tag: &quot;img&quot;, src: &quot;authImg&quot;,align:&quot;absbottom&quot;});<br>});<br><br> <!--v:3.2--> ]]></description>
<category><![CDATA[个人日记]]></category>
<author><![CDATA[344867279@qq.com(/tp鳎毪鍪蕾)]]></author>
<comments>http://344867279.qzone.qq.com/blog/1239971378#comment</comments>
<qz:effect>134218241</qz:effect>
<pubDate>Fri, 17 Apr 2009 12:29:38 GMT</pubDate>
<guid>http://344867279.qzone.qq.com/blog/1239971378</guid>
</item>

<item>
<title><![CDATA[简单的搜索引擎开发（struts2+spring2.5+hibernat3.3+compass）]]></title>
<link>http://344867279.qzone.qq.com/blog/1231993407</link>
<description><![CDATA[<br><br>     其实就是用struts2.1.6+spring2.5+hibernat3.3+compass整合做了一个简单的搜索功能而已，我将贴出来给大家看看<br><wbr /><a href="http://b5.photo.store.qq.com/http_imgload.cgi?/rurl4_b=f208e5970be1aec5e9f46fe33a17f77e6171abbae9f5e766fae2288e18158c3f9f3f91b3c35089e4b6315c38b86bf21adb28819ca293b7d6b07558d995d8884ccd43b4cf7522b64fba733d8e9e49b896e03d6260" target="_blank"><img style="border:0;" src="http://b5.photo.store.qq.com/http_imgload.cgi?/rurl4_b=f208e5970be1aec5e9f46fe33a17f77e6171abbae9f5e766fae2288e18158c3f9f3f91b3c35089e4b6315c38b86bf21adb28819ca293b7d6b07558d995d8884ccd43b4cf7522b64fba733d8e9e49b896e03d6260" /></a><wbr /> <!--v:3.2--> ]]></description>
<category><![CDATA[个人日记]]></category>
<author><![CDATA[344867279@qq.com(/tp鳎毪鍪蕾)]]></author>
<comments>http://344867279.qzone.qq.com/blog/1231993407#comment</comments>
<qz:effect>134218241</qz:effect>
<pubDate>Thu, 15 Jan 2009 04:23:27 GMT</pubDate>
<guid>http://344867279.qzone.qq.com/blog/1231993407</guid>
</item>

<item>
<title><![CDATA[jbpm开发实例（二）]]></title>
<link>http://344867279.qzone.qq.com/blog/1231127108</link>
<description><![CDATA[如果觉得看的有点模糊可以看看我传上来的那个图。然后你在这个试图框的下面可以看到有个source，点击一下，就会发现他已经自动的给你生成xml代码了。但是这样还是有点不够，我们只是定义了一个tasknode节点，并没有定义tasknode节点的任务由谁来做。那么我们还要定义一个tasknode节点是由谁来做的： <br>    那么这段代码是这么写的： <br><br>Java代码 <a href="http://www.javaeye.com/topic/193241#" target="_blank"><wbr /><a href="http://www.javaeye.com/images/icon_copy.gif" target="_blank"><img style="border:0;" src="http://www.javaeye.com/images/icon_copy.gif" /></a><wbr /></a><wbr /><br><li style="margin:25px;">&lt;?xml version=<span style="color:#0000ff;line-height:1.8em;">&quot;1.0&quot;</span><wbr /> encoding=<span style="color:#0000ff;line-height:1.8em;">&quot;UTF-8&quot;</span><wbr />?&gt;   </li><li style="margin:25px;">  </li><li style="margin:25px;">&lt;process-definition   </li><li style="margin:25px;">  xmlns=<span style="color:#0000ff;line-height:1.8em;">&quot;&quot;</span><wbr />  name=<span style="color:#0000ff;line-height:1.8em;">&quot;test1&quot;</span><wbr />&gt;   </li><li style="margin:25px;">   &lt;start-state name=<span style="color:#0000ff;line-height:1.8em;">&quot;start&quot;</span><wbr />&gt;   </li><li style="margin:25px;">      &lt;transition name=<span style="color:#0000ff;line-height:1.8em;">&quot;&quot;</span><wbr /> to=<span style="color:#0000ff;line-height:1.8em;">&quot;部门经理审批&quot;</span><wbr />&gt;&lt;/transition&gt;   </li><li style="margin:25px;">   &lt;/start-state&gt;   </li><li style="margin:25px;">   &lt;task-node name=<span style="color:#0000ff;line-height:1.8em;">&quot;部门经理审批&quot;</span><wbr />&gt;   </li><li style="margin:25px;">      &lt;task&gt;   </li><li style="margin:25px;">        &lt;assigment actorId=<span style="color:#0000ff;line-height:1.8em;">&quot;部门经理&quot;</span><wbr />&gt;&lt;/assigment&gt;   </li><li style="margin:25px;">      &lt;/task&gt;   </li><li style="margin:25px;">      &lt;transition name=<span style="color:#0000ff;line-height:1.8em;">&quot;&quot;</span><wbr /> to=<span style="color:#0000ff;line-height:1.8em;">&quot;总经理审批&quot;</span><wbr />&gt;&lt;/transition&gt;   </li><li style="margin:25px;">   &lt;/task-node&gt;   </li><li style="margin:25px;">   &lt;task-node name=<span style="color:#0000ff;line-height:1.8em;">&quot;总经理审批&quot;</span><wbr />&gt;   </li><li style="margin:25px;">      &lt;task&gt;   </li><li style="margin:25px;">        &lt;assigment actorId=<span style="color:#0000ff;line-height:1.8em;">&quot;总经理&quot;</span><wbr />&gt;&lt;/assigment&gt;   </li><li style="margin:25px;">      &lt;/task&gt;   </li><li style="margin:25px;">      &lt;transition name=<span style="color:#0000ff;line-height:1.8em;">&quot;&quot;</span><wbr /> to=<span style="color:#0000ff;line-height:1.8em;">&quot;end1&quot;</span><wbr />&gt;&lt;/transition&gt;   </li><li style="margin:25px;">   &lt;/task-node&gt;   </li><li style="margin:25px;">   &lt;end-state name=<span style="color:#0000ff;line-height:1.8em;">&quot;end1&quot;</span><wbr />&gt;&lt;/end-state&gt;   </li><li style="margin:25px;">&lt;/process-definition&gt;  </li></ol>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&lt;process-definition  xmlns=&quot;&quot;  name=&quot;test1&quot;&gt;   &lt;start-state name=&quot;start&quot;&gt;      &lt;transition name=&quot;&quot; to=&quot;部门经理审批&quot;&gt;&lt;/transition&gt;   &lt;/start-state&gt;   &lt;task-node name=&quot;部门经理审批&quot;&gt;      &lt;task&gt;       &lt;assigment actorId=&quot;部门经理&quot;&gt;&lt;/assigment&gt;      &lt;/task&gt;      &lt;transition name=&quot;&quot; to=&quot;总经理审批&quot;&gt;&lt;/transition&gt;   &lt;/task-node&gt;   &lt;task-node name=&quot;总经理审批&quot;&gt;      &lt;task&gt;       &lt;assigment actorId=&quot;总经理&quot;&gt;&lt;/assigment&gt;      &lt;/task&gt;      &lt;transition name=&quot;&quot; to=&quot;end1&quot;&gt;&lt;/transition&gt;   &lt;/task-node&gt;   &lt;end-state name=&quot;end1&quot;&gt;&lt;/end-state&gt;&lt;/process-definition&gt;<br><br>    这样的话我们的流程定义文件就定义完了，但是这只是把文件定义完了，系统并不知道啊，所以我们还要把我们的文件部署到系统中去，那么这个过程是这样的： <br><br>    首先我们在src/main/java里面新建立一个包，然后建立一个class，随便起个名字，就叫TestJBPM_01吧，那么在这个类里面我们要做的是什么呢？我们要先导入表，因为jbpm要运行就要用到很多个表，ok，那么我们这个里面导入表和hibernate导入表是差不多的，它的代码是这样的： <br>Java代码 <a href="http://www.javaeye.com/topic/193241#" target="_blank"><wbr /><a href="http://www.javaeye.com/images/icon_copy.gif" target="_blank"><img style="border:0;" src="http://www.javaeye.com/images/icon_copy.gif" /></a><wbr /></a><wbr /><br><li style="margin:25px;"><span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">package</span><wbr /></span><wbr /> com.jbpm.test;   </li><li style="margin:25px;">  </li><li style="margin:25px;"><span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">import</span><wbr /></span><wbr /> junit.framework.TestCase;   </li><li style="margin:25px;">  </li><li style="margin:25px;"><span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">import</span><wbr /></span><wbr /> org.jbpm.JbpmConfiguration;   </li><li style="margin:25px;">  </li><li style="margin:25px;"><span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">public</span><wbr /></span><wbr /> <span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">class</span><wbr /></span><wbr /> TestJbpm_01 <span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">extends</span><wbr /></span><wbr /> TestCase {   </li><li style="margin:25px;">       </li><li style="margin:25px;">    <span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">public</span><wbr /></span><wbr /> <span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">void</span><wbr /></span><wbr /> testJbpm(){   </li><li style="margin:25px;">           </li><li style="margin:25px;">        <span style="color:#008200;line-height:1.8em;">//创建jbpm数据库表。他就像hibernate里面的哪个export一样。实际上他就是hibernate里面的哪个export。 </span><wbr />  </li><li style="margin:25px;">        <span style="color:#008200;line-height:1.8em;">//应为他映射了很多个表，所以我们就能创建那么多个表。 </span><wbr />  </li><li style="margin:25px;">        JbpmConfiguration.getInstance().createSchema();   </li><li style="margin:25px;">           </li><li style="margin:25px;">    }   </li><li style="margin:25px;">}  </li></ol>package com.jbpm.test;import junit.framework.TestCase;import org.jbpm.JbpmConfiguration;public class TestJbpm_01 extends TestCase {  public void testJbpm(){    //创建jbpm数据库表。他就像hibernate里面的哪个export一样。实际上他就是hibernate里面的哪个export。  //应为他映射了很多个表，所以我们就能创建那么多个表。  JbpmConfiguration.getInstance().createSchema();   }}<br><br>然后呢我们就开始部署我们的流程定义文件，我们将这个文件当中的内容呢放到数据库当中去，当我们以后再用的时候呢我们就随时的将它加载出来。 <br><br>Java代码 <a href="http://www.javaeye.com/topic/193241#" target="_blank"><wbr /><a href="http://www.javaeye.com/images/icon_copy.gif" target="_blank"><img style="border:0;" src="http://www.javaeye.com/images/icon_copy.gif" /></a><wbr /></a><wbr /><br><li style="margin:25px;"><span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">package</span><wbr /></span><wbr /> com.jbpm.test;   </li><li style="margin:25px;">  </li><li style="margin:25px;"><span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">import</span><wbr /></span><wbr /> junit.framework.TestCase;   </li><li style="margin:25px;">  </li><li style="margin:25px;"><span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">import</span><wbr /></span><wbr /> org.jbpm.JbpmConfiguration;   </li><li style="margin:25px;"><span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">import</span><wbr /></span><wbr /> org.jbpm.JbpmContext;   </li><li style="margin:25px;"><span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">import</span><wbr /></span><wbr /> org.jbpm.graph.def.ProcessDefinition;   </li><li style="margin:25px;">  </li><li style="margin:25px;"><span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">public</span><wbr /></span><wbr /> <span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">class</span><wbr /></span><wbr /> TestJbpm_02 <span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">extends</span><wbr /></span><wbr /> TestCase {   </li><li style="margin:25px;">       </li><li style="margin:25px;">    <span style="color:#008200;line-height:1.8em;">//jbpmConfiguration对象的创建 </span><wbr />  </li><li style="margin:25px;">    <span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">static</span><wbr /></span><wbr /> JbpmConfiguration jbpmConfiguration = JbpmConfiguration.getInstance();   </li><li style="margin:25px;">       </li><li style="margin:25px;">    <span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">public</span><wbr /></span><wbr /> <span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">void</span><wbr /></span><wbr /> testJbpm(){   </li><li style="margin:25px;">           </li><li style="margin:25px;">        <span style="color:#008200;line-height:1.8em;">//然后我们把processDefinition里面相关的对象持久化到数据库里面去。 </span><wbr />  </li><li style="margin:25px;">        <span style="color:#008200;line-height:1.8em;">//流程定义文件里面有很多个概念，他有node，有transition，还有processDefinition，那么我们不需要一个 </span><wbr />  </li><li style="margin:25px;">        <span style="color:#008200;line-height:1.8em;">//一个保存，jbpm把保存这么多对象的方法封装成一个接口，叫做deployProcessDefinition。我们只要调用这个 </span><wbr />  </li><li style="margin:25px;">        <span style="color:#008200;line-height:1.8em;">//方法，传一个processDefinition对象，我们就能将他们存入到数据库里面去。 </span><wbr />  </li><li style="margin:25px;">           </li><li style="margin:25px;">        <span style="color:#008200;line-height:1.8em;">//这个首先第一步我们要得到一个processDefinition对象，然后我们把他部署到流程中去。 </span><wbr />  </li><li style="margin:25px;">        ProcessDefinition processDefinition = ProcessDefinition.parseXmlResource(<span style="color:#0000ff;line-height:1.8em;">&quot;testJBPM/testJbpm.xml&quot;</span><wbr />);   </li><li style="margin:25px;">        <span style="color:#008200;line-height:1.8em;">//我们要存就必须获得一个session对象，而jbpm已经把session对象封装到一个JbpmContext对象里面了。 </span><wbr />  </li><li style="margin:25px;">        <span style="color:#008200;line-height:1.8em;">//那么这个jbpmContext对象是怎么得到的呢，我们要先有一个jbpmConfiguration对象，我们要对数据库进行 </span><wbr />  </li><li style="margin:25px;">        <span style="color:#008200;line-height:1.8em;">//操作的时候一定要有jbpmConfiguration这个对象，用他来创建一个类似于hibernate当中的session一样的 </span><wbr />  </li><li style="margin:25px;">        <span style="color:#008200;line-height:1.8em;">//对象——jbpmContext。他是我们对数据库所有的操作的一个接口。 </span><wbr />  </li><li style="margin:25px;">        JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();   </li><li style="margin:25px;">        <span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">try</span><wbr /></span><wbr />{   </li><li style="margin:25px;">            <span style="color:#008200;line-height:1.8em;">//然后部署的操作已经由jbpmContext给我们创建好了，我们只需要调一下他的一个方法就可以了。 </span><wbr />  </li><li style="margin:25px;">            jbpmContext.deployProcessDefinition(processDefinition);   </li><li style="margin:25px;">        }<span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">finally</span><wbr /></span><wbr />{   </li><li style="margin:25px;">            <span style="color:#008200;line-height:1.8em;">//最后我们还要对他close一下，就像我们用hibernate的时候要close session一样。 </span><wbr />  </li><li style="margin:25px;">            jbpmContext.close();   </li><li style="margin:25px;">        }   </li><li style="margin:25px;">    }   </li><li style="margin:25px;">}  </li></ol>package com.jbpm.test;import junit.framework.TestCase;import org.jbpm.JbpmConfiguration;import org.jbpm.JbpmContext;import org.jbpm.graph.def.ProcessDefinition;public class TestJbpm_02 extends TestCase {  //jbpmConfiguration对象的创建 static JbpmConfiguration jbpmConfiguration = JbpmConfiguration.getInstance();  public void testJbpm(){    //然后我们把processDefinition里面相关的对象持久化到数据库里面去。  //流程定义文件里面有很多个概念，他有node，有transition，还有processDefinition，那么我们不需要一个  //一个保存，jbpm把保存这么多对象的方法封装成一个接口，叫做deployProcessDefinition。我们只要调用这个  //方法，传一个processDefinition对象，我们就能将他们存入到数据库里面去。    //这个首先第一步我们要得到一个processDefinition对象，然后我们把他部署到流程中去。  ProcessDefinition processDefinition = ProcessDefinition.parseXmlResource(&quot;testJBPM/testJbpm.xml&quot;);  //我们要存就必须获得一个session对象，而jbpm已经把session对象封装到一个JbpmContext对象里面了。  //那么这个jbpmContext对象是怎么得到的呢，我们要先有一个jbpmConfiguration对象，我们要对数据库进行  //操作的时候一定要有jbpmConfiguration这个对象，用他来创建一个类似于hibernate当中的session一样的  //对象——jbpmContext。他是我们对数据库所有的操作的一个接口。  JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();  try{   //然后部署的操作已经由jbpmContext给我们创建好了，我们只需要调一下他的一个方法就可以了。   jbpmContext.deployProcessDefinition(processDefinition);  }finally{   //最后我们还要对他close一下，就像我们用hibernate的时候要close session一样。   jbpmContext.close();  } }}<br><br>Ok，第二步我们也做完了，那么现在我们开始做第三步，也就是说，我们流程定义文件写好了，现在我们的系统当中有了这样一个报销流程，那么就开始实际的去用她吧，一个人小报销了，那么她就要写一个报销的申请，但是这个报销的申请写完了存到数据库当中了还不能算完了，应该和我们的这个流程关联起来啊，那么她应该怎么去关联呢，嘿嘿，是这样地：我们在建立这个申请单这个类的时候应该定义一个processInstanceId属性，她是一个long型的，她就记录这我们的这个流程实例的id，那么什么是流程实例（processInstance）呢，她是我们工作流当中第二重要的概念，他和流程定义的关系就相当于对象和类之间的关系，类是一个抽象的东西，她定义完了是什么也干不了的，要想用她内部定义的东西我们就要new出一个实例来，当然这个里面也是这样的。 <br><br>那么也就是说，当我们创建这个报销申请的时候我们就要先根据这个流程‘new’出一个流程实例来存到数据库当中，然后在把她的id传给报销申请对象然后再将这个报销申请对象存到数据库当中。那么这个代码是这样的： <br>Java代码 <a href="http://www.javaeye.com/topic/193241#" target="_blank"><wbr /><a href="http://www.javaeye.com/images/icon_copy.gif" target="_blank"><img style="border:0;" src="http://www.javaeye.com/images/icon_copy.gif" /></a><wbr /></a><wbr /><br><li style="margin:25px;"><span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">package</span><wbr /></span><wbr /> com.jbpm.test;   </li><li style="margin:25px;">  </li><li style="margin:25px;"><span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">import</span><wbr /></span><wbr /> junit.framework.TestCase;   </li><li style="margin:25px;">  </li><li style="margin:25px;"><span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">import</span><wbr /></span><wbr /> org.hibernate.Session;   </li><li style="margin:25px;">  </li><li style="margin:25px;"><span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">public</span><wbr /></span><wbr /> <span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">class</span><wbr /></span><wbr /> TestJbpm_03 <span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">extends</span><wbr /></span><wbr /> TestCase {   </li><li style="margin:25px;">       </li><li style="margin:25px;">    <span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">public</span><wbr /></span><wbr /> <span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">void</span><wbr /></span><wbr /> testJbpm(){   </li><li style="margin:25px;">        Session session = <span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">null</span><wbr /></span><wbr />;   </li><li style="margin:25px;">        <span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">try</span><wbr /></span><wbr />{   </li><li style="margin:25px;">            session = HibernateUtil.getSession();   </li><li style="margin:25px;">            session.beginTransaction();   </li><li style="margin:25px;">               </li><li style="margin:25px;">            Document doc = <span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">new</span><wbr /></span><wbr /> Document();   </li><li style="margin:25px;">            doc.setTitle(<span style="color:#0000ff;line-height:1.8em;">&quot;title3&quot;</span><wbr />);   </li><li style="margin:25px;">            doc.setContent(<span style="color:#0000ff;line-height:1.8em;">&quot;this is content3&quot;</span><wbr />);   </li><li style="margin:25px;">            session.save(doc);                         </li><li style="margin:25px;">            session.getTransaction().commit();   </li><li style="margin:25px;">        }<span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">catch</span><wbr /></span><wbr />(Exception e){   </li><li style="margin:25px;">            e.printStackTrace();   </li><li style="margin:25px;">            session.getTransaction().rollback();   </li><li style="margin:25px;">        }<span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">finally</span><wbr /></span><wbr />{   </li><li style="margin:25px;">            HibernateUtil.closeSession(session);   </li><li style="margin:25px;">        }   </li><li style="margin:25px;">    }   </li><li style="margin:25px;">}  </li></ol>package com.jbpm.test;import junit.framework.TestCase;import org.hibernate.Session;public class TestJbpm_03 extends TestCase {  public void testJbpm(){  Session session = null;  try{   session = HibernateUtil.getSession();   session.beginTransaction();      Document doc = new Document();   doc.setTitle(&quot;title3&quot;);   doc.setContent(&quot;this is content3&quot;);   session.save(doc);         session.getTransaction().commit();  }catch(Exception e){   e.printStackTrace();   session.getTransaction().rollback();  }finally{   HibernateUtil.closeSession(session);  } }}<br><br>Java代码 <a href="http://www.javaeye.com/topic/193241#" target="_blank"><wbr /><a href="http://www.javaeye.com/images/icon_copy.gif" target="_blank"><img style="border:0;" src="http://www.javaeye.com/images/icon_copy.gif" /></a><wbr /></a><wbr /><br><li style="margin:25px;"><span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">package</span><wbr /></span><wbr /> com.jbpm.test;   </li><li style="margin:25px;">  </li><li style="margin:25px;"><span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">import</span><wbr /></span><wbr /> junit.framework.TestCase;   </li><li style="margin:25px;">  </li><li style="margin:25px;"><span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">import</span><wbr /></span><wbr /> org.jbpm.JbpmConfiguration;   </li><li style="margin:25px;"><span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">import</span><wbr /></span><wbr /> org.jbpm.JbpmContext;   </li><li style="margin:25px;"><span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">import</span><wbr /></span><wbr /> org.jbpm.graph.def.ProcessDefinition;   </li><li style="margin:25px;"><span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">import</span><wbr /></span><wbr /> org.jbpm.graph.exe.ProcessInstance;   </li><li style="margin:25px;">/**   </li><li style="margin:25px;">/*   </li><li style="margin:25px;">/*将申请单和流程实例绑定   </li><li style="margin:25px;">/*   </li><li style="margin:25px;"><span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">public</span><wbr /></span><wbr /> <span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">class</span><wbr /></span><wbr /> TestJbpm_04 <span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">extends</span><wbr /></span><wbr /> TestCase {   </li><li style="margin:25px;">       </li><li style="margin:25px;">    <span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">static</span><wbr /></span><wbr /> JbpmConfiguration jbpmConfiguration = JbpmConfiguration.getInstance();   </li><li style="margin:25px;">       </li><li style="margin:25px;">    <span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">public</span><wbr /></span><wbr /> <span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">void</span><wbr /></span><wbr /> testJbpm(){   </li><li style="margin:25px;">           </li><li style="margin:25px;">        JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();   </li><li style="margin:25px;">        jbpmContext.setSessionFactory(HibernateUtil.getSessionFactory());   </li><li style="margin:25px;">        <span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">try</span><wbr /></span><wbr /> {   </li><li style="margin:25px;">            ProcessDefinition processDefinition = jbpmContext.getGraphSession().findLatestProcessDefinition(<span style="color:#0000ff;line-height:1.8em;">&quot;testJbpm&quot;</span><wbr />);   </li><li style="margin:25px;">            ProcessInstance processInstance = <span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">new</span><wbr /></span><wbr /> ProcessInstance(processDefinition);   </li><li style="margin:25px;">            jbpmContext.save(processInstance);     </li><li style="margin:25px;">               </li><li style="margin:25px;">               </li><li style="margin:25px;">            <span style="color:#008200;line-height:1.8em;">//将我们的document和instance绑定。 </span><wbr />  </li><li style="margin:25px;">            <span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">long</span><wbr /></span><wbr /> processInstanceId = processInstance.getId();   </li><li style="margin:25px;">            Document document = (Document)jbpmContext.getSession().load(Document.<span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">class</span><wbr /></span><wbr />,<span style="color:#c00000;line-height:1.8em;">1</span><wbr />);   </li><li style="margin:25px;">            document.setProcessInstanceId(processInstanceId);   </li><li style="margin:25px;">            jbpmContext.getSession().update(document);   </li><li style="margin:25px;">            processInstance.getContextInstance().setVariable(<span style="color:#0000ff;line-height:1.8em;">&quot;document&quot;</span><wbr />, document.getId());   </li><li style="margin:25px;">        }<span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">catch</span><wbr /></span><wbr />(Exception e){   </li><li style="margin:25px;">            e.printStackTrace();   </li><li style="margin:25px;">        }<span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">finally</span><wbr /></span><wbr />{   </li><li style="margin:25px;">            jbpmContext.close();   </li><li style="margin:25px;">        }   </li><li style="margin:25px;">           </li><li style="margin:25px;">    }   </li><li style="margin:25px;">}  </li></ol>package com.jbpm.test;import junit.framework.TestCase;import org.jbpm.JbpmConfiguration;import org.jbpm.JbpmContext;import org.jbpm.graph.def.ProcessDefinition;import org.jbpm.graph.exe.ProcessInstance;/**/*/*将申请单和流程实例绑定/*public class TestJbpm_04 extends TestCase {  static JbpmConfiguration jbpmConfiguration = JbpmConfiguration.getInstance();  public void testJbpm(){    JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();  jbpmContext.setSessionFactory(HibernateUtil.getSessionFactory());  try {   ProcessDefinition processDefinition = jbpmContext.getGraphSession().findLatestProcessDefinition(&quot;testJbpm&quot;);   ProcessInstance processInstance = new ProcessInstance(processDefinition);   jbpmContext.save(processInstance);           //将我们的document和instance绑定。   long processInstanceId = processInstance.getId();   Document document = (Document)jbpmContext.getSession().load(Document.class,1);   document.setProcessInstanceId(processInstanceId);   jbpmContext.getSession().update(document);   processInstance.getContextInstance().setVariable(&quot;document&quot;, document.getId());  }catch(Exception e){   e.printStackTrace();  }finally{   jbpmContext.close();  }   }}<br><br><br>现在我们的申请已经和实例关联起来了，那么接下来的下一步就开始用啦，就是让这个申请流转起来吧，那么她应该怎么去流转呢，嘿嘿，jbpm给我们提供一个signal方法，每当执行一次这个方法的时候她就流转一下到下一个节点，你可以打印出当前节点试一下，看看是不是执行一次你的当前节点就换一下。这段代码是这样的： <br>Java代码 <a href="http://www.javaeye.com/topic/193241#" target="_blank"><wbr /><a href="http://www.javaeye.com/images/icon_copy.gif" target="_blank"><img style="border:0;" src="http://www.javaeye.com/images/icon_copy.gif" /></a><wbr /></a><wbr /><br><li style="margin:25px;"><span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">package</span><wbr /></span><wbr /> com.jbpm.test;   </li><li style="margin:25px;">  </li><li style="margin:25px;"><span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">import</span><wbr /></span><wbr /> junit.framework.TestCase;   </li><li style="margin:25px;">  </li><li style="margin:25px;"><span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">import</span><wbr /></span><wbr /> org.jbpm.JbpmConfiguration;   </li><li style="margin:25px;"><span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">import</span><wbr /></span><wbr /> org.jbpm.JbpmContext;   </li><li style="margin:25px;"><span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">import</span><wbr /></span><wbr /> org.jbpm.graph.exe.ProcessInstance;   </li><li style="margin:25px;">  </li><li style="margin:25px;"><span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">public</span><wbr /></span><wbr /> <span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">class</span><wbr /></span><wbr /> TestJbpm_05 <span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">extends</span><wbr /></span><wbr /> TestCase {   </li><li style="margin:25px;">       </li><li style="margin:25px;">    <span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">static</span><wbr /></span><wbr /> JbpmConfiguration jbpmConfiguration = JbpmConfiguration.getInstance();   </li><li style="margin:25px;">       </li><li style="margin:25px;">    <span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">public</span><wbr /></span><wbr /> <span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">void</span><wbr /></span><wbr /> testJbpm(){   </li><li style="margin:25px;">        JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();   </li><li style="margin:25px;">        jbpmContext.setSessionFactory(HibernateUtil.getSessionFactory());   </li><li style="margin:25px;">        <span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">try</span><wbr /></span><wbr />{   </li><li style="margin:25px;">               </li><li style="margin:25px;">            Document document = (Document)jbpmContext.getSession().load(Document.<span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">class</span><wbr /></span><wbr />, <span style="color:#c00000;line-height:1.8em;">3</span><wbr />);   </li><li style="margin:25px;">            <span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">long</span><wbr /></span><wbr /> processInstanceId = document.getProcessInstanceId();   </li><li style="margin:25px;">            ProcessInstance processInstance = jbpmContext.getProcessInstance(processInstanceId);   </li><li style="margin:25px;">            processInstance.signal();   </li><li style="margin:25px;">        }<span style="font-weight:bold"><wbr /><span style="color:#7f0055;line-height:1.8em;">finally</span><wbr /></span><wbr />{   </li><li style="margin:25px;">            jbpmContext.close();   </li><li style="margin:25px;">        }   </li><li style="margin:25px;">    }   </li><li style="margin:25px;">}  </li></ol>package com.jbpm.test;import junit.framework.TestCase;import org.jbpm.JbpmConfiguration;import org.jbpm.JbpmContext;import org.jbpm.graph.exe.ProcessInstance;public class TestJbpm_05 extends TestCase {  static JbpmConfiguration jbpmConfiguration = JbpmConfiguration.getInstance();  public void testJbpm(){  JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();  jbpmContext.setSessionFactory(HibernateUtil.getSessionFactory());  try{      Document document = (Document)jbpmContext.getSession().load(Document.class, 3);   long processInstanceId = document.getProcessInstanceId();   ProcessInstance processInstance = jbpmContext.getProcessInstance(processInstanceId);   processInstance.signal();  }finally{   jbpmContext.close();  } }}<br><br><br>好啦，jbpm的简单例子就到这里了，有什么问题大家可以给我留留言，还请大家多多指教小弟啊。后面我还会写点更具体的一些问题，比如说列出提交到这个人这还没有审批的公文啊，还有如果有多个分支的话应该怎么去做啊等等等等。 <br> <!--v:3.2--> ]]></description>
<category><![CDATA[个人日记]]></category>
<author><![CDATA[344867279@qq.com(/tp鳎毪鍪蕾)]]></author>
<comments>http://344867279.qzone.qq.com/blog/1231127108#comment</comments>
<qz:effect>134218241</qz:effect>
<pubDate>Mon, 05 Jan 2009 03:45:08 GMT</pubDate>
<guid>http://344867279.qzone.qq.com/blog/1231127108</guid>
</item>

<item>
<title><![CDATA[jbpm开发实例（一）]]></title>
<link>http://344867279.qzone.qq.com/blog/1231127079</link>
<description><![CDATA[ 前几天发了一篇文章，没几个人看也没人留言，看来我这功夫差的还是远啊，今天来一个实际点的吧。可能上回的废话太多。说说这个jbpm应该怎么来用。 <br><br>    首先当你想学一个框架的时候一定是你要有项目来用他了，OK，那么你项目当中的流程是什么你应该清楚吧，那么当你清楚了这些的时候我们就开始我们这个最简单的例子吧。 <br><br>    假如我们现在有这么一个例子，公司员工想报销点出差费，那么他要将他的申请提交给他的第一级领导——部门主管去审批，然后部门主管审批完了之后还要交给这个部门主管的上级公司老总进行审批。那么针对这个简单的流程，我们应该从哪里下手呢？ <br><br>    首先第一件事情就是写流程定义文件，那么这个文件我们用什么来写呢，他就是一个符合某个语法的xml文件，幸运的是jbpm给我们提供了一个集成的开发环境让我们来用。 <br><br>    首先去官网上下一个jbpm-jpdl-suite-3.2.GA包，解压后你会发现他里面有一个designer文件夹，那个里面就是我们写流程定义文件的开发环境，他是一个eclipse的插件，但是好像他给我们的那个eclipse版本有问题，建议大家从新下一个eclipse-SDK-3.2.1-win32.zip这个版本的eclipse，然后覆盖他给我们提供的那个。 <br><br>    准备工作做完了，那么我们就开始吧，首先我们打开解压目录下的designer文件夹中的designer.bat文件，他弹出一个eclipse，然后我们就用这个东西来开发我们的流程定义文件了。 <br><br>    打开之后你就会看见一个他的小例子，不过我们不去用他，我们自己新建一个工程。右键-new-other-jBoss jbpm-process project。这个时候你会看见他弹出一个对话框，输入你的工程名字，然后点击next，这个时候你会发现他已经把jbpm加载进去了，记住要选中Generate simple ......。 <br><br>    工程建立完了，我们开始建立我们的流程定义文件。在工程里面你会发现src/main/jpdl这个source folder，然后你会看见他里面已经有了一个流程定义文件了，但是我们不去用他的，我们自己建立一个，右键src/main/jpdl，然后new-other-jBoss jbpm-process definition。这个时候他就会弹出一个对话框，起一个你要写的流程定义文件的名字输入进去，OK，可以了。这个时候你打开你建立的那个文件夹，里面就有processdefinition.xml文件，ok，打开他。 <br><br>    在右面的图里面你就可以看到一张什么都没有的白纸，我们看看这部分左面的那些东西，什么start啊，end啊，tasknode啊，fork啊，join啊。那我们来解释一下这是个什么东西呢，我们看看我们的需求，员工要写一个报销单，然后交给部门主管来处理，那么部门主管就应该算是一个tasknode，他就是一个任务节点。start和end其实就是一个虚状态，当我们写完报销单的时候我们就提交了，这个时候他就到了第一个tasknode这个节点了。然后他审批完了还要交给总经理审批，那么他又是一个tasknode，然后总经理审批完了结束，ok，是一个end。 <br><br>    start--》tasknode（部门主管审批）--》tasknode（总经理审批）--》end。 <br><br> <!--v:3.2--> ]]></description>
<category><![CDATA[个人日记]]></category>
<author><![CDATA[344867279@qq.com(/tp鳎毪鍪蕾)]]></author>
<comments>http://344867279.qzone.qq.com/blog/1231127079#comment</comments>
<qz:effect>134218240</qz:effect>
<pubDate>Mon, 05 Jan 2009 03:44:39 GMT</pubDate>
<guid>http://344867279.qzone.qq.com/blog/1231127079</guid>
</item>

<item>
<title><![CDATA[权限管理数据表设计说明]]></title>
<link>http://344867279.qzone.qq.com/blog/1224474632</link>
<description><![CDATA[B/S系统中的权限比C/S中的更显的重要，C/S系统因为具有特殊的客户端，所以访问用户的权限检测可以通过客户端实现或通过客户端+服务器检测实现，而B/S中，浏览器是每一台计算机都已具备的，如果不建立一个完整的权限检测，那么一个“非法用户”很可能就能通过浏览器轻易访问到B/S系统中的所有功能。因此B/S业务系统都需要有一个或多个权限系统来实现访问权限检测，让经过授权的用户可以正常合法的使用已授权功能，而对那些未经授权的“非法用户”将会将他们彻底的“拒之门外”。下面就让我们一起了解一下如何设计可以满足大部分B/S系统中对用户功能权限控制的权限系统。 <br> <br><span style="font-weight:bold"><wbr />需求陈述</span><wbr /><br><ul style="list-style-type:disc"><li style="margin:25px;"><span style="font-weight:bold"><wbr />不同职责的人员，对于系统操作的权限应该是不同的。</span><wbr />优秀的业务系统，这是最基本的功能。<br> <br><li style="margin:25px;"><span style="font-weight:bold"><wbr />可以对“组”进行权限分配</span><wbr />。对于一个大企业的业务系统来说，如果要求管理员为其下员工逐一分配系统操作权限的话，是件耗时且不够方便的事情。所以，系统中就提出了对“组”进行操作的概念，将权限一致的人员编入同一组，然后对该组进行权限分配。<br> <br><li style="margin:25px;"><span style="font-weight:bold"><wbr />权限管理系统应该是可扩展的</span><wbr />。它应该可以加入到任何带有权限管理功能的系统中。就像是组件一样的可以被不断的重用，而不是每开发一套管理系统，就要针对权限管理部分进行重新开发。<br> <br><li style="margin:25px;"><span style="font-weight:bold"><wbr />满足业务系统中的功能权限。</span><wbr />传统业务系统中，存在着两种权限管理，其一是功能权限的管理，而另外一种则是资源权限的管理，在不同系统之间，功能权限是可以重用的，而资源权限则不能。<br></li></ul><span style="font-weight:bold"><wbr />关于设计</span><wbr /><br><span style="font-weight:bold"><wbr /><span style="font-size:10px;line-height:1.8em;">　　</span><wbr /></span><wbr />借助NoahWeb的动作编程理念，在设计阶段，系统设计人员无须考虑程序结构的设计，而是从程序流程以及数据库结构开始入手。为了实现需求，数据库的设计可谓及其重要，无论是“组”操作的概念，还是整套权限管理系统的重用性，都在于数据库的设计。<br>我们先来分析一下数据库结构：<br><span style="font-weight:bold"><wbr /><span style="font-size:10px;line-height:1.8em;">　　</span><wbr /></span><wbr />首先，action表（<span style="font-weight:bold"><wbr />以下简称为“权限表”</span><wbr />），gorupmanager表（<span style="font-weight:bold"><wbr />以下简称为“管理组表”</span><wbr />），以及master表（<span style="font-weight:bold"><wbr />以下简称为“人员表”</span><wbr />），是三张实体表，它们依次记录着“权限”的信息，“管理组”的信息和“人员”的信息。如下图：<br><div style="text-align:center;"><wbr /><a href="http://www.noahweb.net/mail/2/16.gif" target="_blank"><img style="width:460px;height:328px;border:0;" src="http://www.noahweb.net/mail/2/16.gif" /></a><wbr /></div><span style="font-weight:bold"><wbr /><span style="font-size:10px;line-height:1.8em;">　　</span><wbr /></span><wbr />这三个表之间的关系是多对多的，一个权限可能同时属于多个管理组，一个管理组中也可能同时包含多个权限。同样的道理，一个人员可能同时属于多个管理组，而一个管理组中也可能同时包含多个人员。如下图：<br><div style="text-align:center;"><wbr /><a href="http://www.noahweb.net/mail/2/1.gif" target="_blank"><img style="width:456px;height:321px;border:0;" src="http://www.noahweb.net/mail/2/1.gif" /></a><wbr /></div><span style="font-weight:bold"><wbr /><span style="font-size:10px;line-height:1.8em;">　　</span><wbr /></span><wbr />由于这三张表之间存在着多对多的关系，那么它们之间的交互，最好使用另外两张表来完成。而这两张表起着映射的作用，分别是“actiongroup”表<span style="font-weight:bold"><wbr />（以下简称“权限映射表”）</span><wbr />和“mastergroup”表<span style="font-weight:bold"><wbr />（以下简称“人员映射表”）</span><wbr />，前者映射了权限表与管理组表之间的交互。后者映射了人员表与管理组表之间的交互。如下图：<br><div style="text-align:center;"><wbr /><a href="http://www.noahweb.net/mail/2/15.gif" target="_blank"><img style="width:637px;height:318px;border:0;" src="http://www.noahweb.net/mail/2/15.gif" /></a><wbr /></div><span style="font-weight:bold"><wbr /><span style="font-size:10px;line-height:1.8em;">　　</span><wbr /></span><wbr />另外，还需要一张表来控制系统运行时左侧菜单中的权限分栏，也就是“权限分栏表”，如下图：<br><div style="text-align:center;"><wbr /><a href="http://www.noahweb.net/mail/2/17.gif" target="_blank"><img style="width:637px;height:318px;border:0;" src="http://www.noahweb.net/mail/2/17.gif" /></a><wbr /></div><span style="font-weight:bold"><wbr /><span style="font-size:10px;line-height:1.8em;">　　</span><wbr /></span><wbr />根据上面的分析，我们进行数据库结构设计，如下图：<br>　　<a href="http://www.noahweb.net/mail/2/Project.htm#biao" target="_blank">点击这里查看权限管理系统数据表字段设计</a><wbr /><br><div style="text-align:center;"><wbr /><a href="http://www.noahweb.net/mail/2/datebase.gif" target="_blank"><img style="width:624px;height:320px;border:0;" src="http://www.noahweb.net/mail/2/datebase.gif" /></a><wbr /></div> <br><span style="font-weight:bold"><wbr /><span style="font-size:10px;line-height:1.8em;">　　</span><wbr /></span><wbr />为了能够进行良好的分析，我们将数据库结构图拆分开来，三张实体表的作用已经很清晰，现在我们来看一下两张映射表的作用。<br><span style="font-weight:bold"><wbr />一 权限映射表</span><wbr /> 如下图：<br><span style="font-weight:bold"><wbr /><span style="font-size:10px;line-height:1.8em;">　　</span><wbr /></span><wbr />首先，我们来了解一下<span style="font-weight:bold"><wbr />权限映射表</span><wbr />与<span style="font-weight:bold"><wbr />管理组表</span><wbr />以及<span style="font-weight:bold"><wbr />权限表</span><wbr />之间的字段关联。<br><div style="text-align:center;"><wbr /><a href="http://www.noahweb.net/mail/2/6.gif" target="_blank"><img style="width:457px;height:159px;border:0;" src="http://www.noahweb.net/mail/2/6.gif" /></a><wbr /></div><span style="font-weight:bold"><wbr /><span style="font-size:10px;line-height:1.8em;">　　</span><wbr /></span><wbr />看图中的红圈，先看gorupid字段相关联，这种关联方式在实际数据库中的表现如下图：<br><div style="text-align:center;"><wbr /><a href="http://www.noahweb.net/mail/2/3.gif" target="_blank"><img style="width:534px;height:152px;border:0;" src="http://www.noahweb.net/mail/2/3.gif" /></a><wbr /></div><span style="font-weight:bold"><wbr /><span style="font-size:10px;line-height:1.8em;">　　</span><wbr /></span><wbr />如图中所示，<span style="font-weight:bold"><wbr />管理组表</span><wbr />中“超级管理员”的groupid为1，那么<span style="font-weight:bold"><wbr />权限映射表</span><wbr />中groupid为1的权限也就是“超级管理员”所拥有的权限。<br><span style="font-weight:bold"><wbr /><span style="font-size:10px;line-height:1.8em;">　　</span><wbr /></span><wbr />使用groupid字段关联，是为了查到一个管理组能够执行的权限有哪些。但这些权限的详细信息却是action字段关联所查询到的。<br><span style="font-weight:bold"><wbr /><span style="font-size:10px;line-height:1.8em;">　　</span><wbr /></span><wbr />action字段相关联在数据库中的表现如下图：<br><div style="text-align:center;"><wbr /><a href="http://www.noahweb.net/mail/2/5.gif" target="_blank"><img style="width:540px;height:154px;border:0;" src="http://www.noahweb.net/mail/2/5.gif" /></a><wbr /></div><span style="font-weight:bold"><wbr /><span style="font-size:10px;line-height:1.8em;">　　</span><wbr /></span><wbr />通过这种关联，才查询到<span style="font-weight:bold"><wbr />权限映射表</span><wbr />之中那些权限的详细信息。综合起来，我们就知道了一个管理组可以执行的权限有哪些，以及这些权限的详细信息是什么。<br><span style="font-weight:bold"><wbr /><span style="font-size:10px;line-height:1.8em;">　　</span><wbr /></span><wbr />或许你会问，为什么不使用actionid字段相关联呢？因为：<br><ul style="list-style-type:disc"><li style="margin:25px;"><span style="font-weight:bold"><wbr />权限表</span><wbr />中的id字段在经过多次的数据库操作之后可能会发生更改。<br><li style="margin:25px;"><span style="font-weight:bold"><wbr />权限映射表</span><wbr />中仅仅记录着一个管理组可以执行的权限。<br><li style="margin:25px;">一旦<span style="font-weight:bold"><wbr />权限表</span><wbr />中的id更改，那么<span style="font-weight:bold"><wbr />权限映射表</span><wbr />中的记录也就更改了。<br><li style="margin:25px;">一个管理组可以执行的权限势必将出错，这是非常不希望的。<br></li></ul><span style="font-weight:bold"><wbr /><span style="font-size:10px;line-height:1.8em;">　　</span><wbr /></span><wbr />考虑到上面的情况，所以应该使用action字段相关联，因为：<br><ul style="list-style-type:disc"><li style="margin:25px;">在<span style="font-weight:bold"><wbr />权限表</span><wbr />中，id可能发生变化，而action字段却是在任何情况下也不可能发生变化的。<br><li style="margin:25px;"><span style="font-weight:bold"><wbr />权限映射表</span><wbr />中记录的action字段也就不会变。<br><li style="margin:25px;">一个管理组可以执行的权限就不会出错了。<br></li></ul><span style="font-weight:bold"><wbr />二 人员映射表</span><wbr /> 如下图：<br><span style="font-weight:bold"><wbr /><span style="font-size:10px;line-height:1.8em;">　　</span><wbr /></span><wbr />我们来了解一下<span style="font-weight:bold"><wbr />人员映射表</span><wbr />与<span style="font-weight:bold"><wbr />管理组表</span><wbr />以及<span style="font-weight:bold"><wbr />人员表</span><wbr />之间的字段关联，如下图：<br><div style="text-align:center;"><wbr /><a href="http://www.noahweb.net/mail/2/13.gif" target="_blank"><img style="width:442px;height:324px;border:0;" src="http://www.noahweb.net/mail/2/13.gif" /></a><wbr /></div> <br><span style="font-weight:bold"><wbr /><span style="font-size:10px;line-height:1.8em;">　　</span><wbr /></span><wbr />看图中的红圈部分，先看groupid字段关联，这种关联方式在数据库中的表现如下图：<br><div style="text-align:center;"><wbr /><a href="http://www.noahweb.net/mail/2/10.gif" target="_blank"><img style="width:437px;height:109px;border:0;" src="http://www.noahweb.net/mail/2/10.gif" /></a><wbr /></div><span style="font-weight:bold"><wbr /><span style="font-size:10px;line-height:1.8em;">　　</span><wbr /></span><wbr />如图，“超级管理员”组的groupid为1，我们再看<span style="font-weight:bold"><wbr />人员映射表</span><wbr />，admin属于超级管理员组，而administrator属于超级管理员组，同时也属于管理员组。<br><span style="font-weight:bold"><wbr /><span style="font-size:10px;line-height:1.8em;">　　</span><wbr /></span><wbr />使用这种关联方式，是为了查到一个管理组中的人员有谁。和上面一样，人员的详细信息是靠id字段（<span style="font-weight:bold"><wbr />人员映射表</span><wbr />中是masterid字段）关联查询到的。<br><span style="font-weight:bold"><wbr /><span style="font-size:10px;line-height:1.8em;">　　</span><wbr /></span><wbr />id字段（<span style="font-weight:bold"><wbr />人员映射表</span><wbr />中是masterid字段）关联表现在数据库中的形式如下图：<br><div style="text-align:center;"><wbr /><a href="http://www.noahweb.net/mail/2/12.gif" target="_blank"><img style="width:526px;height:108px;border:0;" src="http://www.noahweb.net/mail/2/12.gif" /></a><wbr /></div><span style="font-weight:bold"><wbr /><span style="font-size:10px;line-height:1.8em;">　　</span><wbr /></span><wbr />一个人员可能同时属于多个“管理组”，如图中，administrator就同时属于两个“管理组”。所以，在<span style="font-weight:bold"><wbr />人员映射表</span><wbr />中关于administrator的记录就会是两条。<br><span style="font-weight:bold"><wbr /><span style="font-size:10px;line-height:1.8em;">　　</span><wbr /></span><wbr />这种关联方式才查询到管理组中人员的详细信息有哪些。综合起来，才可以知道一个管理组中的人员有谁，以及这个人员的详细信息。<br><span style="font-weight:bold"><wbr /><span style="font-size:10px;line-height:1.8em;">　　</span><wbr /></span><wbr />再结合上面谈到的<span style="font-weight:bold"><wbr />权限表</span><wbr />和<span style="font-weight:bold"><wbr />权限映射表</span><wbr />，就实现了需求中的“组”操作，如下图：<br><div style="text-align:center;"><wbr /><a href="http://www.noahweb.net/mail/2/14.gif" target="_blank"><img style="width:636px;height:323px;border:0;" src="http://www.noahweb.net/mail/2/14.gif" /></a><wbr /></div><span style="font-weight:bold"><wbr /><span style="font-size:10px;line-height:1.8em;">　　</span><wbr /></span><wbr />其实，<span style="font-weight:bold"><wbr />管理组表</span><wbr />中仅仅记录着组的基本信息，如名称，组id等等。至于一个组中人员的详细信息，以及该组能够执行的权限的详细信息，都记录在<span style="font-weight:bold"><wbr />人员表</span><wbr />和<span style="font-weight:bold"><wbr />权限表</span><wbr />中。两张<span style="font-weight:bold"><wbr />映射表</span><wbr />才真正记录着一个组有哪些人员，能够执行哪些权限。通过两张映射表的衔接，三张实体表之间的交互才得以实现，<span style="font-weight:bold"><wbr />从而完成了需求中提到的“组”操作</span><wbr />。<br><span style="font-weight:bold"><wbr /><span style="font-size:10px;line-height:1.8em;">　　</span><wbr /></span><wbr />我们再来看一下<span style="font-weight:bold"><wbr />权限分栏表</span><wbr />与<span style="font-weight:bold"><wbr />权限表</span><wbr />之间的交互。这两张表之间的字段关联如下图：<br><div style="text-align:center;"><wbr /><a href="http://www.noahweb.net/mail/2/19.gif" target="_blank"><img style="width:334px;height:142px;border:0;" src="http://www.noahweb.net/mail/2/19.gif" /></a><wbr /></div><span style="font-weight:bold"><wbr /><span style="font-size:10px;line-height:1.8em;">　　</span><wbr /></span><wbr />两张表使用了actioncolumnid字段相关联，这种关联方式在数据库中的表现如下图：<br><div style="text-align:center;"><wbr /><a href="http://www.noahweb.net/mail/2/18.gif" target="_blank"><img style="width:531px;height:363px;border:0;" src="http://www.noahweb.net/mail/2/18.gif" /></a><wbr /></div><span style="font-weight:bold"><wbr /><span style="font-size:10px;line-height:1.8em;">　　</span><wbr /></span><wbr />如图所示，通过这种关联方式，我们可以非常清晰的看到<span style="font-weight:bold"><wbr />权限表</span><wbr />中的权限属于哪个分栏。<br><span style="font-weight:bold"><wbr /><span style="font-size:10px;line-height:1.8em;">　　</span><wbr /></span><wbr />现在，数据库结构已经很清晰了，分配权限的功能以及“组”操作都已经实现。下面我们再来分析一下需求中提到的关于权限管理系统的重用性问题。<br><span style="font-weight:bold"><wbr /><span style="font-size:10px;line-height:1.8em;">　　</span><wbr /></span><wbr />为什么使用这种数据库设计方式搭建起来的系统可以重用呢？<br><ul style="list-style-type:disc"><li style="margin:25px;"><span style="font-weight:bold"><wbr />三张实体表中记录着系统中的三个决定性元素。</span><wbr />“权限”，“组”和“人”。而这三种元素可以任意添加，彼此之间不受影响。无论是那种类型的业务系统，这三个决定性元素是不会变的，也就意味着结构上不会变，而变的仅仅是数据。<br><li style="margin:25px;"><span style="font-weight:bold"><wbr />两张映射表中记录着三个元素之间的关系。</span><wbr />但这些关系完全是人为创建的，需要变化的时候，只是对数据库中的记录进行操作，无需改动结构。<br><li style="margin:25px;"><span style="font-weight:bold"><wbr />权限分栏表中记录着系统使用时显示的分栏</span><wbr />。无论是要添加分栏，修改分栏还是减少分栏，也只不过是操作记录而已。<br></li></ul><span style="font-weight:bold"><wbr /><span style="font-size:10px;line-height:1.8em;">　　</span><wbr /></span><wbr />综上所述，这样设计数据库，系统是完全可以重用的，并且经受得住“变更”考验的。<br><span style="font-weight:bold"><wbr />总结：</span><wbr /><br><span style="font-weight:bold"><wbr /><span style="font-size:10px;line-height:1.8em;">　　</span><wbr /></span><wbr />此套系统的重点在于，三张<span style="font-weight:bold"><wbr />实体表</span><wbr />牢牢地抓住了系统的核心成分，而两张映射表完美地映射出三张实体表之间的交互。其难点在于，理解映射表的工作，它记录着关系，并且实现了“组”操作的概念。而系统总体的设计是本着可以在不同的MIS系统中“重用”来满足不同系统的功能权限设置。<br><span style="font-weight:bold"><wbr />附录：</span><wbr /><br><div style="text-align:center;"><span style="font-weight:bold"><wbr />权限管理系统数据表的字段设计</span><wbr /></div><span style="font-weight:bold"><wbr /><span style="font-size:10px;line-height:1.8em;">　　</span><wbr /></span><wbr />下面我们来看看权限管理系统的数据库表设计，共分为六张表，如下图：<br>action表：<br><div style="text-align:center;"><span style="font-style:italic"><wbr /><wbr /><a href="http://www.noahweb.net/mail/2/datebase1.gif" target="_blank"><img style="width:502px;height:119px;border:0;" src="http://www.noahweb.net/mail/2/datebase1.gif" /></a><wbr /></span><wbr /></div><span style="font-weight:bold"><wbr /><span style="font-size:10px;line-height:1.8em;">　　</span><wbr /></span><wbr />action表中记录着系统中所有的动作，以及动作相关描述。<br>actioncolumn表：<br><div style="text-align:center;"><wbr /><a href="http://www.noahweb.net/mail/2/datebase2.gif" target="_blank"><img style="width:459px;height:75px;border:0;" src="http://www.noahweb.net/mail/2/datebase2.gif" /></a><wbr /></div><span style="font-weight:bold"><wbr /><span style="font-size:10px;line-height:1.8em;">　　</span><wbr /></span><wbr />actioncolumn表中记录着动作的分栏，系统运行时，左侧菜单栏提供了几块不同的功能，每一块就是一个分栏，每添加一个分栏，该表中的记录就会增加一条,相对应的，左侧菜单栏中也会新增机一个栏。<br>actiongroup表：<br><div style="text-align:center;"><wbr /><a href="http://www.noahweb.net/mail/2/datebase3.gif" target="_blank"><img style="width:498px;height:135px;border:0;" src="http://www.noahweb.net/mail/2/datebase3.gif" /></a><wbr /></div><span style="font-weight:bold"><wbr /><span style="font-size:10px;line-height:1.8em;">　　</span><wbr /></span><wbr />actiongroup表记录着动作所在的组。<br>groupmanager表：<br><div style="text-align:center;"><wbr /><a href="http://www.noahweb.net/mail/2/datebase4.gif" target="_blank"><img style="width:405px;height:135px;border:0;" src="http://www.noahweb.net/mail/2/datebase4.gif" /></a><wbr /></div><span style="font-weight:bold"><wbr /><span style="font-size:10px;line-height:1.8em;">　　</span><wbr /></span><wbr />groupmanager表记录着管理组的相关信息，每添加一个管理组，这里的记录就会增加一条。<br>mastergroup表：<br><div style="text-align:center;"><wbr /><a href="http://www.noahweb.net/mail/2/datebase6.gif" target="_blank"><img style="width:444px;height:150px;border:0;" src="http://www.noahweb.net/mail/2/datebase6.gif" /></a><wbr /></div><span style="font-weight:bold"><wbr /><span style="font-size:10px;line-height:1.8em;">　　</span><wbr /></span><wbr />mastergroup表记录着管理员所在的管理组，由于一名管理员可能同同时属于多个组，所以该表中关于某一名管理员的记录可能有多条。<br>master表：<br><div style="text-align:center;"><wbr /><a href="http://www.noahweb.net/mail/2/datebase5.gif" target="_blank"><img style="width:409px;height:300px;border:0;" src="http://www.noahweb.net/mail/2/datebase5.gif" /></a><wbr /></div><span style="font-weight:bold"><wbr /><span style="font-size:10px;line-height:1.8em;">　　</span><wbr /></span><wbr />master表记录着所有管理员的信息，每添加一个管理员，该表就会增加一条记录。 <!--v:3.2--> ]]></description>
<category><![CDATA[个人日记]]></category>
<author><![CDATA[344867279@qq.com(/tp鳎毪鍪蕾)]]></author>
<comments>http://344867279.qzone.qq.com/blog/1224474632#comment</comments>
<qz:effect>134218241</qz:effect>
<pubDate>Mon, 20 Oct 2008 03:50:32 GMT</pubDate>
<guid>http://344867279.qzone.qq.com/blog/1224474632</guid>
</item>

<item>
<title><![CDATA[系统权限设计]]></title>
<link>http://344867279.qzone.qq.com/blog/1224474552</link>
<description><![CDATA[本文提供一种集成功能权限和数据权限的解决方法，以满足多层次组织中权限管理方面的集中控制。本方法是RBAC（基于角色的访问控制方法）的进一步扩展和延伸，即在功能权限的基础上增加数据权限的管理，实现数据权限和功能权限的集中处理。 <br><br><br><br>通用数据权限管理系统设计（一） <br>前言： <br>本文提供一种集成功能权限和数据权限的解决方法，以满足多层次组织中权限管理方面的集中控制。本方法是RBAC（基于角色的访问控制方法）的进一步扩展和延伸，即在功能权限的基础上增加数据权限的管理，实现数据权限和功能权限的集中处理。 <br>解释： <br>功能权限：能做什么的问题，如增加销售订单； <br>数据权限：能在哪里干什么的问题，如察看北京分公司海淀销售部张三的销售订单； <br>术语： <br>资源：系统中的资源，主要是各种业务对象，如销售单、付款单等； <br>操作类型：对资源可能的访问方法，如增加、删除、修改等； <br>功能：对资源的操作，是资源与操作类型的二元组，如增加销售单、修改销售单等； <br>数据类型：业务系统中常用的数据权限类型，如公司、部门、项目、个人等； <br>数据对象：具体的业务对象，如甲公司、乙部门等等，包括所有涉及到数据权限的对象值； <br>权限：角色可使用的功能，分角色的功能权限和角色的数据权限； <br>角色：特定权限的集合； <br>用户：参与系统活动的主体，如人，系统等。 <br>通用数据权限管理系统设计（二） <br>方法说明： <br>在实际应用中，数据权限的控制点一般相对固定，如针对公司、部门、个人、客户、供应商等，也就是说数据权限一般针对指定数据类型下的一些数据对象。 <br>本方法中，数据权限的依赖于功能权限，是对功能权限的进一步描述，说明角色在指定的功能点上的数据控制权限。 <br>本方法中采用“没有明确规定即视为有效”的原则，如果没有定义功能的数据权限，则说明该角色具有该功能的全部的权限。如果定义了功能的某种类型的数据权限，则该用户只具有该类型下指定数据的数据权限。 <br>这段话比较绕口，下面举个例子实际例子。 <br>某公司有北京销售部、上海销售部和广州销售部三个销售部，现在需要定义几种角色： <br>    销售总监        -- 能察看所有销售部的销售订单； <br>    北京销售经理 -- 只能察看北京销售部的所有销售订单； <br>    上海销售经理 -- 只能察看上海销售部的所有销售订单；   <br>    广州销售经理 -- 只能察看广州销售部的所有销售订单；   <br>上述角色的定义如下： <br>       ------------------------------------------------------------------- <br>     角色名称             功能             数据类型     数据对象   <br>       ------------------------------------------------------------------- <br>     销售总监           察看销售订单                                  <br>     北京销售经理       察看销售订单         部门         北京   <br>     上海销售经理       察看销售订单         部门         上海      <br>     广州销售经理       察看销售订单         部门         广州      <br>       ------------------------------------------------------------------- <br>    上述定义中，销售总监只定义了功能权限，而没有定义数据权限，所以销售总监能够察看所有的销售订单；而其他几位销售经理分别定义了这一功能的数据权限，所以只能察看指定部门的销售订单。 <br>     在实际应用中，往往会出现部门分组，组长能够察看本组所有人员处理的销售订单的情况，以及某些情况下，某些人只能察看本人的销售订单的情况，这些特殊情况在上述的说明中无法解决，需要在设计和实现中进行处理。 <br>    北京销售代表 -- 只能察看北京销售部的本人的所有销售订单；   <br>     北京销售代表         察看销售订单           部门            北京      <br>                                                 个人                   <br>通用数据权限管理系统设计（三）--数据库设计 <br>我们先来看看传统的基于角色的权限管理系统，如下图所示，最简单的基于角色的权限管理由系统功能、系统角色、系统用户、角色功能和用户角色五部分组成。 <br><br><wbr /><a href="http://p.blog.csdn.net/images/p_blog_csdn_net/fly_cloud/role_based.gif" target="_blank"><img style="border:0;" src="http://p.blog.csdn.net/images/p_blog_csdn_net/fly_cloud/role_based.gif" /></a><wbr /> <br>      图一：基于角色的数据库结构 <br><br>为实现数据权限控制，在设计上对基于角色的权限管理进行扩充，如下图所示： <br><wbr /><a href="http://p.blog.csdn.net/images/p_blog_csdn_net/fly_cloud/dat_based.gif" target="_blank"><img style="width:700px;height:485px;border:0;" src="http://p.blog.csdn.net/images/p_blog_csdn_net/fly_cloud/dat_based.gif" /></a><wbr /> <br>图二：通用数据权限管理系统数据库设计 <br>对比两张图，我们可以看到，他们之间的主要变化为： <br>1、 增加系统资源信息和操作类型信息，系统资源为树形结构、如销售模块、销售订单等；操作类型记录可能的操作，如增加、删除、修改、查看、查询等，系统功能是资源与操作类型的组合，对资源的操作就是系统功能。 <br>2、 增加数据对象类型和数据对象两张表，数据对象类型记录系统中需要控制的对象类型，如部门、库房、员工、客户、供应商等；数据对象记录各对象类型的对象实例，如北京销售部、上海销售部、张三、李四等等。（独立保存的好处后面会说到） <br>3、 增加系统资源与数据对象类型的关联表（多对多），本表为配置表，说明某种资源可能需要的控制点，如销售订单与部门类型的关联可能涉及到分部门分配权限；销售订单与客户的关联可能涉及到按客户分配权限等等。 <br>4、 增加数据对象与角色权限的关联，这张表是真正最终实现数据权限管理的所在地。 <br>通过这种设计，能够最小化地减少对原有权限系统的更改，并且可以很灵活地增加数据的控制点。在产品化软件的设计中使用，能够灵活满足客户的需要。 <!--v:3.2--> ]]></description>
<category><![CDATA[个人日记]]></category>
<author><![CDATA[344867279@qq.com(/tp鳎毪鍪蕾)]]></author>
<comments>http://344867279.qzone.qq.com/blog/1224474552#comment</comments>
<qz:effect>134218241</qz:effect>
<pubDate>Mon, 20 Oct 2008 03:49:12 GMT</pubDate>
<guid>http://344867279.qzone.qq.com/blog/1224474552</guid>
</item>

<item>
<title><![CDATA[什么是RSS?RSS用来做什么?怎样实现RSS功能？]]></title>
<link>http://344867279.qzone.qq.com/blog/1214175638</link>
<description><![CDATA[RSS是站点用来和其他站点之间共享内容的一种简易方式（也叫聚合内容）   <br><br>在门户网站大行其道，人们已经习惯通过搜索引擎来获取新闻资讯的今天，一种全新的资讯传播方式已经悄悄地来到我们身边，仔细观察一些网站，你可能注意到一些被标记为&quot;XML&quot;或&quot;RSS&quot;的橙色图标。  <br><br>面对扑面而来的新闻，不用再花费大量的时间冲浪和从新闻网站下载，只要通过下载或购买一种小程序，这种技术被称为简易信息聚合（RSS：Really Simple Syndication）。RSS会收集和组织定制的新闻，按照你希望的格式、地点、时间和方式，直接传送到你的计算机上。新闻网站和那些在线日记作者已体会到了RSS提要带来的乐趣，这也使读者可以更容易跟踪RSS提要。<br><br>RSS是一个缩写的英文术语，在英文中被认为有几个不同的源头，并被不同的技术团体做不同的解释。它既可以是&quot;Rich Site Summary&quot;（丰富站点摘要），或&quot;RDF Site Summary&quot;（RDF站点摘要），也可以是&quot;Really Simple Syndication&quot;（真正简易聚合）。现在已有的有Netscape, 1.0 (RSS-DEV版本),和 0.9x and 2.0 (UserLand Software版本) 0.9x和2.0。不过几乎所有能支持RSS的程序都可以浏览不同版本的RSS。   <br><br>RSS是基于文本的格式。它是XML（可扩展标识语言）的一种形式。通常RSS文件都是标为XML，RSS files(通常也被称为RSS feeds或者channels)通常只包含简单的项目列表。一般而言，每一个项目都含有一个标题，一段简单的介绍，还有一个URL链接（比如是一个网页的地址）。其他的信息，例如日期，创建者的名字等等，都是可以选择的。   <br><br>RSS是站点用来和其他站点之间共享内容的一种简易方式（也叫聚合内容），通常被用于新闻和其他按顺序排列的网站，例如Blog。一段项目的介绍可能包含新闻的全部介绍，Blog post等等。或者仅仅是额外的内容或者简短的介绍。这些项目的链接通常都能链接到全部的内容。网络用户可以在客户端借助于支持RSS的新闻聚合工具软件（例如NewzCrawler、FeedDemon），在不打开网站内容页面的情况下阅读支持RSS输出的网站内容。网站提供RSS输出，有利于让用户发现网站内容的更新。   <br><br>RSS如何工作？首先您一般需要下载和安装一个RSS阅读器，然后从网站提供的聚合新闻目录列表中订阅您感兴趣的新闻栏目的内容。 <br><span style="color:#ff0033;line-height:1.8em;">拿本站做个例子说明吧，当你看到一个网站像本站一样有一个橙色的RSS图标时点击打开一个页面，本站是</span><wbr /><a href="http://www.luoyejie.cn/rss.php" target="_blank"><span style="color:#ff0033;line-height:1.8em;">http://www.luoyejie.cn/rss.php</span><wbr /></a><wbr /><span style="color:#ff0033;line-height:1.8em;">然后复制打开页面的地址添加到RSS阅读器的RSS源中，就可以执行阅览了。</span><wbr />订阅后，您将会及时获得所订阅新闻频道的最新内容。 对于一般用户来说，用RSS订阅新闻可以像使用Outlook Express收取订阅的邮件一样简单；而对于Web应用程序的开发者而言，RSS的工作过程也不是那么复杂，至少比大多数其他常见的Web技术都更容易被理解和被实现。 有人认为，RSS的初衷似乎是为了给邮件列表订阅服务以致命的打击，若从RSS的应用方式来看，这几乎是不可避免的。但从实际效果来看，RSS最火爆的应用并非是商业信息的集中订阅，而是个人通过Web实现的信息聚合，一个典型的例子就是各国的网志作者（Blogger）首先成为最普遍的RSS应用人群。  <br>         浏览者通过订阅不同的RSS(可同时订阅多个网站)，就能在不登录网站的情况下获得及时的新闻信息，还可以避免网页上无用的广告和垃圾信息的干扰。使用RSS会为浏览者节省大量的时间，也会成为体现网站人性化设计的一个亮点，提升了网站的档次。  <br><br>其实RSS技术并不太难，如果你的网站信息量较大，完全可以把这一技术运用到自己的站点中来。  <br><br>小知识：什么是RSS  <br><br>RSS是站点与站点之间共享内容的一种简易方式(也称为“聚合内容”)，通常被用于新闻和其他按顺序排列的网站，例如Blog网站。网站提供RSS输出，有利于让用户发现网站内容的更新。网站用户可以在客户端借助于类似新闻资讯阅读器等支持RSS的新闻聚合工具软件，在不打开网站内容页面的情况下阅读支持RSS输出的网站内容。  <br><br>一、知己知彼，百战不殆  <br><br>要想为网站创建RSS，首先我们必须对RSS进行深入的了解。RSS是基于XML(可扩展标志语言)的一种形式，并且所有的RSS文件都要遵守万维网联盟(W3C)站点发布的XML 1.0规范。一般来说，RSS文档的最顶层是一个&lt;rss&gt;元素作为根元素，&lt;rss&gt;元素有一个强制属性version，用于指定当前RSS文档的版本，目前常用的RSS版本是2.0。&lt;rss&gt;元素下的子元素是唯一的一个&lt;channel&gt;元素，它包含了关于该网站或栏目的信息和内容，在&lt;channel&gt;下必备的语句有三个：  <br><br>&lt;title&gt;：网站或栏目的名称，一般与网站或栏目的页面title一致；  <br>&lt;link&gt;：网站或栏目的URL；  <br>&lt;description&gt;：对网站或栏目的简要描述。  <br><br>还可以使用一些如&lt;language&gt;(语言)、&lt;copyright&gt;(版权声明)等可选语句来丰富&lt; channel&gt;内容，具体的新闻提要就要依靠&lt;item&gt;来体现了。一般一条新闻就是一个&lt;item&gt;，&lt; item&gt;下至少要存在一个&lt;title&gt;或&lt;description&gt;，其他语句可以根据需要进行选择。  <br><br>提示：更多RSS的语句介绍可参考<a href="http://www.donews.net/softbunny/articles/11030.aspx" target="_blank"><span style="color:#f19e00;font-size:13px;line-height:1.8em;">http://www.donews.net/softbunny/articles/11030.aspx</span><wbr /></a><wbr />    。学习RSS语句时可以使用IE打开一个XML链接进行对照参考，如天极网网络通信版块聚合内容<a href="http://rss.chinabyte.com/218424581927469056.xml" target="_blank"><span style="color:#f19e00;font-size:13px;line-height:1.8em;">http://rss.chinabyte.com/218424581927469056.xml</span><wbr /></a><wbr />    。  <br><br>二、RSS，手工造  <br><br>了解了RSS具体的语句结构和用法后，我们就可以按照以下格式在最常用的记事本或网页编辑软件中手工编辑网站的RSS了。  <br><br><br><span style="line-height:1.8em;">以下是代码片段：</span><wbr /><br>&lt;?xml version=“1.0” en coding=“gb2312”?&gt;   <br>&lt;rss version=“2.0”&gt;   <br>&lt;channel&gt;   <br>&lt;title&gt;网站或栏目的名称&lt;/title&gt;   <br>&lt;link&gt;网站或栏目的URL地址&lt;/link&gt;   <br>&lt;description&gt;网站或栏目的简要介绍&lt;/description&gt;   <br>&lt;item&gt;   <br>&lt;title&gt;新闻标题&lt;/title&gt;   <br>&lt;link&gt;新闻的链接地址&lt;/link&gt;   <br>&lt;description&gt;新闻简要介绍&lt;/description&gt;   <br>&lt;pubDate&gt;新闻发布时间&lt;/pubDate&gt;   <br>&lt;author&gt;新闻作者名称&lt;/author&gt;   <br>&lt;/item&gt;   <br>&lt;item&gt;   <br>……   <br>&lt;/item&gt;   <br>&lt;/channel&gt;   <br>&lt;/rss&gt;  <br><br>其中中文文字和省略号部分就是要添加新闻的部分，按照提示依次添加完毕即可保存为.xml文件并在网站的适当位置加入“XML”字样的图标，然后链接到该 .xml文件，这样你的网站就拥有了RSS输出了。  <br><br>三、工具编写，轻松自如  <br><br>如果网站更新的新闻量大，依靠手工编写RSS文件就有可能出错。我们可以请RSS生成器(下载地址：http://sq.onlinedown.net/down/rsscreator.rar)来辅助我们工作。开启软件，执行“文件→新建→RSS”新建一个RSS文件(图1)。首先在上方“必选元素”区输入“Description”、 “Link”和“Title”三个必选语句的内容，要添加新闻条目就点击“Items”后的按钮进入新闻添加窗口(图2)，单击“Add”按钮增加一个新闻条目，然后在左边的语句中根据提示添加新闻标题(Title)、简要(Description)和链接(Link)等，完毕后返回到软件主界面，按下工具栏中的保存按钮将文档保存为 .xml文件即可。  <br><br>提示：RSS生成器需要.NET Framework的支持，在安装之前要在<a href="http://go.microsoft.com/fwlink/?LinkId=9832" target="_blank"><span style="color:#f19e00;font-size:13px;line-height:1.8em;">http://go.microsoft.com/fwlink/?LinkId=9832</span><wbr /></a><wbr /> 处下载安装.NET Framework组件包。  <br><br>四、自动生成，一劳永逸  <br><br>对于静态网站我们可以手工或使用工具来编写RSS输出，若是动态网站则要通过程序来转换新闻数据库内容输出RSS了。有兴趣的朋友可以在<a href="http://www.mh.fy.cn/rss2.rar" target="_blank"><span style="color:#f19e00;font-size:13px;line-height:1.8em;">http://www.mh.fy.cn/rss2.rar</span><wbr /></a><wbr /> 处下载转换模板，此模板适合ASP+ACCESS类的动态网站更新系统，需要修改的是数据库链接部分db=*.mdb。另外在数据库字段读取以及给新闻标题 (Title)和链接(Link)等字段赋值也要根据数据库的具体情况做一些修改，使用该模板调试成功后，网站的RSS输出地址就是http: //你的域名/rss2.asp。  <br>参考资料：<a href="http://www.rsschina.com.cn/" target="_blank"><span style="color:#f19e00;font-size:13px;line-height:1.8em;">www.RSSchina.com.cn</span><wbr /></a><wbr /> <!--v:3.2--> ]]></description>
<category><![CDATA[个人日记]]></category>
<author><![CDATA[344867279@qq.com(/tp鳎毪鍪蕾)]]></author>
<comments>http://344867279.qzone.qq.com/blog/1214175638#comment</comments>
<qz:effect>512</qz:effect>
<pubDate>Sun, 22 Jun 2008 23:00:38 GMT</pubDate>
<guid>http://344867279.qzone.qq.com/blog/1214175638</guid>
</item>

<item>
<title><![CDATA[webservice 在实际开发的应用（转载）]]></title>
<link>http://344867279.qzone.qq.com/blog/1212827648</link>
<description><![CDATA[去年，在一个大型项目(1500w)中用到Web Services，现在项目进入了尾声，所以对以前的开发经历做一个总结。 <br>我想大家一定会问？为什么你们项目中要用到Web Services，因为客户有如下需求： <br>1、客户要求项目用C/S架构，并且服务器端是IBM那一套：WebSphere AppServer＋DB2＋AIX5.3＋RS/6000。 <br>2、最终用户上报数据，因为网络原因，譬如Modem上网，可以离线操作，等填写了几十张报表后，可以一次提交。同时，在登录时，可以将服务端数据同步到本地Access或MSSQL数据库，这样提高客户端响应速度。 <br>3、由于有些报表以后可能需要修改，或添加一些新报表，又不想重新开发，这样客户那边工作人员可以通过客户端自定义。 <br><br>如果有以上需求，我想大家应该都比较认同这种异构分布式解决方案：客户端用C# .Net开发，通过Web Services调用服务器端Java组件。 <br><br>其实，上面的解决方案太过于理想，最后我们不得不面对残酷的现实：三种客户端中的两种最后被迫改为B/S。 <br>在项目中，我主要负责Web Services和服务器端组件开发中所遇到的种种问题，相当于技术支持吧，以及部分模块的开发。 <br><br>以下是我们开发中遇到的实际问题，虽然最终都一一解决，但遇到了几个无法突破的瓶颈：客户端不稳定，客户端响应迟缓，后期测试和维护困难巨大。 <br><br><span style="font-weight:bold"><wbr />一、异构平台的Web Services兼容性</span><wbr /> <br>开发过程中，我们用Axis做Web Services引擎，Tomcat做容器。因为我们只有IBM提供的RAD6.0的60天试用版。该工具超级占内存，用内置的WebSphere开发测试极其缓慢，严重影响开发效率，经过我初期试用后，基本废弃了。推荐项目组二三十开发人员用Lomboz eclipse3.12开发，基本满意。 <br><br>由于Axis是一个嵌入式引擎，所以可以将其打包到最终的WebSphere AppServer（WAS）上，也就是说，我们没有用到WAS提供的Web Services引擎，这引出了后面会谈到的一个问题：Web Services安全性怎么部署？ <br><br>用Axis时，Axis一直都有一个bug或是说缺陷，官方文档也详细注明，只是我们当时没有发现而走了很多弯路：用Axis发布的Web Services给.net客户端调用时，必须用RPC风格，不能用Web Services标准的跨平台风格Document，而后者是Lomboz axis插件的默认方式。也就是说，我们发布的Web Services总是莫名其妙的不好用。我们用JBuilder2007自带的Axis插件发布，竟然非常顺利。 <br><br><span style="font-weight:bold"><wbr />二、Web Services开发中服务器端组件问题</span><wbr /> <br>我们服务器端开发，是用Spring＋Hibernate，在Spring的Service层上再封装一层，也就是fa?ade模式了，该fa?ade直接发布为Web Services，必须经过这个转换，一是因为性能，二是因为Hibernate的复杂Model对象，在wsdl描述后，被.net客户端识别有些问题，List、Map也会有问题，总之这些对象太复杂了，我们包装成简单的VO对象。 <br><br>另外一个问题是，我们的service方法，如果直接给WebWork这样的框架在服务端用的的话，是不会出问题，当提供给.net客户端用时，就会出现lazy loading的错误，因为.net客户端不能接收Proxy对象，必须将数据全部load出来，但这时Hibernate的session已经关闭。项目组很多人遇到这些问题，最后大家不约而同的全部用eager模式，导致了最后的恶果：严重的的性能问题。由于我不是leader，所以当时这个问题发现了，也没法要求别人，毕竟很大的一个团队。 <br>切身体会：一个团队，如果不熟悉Hibernate就随便上，技术风险非常大。Hibernate带来的开发效率，是以团队成员掌握它为前提。 <br><br>当然，性能问题不只是由Hibernate引起，Web Services本身的性能也非常严重：XML的序列化和反序列化耗时，XML文件的膨胀导致的网络传输，HTTP的无状态导致网络IO性能。切身体会：如果系统必须用分布式，而不是追求所谓的SOA架构，Web Services应该是下下策，因为还有很多协议和方式可以选择：IIOP、RMI、Hessian、burlap、RPC，另外，做系统集成还有Message方式。 <br><br>Web Services开发中其它问题比较少，因为Web Services本身不用编程，只是部署的事情，开发工具和服务器会自动为我们做，我们只需要理解SOAP引擎的原理和使用就够了，真的遇到问题，可以通过Axis的TcpMonitor监视SOAP数据包。 <br>开发过程中，.net客户端那边，VSStudio做得很智能，它会根据wsdl文件生成我们所要的一切，当然，wsdl文件的变化，会导致VSStudio重新生成所有的类和接口，也很耗时，并且容易出问题。 <br><br><span style="font-weight:bold"><wbr />三、Web Services的安全问题</span><wbr /> <br>当时解决Web Services安全问题，花了我将近一个月的时间，主要是学习和处理如下四个问题： <br>XML和Web Services安全规范 <br>WAS的 Web Services引擎的安全部署 <br>Axis和参考的Xfire引擎的Web Services安全 <br>.net客户端WSE3.0的安全以及和WAS的通讯 <br><br>最后这些问题基本上都解决了，不过还是没有用上，因为在我们已经开发的几种客户端和服务器端部署上很麻烦，还要测试，另外，客户也没法验收这个啊。 <br><br>当然，我们还回避了一个严肃的问题：我们的Web Services是发布在Axis引擎上，还没有移植到WAS的Web Services引擎，而发布在这个平台，必须有RAD这类开发工具支持，几乎没法手动做。WAS引擎的Web Services安全配置异常复杂：我们当时只配置了Authentication和Integration，没有做Encryption，但完全够用。我当时用Sun的NetBean开发工具发布了一下Web Serivces，也是挺好用的，不过没有配置安全。顺便说一下，Sun的web Services引擎jwsdp2.0设计有点类似于EJB容器，很不好用，移植性特差。 <br>我们当时用Axis引擎是1.3版本，而该版并不支持标准的OASIS的WS-Security，只有到2.0版才开始，而且几乎都是手写配置文件。 <br><br>WAS的Web Services安全配置，对照IBM的红皮书，不是很难，但很复杂，安全相关的xml代码都好几百行，好几个文件。配置过程中，和.net客户端通讯时遇到一个问题，怎么也不能互通，但.net和.net客户端可以互通，Java和Java客户端也可以互通,最后我通过拦截soap包,找到了解决办法: 必须手动更改http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3 后的v3，IBM工具生成的是v1，这是标准不兼容引起的，因为当时RAD是04年底,而微软的WSE3.0比较新。后来发现这篇文章有相似的经历：<a href="http://pluralsight.com/blogs/kirillg/archive/2005/04/13/7315.aspx" target="_blank"><span style="color:#006699;line-height:1.8em;">http://pluralsight.com/blogs/kirillg/archive/2005/04/13/7315.aspx </span><wbr /></a><wbr /><br><br>在处理Web Services安全过程中，我通过emule和IBM网站下载了上10本这方面的书籍，我觉得以下资料对我帮助最大： <br>Axis的若干文档：Reference、developers-guide、architecture-guide等，非常详细 <br>IBM的红皮书：《WebSphere Version 6 Web Services Handbook Development and Deployment.pdf》、《WebSphere Application Server V6 Security Handbook.pdf》，它专门讲述了Web Services安全的原理和具体配置，非常深入浅出。 <br>《Securing Web Services with WS-Security》：这本书很理论化，但我认为非常好，虽然Amazon排行不高。 <br>WSE3.0的MSDN文档。<br><br><br><span style="font-weight:bold"><wbr />四、开发过程中的的沟通问题</span><wbr /> <br>这应该不是一个技术问题，而是一个软件开发方法学的问题，但对整个软件开发过程影响极大。 <br>我们面对的现实：.net客户端开发人员不懂服务器端Java，服务器端Java开发人员不懂.net。 <br>除了技术壁垒外，还有业务衔接性的问题，因为我们不是纵向分模块开发，而横向开发的前提是我们服务器端开发人员很熟悉业务，知道客户端需要的接口，但实际上，业务主要由客户端推动。所以，两端的开发人员都遇到很大的沟通壁垒。 <br><br>从技术的角度表达就是：客户端开发人员需要的接口，服务器端开发人员不清楚；服务器端开发人员也不知道怎么把握粒度。譬如，有个updateUser方法，但更新用户信息时，可能需要更新很多信息：用户信息、用户角色、用户所属组….。loadUser时也有同样的按需加载问题。 <br><br>当然，从技术角度，开发Web Serivces有Bottom-up和Top-down两种开发模式。我们选择了前者，也是最常见的方式，也许用后者更适合我们的项目：从定义的wsdl文件开始，客户端和服务器端开发都遵循它。但问题是：我们怎么确定wsdl，也就是我们所要求的接口，因为我们自己对业务都不是很熟。 <br><br><span style="font-weight:bold"><wbr />五、客户端和服务端开发测试方法</span><wbr /> <br>我们当时做得很笨，也最直接：等服务器端组件发布完毕后，通知客户端开发人员，然后客户端开发人员通过VSStudio提供的Web Services生成工具，根据Axis发布的wsdl文件，生成所需的.net对象，然后像本地调用一样使用。 <br><br>但问题是： <br>wsdl随时都在变，这意味着客户端生成的组件总在变化，经常出现编译错误。 <br>客户端开发过程中遇到的问题，一会是客户端自己，一会是服务器端组件：我要的方法包含的信息不够啊。 <br><br>服务器组件测试一次，起容器特慢，而且客户端调用也慢。 <br>我们的测试，最后走入了一个怎样的泥潭：譬如测试一张报表，都是在客户端手工填写，然后观察服务器端日志和响应。有人会问，用LoadRunner或Function Tester这类自动测试工具不就ok了吗？我都用过，它们对Web UI确实好用，后者对Swing客户端也好用，但对.net客户端，像是不太现实。 <br>另外，Debug非常困难，因为它要求两端开发人员必须在一起密切配合。 <br><br>我自己认为的解决方案，但未必真的好用： <br>服务器端Service方法必须写单元测试TestCase，可能代码量非常大，测试好后方发布为Web Services。 <br>同时，服务器端提供同一套接口的Mock实现，供客户端开发测试，解决并行开发的问题。 <br><br><span style="font-weight:bold"><wbr />六、其它问题</span><wbr /> <br>当然，上面的几点，具体到细节，我都省略了，总之问题非常非常多：技术问题、管理问题、方法和过程问题。 <br><br>特别提的一点是，我们几乎开发了两套“业务层＋持久化”解决方案，因为离线客户端也用了NHibernate持久化，这样导致开发测试工作量巨大，就说一点吧:两边同步是通过打包的sql语句，通过SOAP传输，但Access和DB2的sql有不兼容问题，如果要兼容，就会以牺牲性能和灵活性为代价。 <br><br>另外，我们写项目建议书时很被动，但也没办法，因为有好几家公司竞争。对我们影响极大的几个问题： <br>1、IBM的WAS比起WebLogic Server易用性差远了，导致部署时极其耗时。而且还有一些bug，譬如连接池资源，当时不得不和IBM工程师咨询。实际上，我们只用到强大的WAS的一个非常小的部分：Web容器。 <br>2、我们没有针对WAS的开发工具RAD。但说实话，那试用版的RAD也是一个字：慢，而且安装时超级大，约4个G。而且和我们已经在用的版本控制工具VSS没法集成。 <br>3、项目的C/S架构不是很合理，就是原来客户的B/S架构，也运行挺好的，而且用asp，跑在一个pc server上。我们一定程度上为了技术而技术。最后也达不到客户需求：性能＋稳定。 <br>4、自定义报表最后没有投入使用，只是一个半成品。本来自定义报表就很难，要是容易，一个软件外行人员，就可以把表现层到持久化轻松搞定，那一般MIS开发人员不要失业了，MDA也没那么强。很多OA平台一直在解决这个问题，也没有发现特别好用的。我们做技术调研期间试过MS的InfoPath和Adobe Designer，以及Excel Server，都不能满足需求。<br><br>当然，这个子系统只是我们那个庞大系统的一个部分。上面也就算我做的一点点总结吧，也是教训啊！不过，从个人角度考虑，学到的东西还是很多的。 <br><br>这个子系统花去了我们将近200个人月，如果说那浪费的部分，估计至少是100个人月的工作量。是什么导致？从我这篇文章只能窥其一角，因为整个系统涉及CMS、OA、BI、E-commerce、GIS、IM、MIS。我自己总结一下，有以下原因： <br>1、项目建议书空洞，不切实际：公司也很无奈，客户也不成熟。 <br>2、需求调研后的需求分析闭门造车：客户的合同是分阶段，我们上交需求说明书后付20％款，上交设计书后又付20％。全一个瀑布开发，虽然按RUP文档写。到半年后的实际开发时，发现很多需求都不合理。 <br>3、整个过程都没有和客户沟通，到最后开发完毕才让客户看，那时客户也懵了：这不是我要的产品啊。改呀，改呀，熬夜啊。 <br>4、项目团队整体技术实力薄弱，当时调来做Java开发的人员，只有少数几个以前做Java，大多数是临时学。想起那Hibernate使用，心寒啊。另外，WAS问题、AIX问题在产品环境下都出来了：系统不稳定、宕机。 <br>5、整个开发阶段流程没有把握好，像项目规范、测试方法、日志、版本控制，这些后期都出现了，而且非常严重。就说那日志吧，最后出问题都不知道怎么查，日志一遍混乱。 <br>6、缺乏做大项目经验，整个系统架构都比较松散，项目开始时很多都不知从何入手，也很仓促。 <br>7、项目持续一年多，人都换了几批了，工作交接很大问题。 <br>..... <br><br>不过，说实话，项目团队，特别是进公司一、两年的员工都很努力，没有人抱怨什么，我和他（她）们一起合作，还是很开心的。 <!--v:3.2--> ]]></description>
<category><![CDATA[个人日记]]></category>
<author><![CDATA[344867279@qq.com(/tp鳎毪鍪蕾)]]></author>
<comments>http://344867279.qzone.qq.com/blog/1212827648#comment</comments>
<qz:effect>512</qz:effect>
<pubDate>Sat, 07 Jun 2008 08:34:08 GMT</pubDate>
<guid>http://344867279.qzone.qq.com/blog/1212827648</guid>
</item>

<item>
<title><![CDATA[介绍S2SH的两种分页方法]]></title>
<link>http://344867279.qzone.qq.com/blog/1212707829</link>
<description><![CDATA[在实际开发当中分页技术是经常用到的，所以今天总结一下我自己在学校以及“应用”当中（<img src="http://imgcache.qq.com/qzone/em/e1.gif"><wbr />）常见的两种方法列举一下。<br>第一种：应该是我们通常做的一种，写一个分页类Pager<br> <br>Pager：<br>package com.book.util;<br>public class Pager {<br> private int totalRows; // 总行数<br> private int pageSize = 5; // 每页显示的行数<br> private int currentPage; // 当前页号<br> private int totalPages; // 总页数<br> private int startRow; // 当前页在数据库中的起始行<br> public Pager() {<br> }<br> public Pager(int _totalRows) {<br>  totalRows = _totalRows;<br>  totalPages = totalRows / pageSize;<br>  int mod = totalRows % pageSize;<br>  if (mod &gt; 0) {<br>   totalPages++;<br>  }<br>  currentPage = 1;<br>  startRow = 0;<br> }<br> public int getStartRow() {<br>  return startRow;<br> }<br> public int getTotalPages() {<br>  return totalPages;<br> }<br> public int getCurrentPage() {<br>  return currentPage;<br> }<br> public int getPageSize() {<br>  return pageSize;<br> }<br> public void setTotalRows(int totalRows) {<br>  this.totalRows = totalRows;<br> }<br> public void setStartRow(int startRow) {<br>  this.startRow = startRow;<br> }<br> public void setTotalPages(int totalPages) {<br>  this.totalPages = totalPages;<br> }<br> public void setCurrentPage(int currentPage) {<br>  this.currentPage = currentPage;<br> }<br> public void setPageSize(int pageSize) {<br>  this.pageSize = pageSize;<br> }<br> public int getTotalRows() {<br>  return totalRows;<br> }<br> public void first() {<br>  currentPage = 1; // 第一页＝首页<br>  startRow = 0;<br> }<br> public void previous() {<br>  if (currentPage == 1) { // 判断是否是第一页 如果是返回<br>   return;<br>  }<br>  currentPage--; // 不是第一页 说明有下一页<br>  startRow = (currentPage - 1) * pageSize; // 记录数从（当前页－1）×pageSize（5）记住startRow从0开始<br> }<br> public void next() {<br>  if (currentPage &lt; totalPages) { // 如果当前页小于总页数<br>   currentPage++; // 有下一页 页数加1<br>  }<br>  startRow = (currentPage - 1) * pageSize; // 记录数从（当前页－1）×pageSize（5）记住startRow从0开始<br> }<br> public void last() {<br>  currentPage = totalPages; // 当前页＝总页数<br>  startRow = (currentPage - 1) * pageSize;// 记录数从（当前页－1）×pageSize（5）记住startRow从0开始<br> }<br> public void refresh(int _currentPage) {<br>  currentPage = _currentPage;<br>  if (currentPage &gt; totalPages) {<br>   last();<br>  }<br> }<br>}<br> <br>第二种：自定义通用的JSP组建进行分页split_page.jsp<br>&lt;%@ page contentType=&quot;text/html;charset=gbk&quot;%&gt;<br>&lt;%<br> // 页面连接路径<br> String jspUrl = null ;<br> // 定义如下分页变量<br> // 1、定义没页要显示的记录数，默认是10条每页<br> int lineSize = 10 ;<br> // 2、定义一个当前是第几页<br> int currentPage = 1 ;<br> // 计算出总页数<br> int pageSize = 0 ;<br> // 总记录数 / 每页显示的记录数<br> int allRecorders = 0 ;<br> // 加入查询关键字变量<br> String keyWord = null ;<br> // 加入一个检索标记<br> String searchFlag = &quot;F&quot; ;<br>%&gt;<br>&lt;%<br> // 需要从外面接收以下参数<br> // 当前页、每页显示的记录数、总记录数、查询关键字、连接地址<br> jspUrl = request.getParameter(&quot;jspUrl&quot;) ;<br> keyWord = request.getParameter(&quot;keyWord&quot;) ;<br> searchFlag = request.getParameter(&quot;searchFlag&quot;) ;<br> try<br> {<br>  lineSize = Integer.parseInt(request.getParameter(&quot;lineSize&quot;)) ;<br>  currentPage = Integer.parseInt(request.getParameter(&quot;currentPage&quot;)) ;<br>  allRecorders = Integer.parseInt(request.getParameter(&quot;allRecorders&quot;)) ;<br> }<br> catch(Exception e)<br> {<br>  // s<br> }<br>%&gt;<br>&lt;%<br> // 计算总页数<br> pageSize = (allRecorders+lineSize-1)/lineSize ;<br>%&gt;<br>&lt;script language=&quot;javaScript&quot;&gt;<br> function openPage(curpage)<br> {<br>  document.spage.cp.value = curpage ;<br>  // alert(cupage) ;<br>  document.spage.submit() ;<br> }<br> function selOpenPage()<br> {<br>  document.spage.cp.value = document.spage.selpage.value ;<br>  document.spage.submit() ;<br> }<br> function change()<br> {<br>  if(document.spage.kw.value!=&quot;&quot;)<br>  {<br>   document.spage.status.value = &quot;selectlike&quot; ;<br>  }<br> }<br>&lt;/script&gt;<br>&lt;form name=&quot;spage&quot; action=&quot;&lt;%=jspUrl%&gt;&quot; onSubmit=&quot;change()&quot;&gt;<br>&lt;input type=&quot;hidden&quot;<br> name=&quot;${param.flagname}&quot; value=${param.flagvalue}&gt; &lt;%<br> if (&quot;T&quot;.equals(searchFlag)) {<br> %&gt; 输入查询关键字：&lt;input type=&quot;text&quot; name=&quot;kw&quot;<br> value=&quot;&lt;%=keyWord.equals(&quot;null&quot;) ? &quot;&quot; : keyWord%&gt;&quot;&gt; &lt;input<br> type=&quot;submit&quot; value=&quot;查询&quot;&gt; &lt;br&gt;<br>&lt;br&gt;<br>&lt;%<br>}<br>%&gt; &lt;%<br> if (allRecorders &gt; 0) {<br> %&gt; &lt;input type=&quot;button&quot; value=&quot;首页&quot; onClick=&quot;openPage(1)&quot;<br> &lt;%=currentPage == 1 ? &quot;disabled&quot; : &quot;&quot;%&gt;&gt; &lt;input type=&quot;button&quot;<br> value=&quot;上一页&quot; onClick=&quot;openPage(&lt;%=currentPage - 1%&gt;)&quot;<br> &lt;%=currentPage == 1 ? &quot;disabled&quot; : &quot;&quot;%&gt;&gt; &lt;input type=&quot;button&quot;<br> value=&quot;下一页&quot; onClick=&quot;openPage(&lt;%=currentPage + 1%&gt;)&quot;<br> &lt;%=currentPage == pageSize ? &quot;disabled&quot; : &quot;&quot;%&gt;&gt; &lt;input type=&quot;button&quot;<br> value=&quot;尾页&quot; onClick=&quot;openPage(&lt;%=pageSize%&gt;)&quot;<br> &lt;%=currentPage == pageSize ? &quot;disabled&quot; : &quot;&quot;%&gt;&gt; &lt;input type=&quot;hidden&quot;<br> name=&quot;cp&quot; value=&quot;&quot;&gt; &lt;font color=&quot;red&quot; size=&quot;5&quot;&gt;&lt;%=currentPage%&gt;&lt;/font&gt;<br>/ &lt;font color=&quot;red&quot; size=&quot;5&quot;&gt;&lt;%=pageSize%&gt;&lt;/font&gt; 跳转到 &lt;select<br> name=&quot;selpage&quot; onChange=&quot;selOpenPage()&quot;&gt;<br> &lt;%<br> for (int x = 1; x &lt;= pageSize; x++) {<br> %&gt;<br> &lt;option value=&quot;&lt;%=x%&gt;&quot; &lt;%=currentPage == x ? &quot;selected&quot; : &quot;&quot;%&gt;&gt;&lt;%=x%&gt;&lt;/option&gt;<br> &lt;%<br> }<br> %&gt;<br>&lt;/select&gt; 页 &lt;%<br>}<br>%&gt;<br>&lt;/form&gt;<br>其他的DAO，action就不写了，主要是把思路写下。<br> <!--v:3.2--> ]]></description>
<category><![CDATA[个人日记]]></category>
<author><![CDATA[344867279@qq.com(/tp鳎毪鍪蕾)]]></author>
<comments>http://344867279.qzone.qq.com/blog/1212707829#comment</comments>
<qz:effect>512</qz:effect>
<pubDate>Thu, 05 Jun 2008 23:17:09 GMT</pubDate>
<guid>http://344867279.qzone.qq.com/blog/1212707829</guid>
</item>

</channel>
</rss>

