??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲国产成人久久99精品,久久精品国产亚洲AV久,亚洲精品视频久久久http://m.tkk7.com/lq410/zh-cnMon, 12 May 2025 07:22:50 GMTMon, 12 May 2025 07:22:50 GMT60关于Spring AOP FrameWork的几UAdvice- -http://m.tkk7.com/lq410/archive/2005/11/02/17844.html扑扑扑扑Wed, 02 Nov 2005 09:19:00 GMThttp://m.tkk7.com/lq410/archive/2005/11/02/17844.htmlhttp://m.tkk7.com/lq410/comments/17844.htmlhttp://m.tkk7.com/lq410/archive/2005/11/02/17844.html#Feedback0http://m.tkk7.com/lq410/comments/commentRss/17844.htmlhttp://m.tkk7.com/lq410/services/trackbacks/17844.html       在Spring的AOP FrameWork中Advice主要分ؓ以下五种cdQ?/DIV>
       1、MethodBeforeAdvice?此Advice指的是对于被切者方法执行之前的q预。此Advice除了在抛出异常时能对被切者方法执行作出干预外Q其他情况下该被切者的Ҏ仍照常执行?/DIV>
       2、MethodInterceptor。此Advice指的是对于被切者方法执行过E进行干预,可得被切者方法在某些条g下不执行Qƈ且可以改变被切者方法执行后q回的类型?/DIV>
       3、AfterReturningAdvice。此Advice指的是对于被切者方法执行之后的q预。此Advice和MethodBeforeAdvice相同?/DIV>
       4、ThrowingAdvice。此Advice指的是当被切者方法抛出异常时q行的干预?/DIV>
       5、IntroductionInterceptor。此Advice可干预被切者,q可改变别切者,比如让被切者实C个接口等{?/DIV>

扑扑 2005-11-02 17:19 发表评论
]]>目备忘http://m.tkk7.com/lq410/archive/2005/10/18/15826.html扑扑扑扑Tue, 18 Oct 2005 08:50:00 GMThttp://m.tkk7.com/lq410/archive/2005/10/18/15826.htmlhttp://m.tkk7.com/lq410/comments/15826.htmlhttp://m.tkk7.com/lq410/archive/2005/10/18/15826.html#Feedback0http://m.tkk7.com/lq410/comments/commentRss/15826.htmlhttp://m.tkk7.com/lq410/services/trackbacks/15826.html
user?
INSERT INTO `user` (`userid`, `name`, `password`, `zhiwu`, `beizhu`, `guanli`, `groupid`) VALUES ('1','admin_lq','liqing',NULL,NULL,1,NULL);

t_group?
INSERT INTO `t_group` (`groupid`, `name`, `parent_groupid`, `create_by`, `beizhu`, `userid`, `node_level`, `nodeid`) VALUES ('1','admin_test','1','1',NULL,NULL,1,10); INSERT INTO `user_group` (`userid`, `groupid`) VALUES ('1','1');

2.用户l只能设|一个维护h?t_group表中的userid字段即ؓl护人员字段,它设|ؓ外键U束user表的userid;


扑扑 2005-10-18 16:50 发表评论
]]>
为select控gd新的optionhttp://m.tkk7.com/lq410/archive/2005/10/17/15730.html扑扑扑扑Mon, 17 Oct 2005 09:49:00 GMThttp://m.tkk7.com/lq410/archive/2005/10/17/15730.htmlhttp://m.tkk7.com/lq410/comments/15730.htmlhttp://m.tkk7.com/lq410/archive/2005/10/17/15730.html#Feedback0http://m.tkk7.com/lq410/comments/commentRss/15730.htmlhttp://m.tkk7.com/lq410/services/trackbacks/15730.html var  _o=opener.document.createElement("Option");  //为父H口中的select新徏一个option对像
 _o.text=groupName2;  //讄option的文?BR> _o.value=nodeId;  //讄option的?BR> _obj.add(_o);  //d到select控g?BR>
一切就是这么简?

扑扑 2005-10-17 17:49 发表评论
]]>
不用q代法而快速实现的jsp树结?/title><link>http://m.tkk7.com/lq410/archive/2005/10/14/15493.html</link><dc:creator>扑扑</dc:creator><author>扑扑</author><pubDate>Fri, 14 Oct 2005 02:26:00 GMT</pubDate><guid>http://m.tkk7.com/lq410/archive/2005/10/14/15493.html</guid><wfw:comment>http://m.tkk7.com/lq410/comments/15493.html</wfw:comment><comments>http://m.tkk7.com/lq410/archive/2005/10/14/15493.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/lq410/comments/commentRss/15493.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/lq410/services/trackbacks/15493.html</trackback:ping><description><![CDATA[<TABLE class=partsmb cellSpacing=0 border=0> <TBODY> <TR> <TD></TD> <TD><SPAN id=_ctl2_lblPermalink> <TABLE class="fixedTable blogpost" cellSpacing=0 width="100%" border=0> <TBODY> <TR> <TD class=bvh8></TD></TR> <TR> <TD vAlign=top><span id="rffzhrd" class=bold id=LastMDatecns!1peK6gp160nydSWlLmNuMm7g!190><STRONG>7?1?/STRONG></SPAN></TD></TR> <TR> <TD height=4><STRONG></STRONG></TD></TR> <TR> <TD class=blackline><STRONG></STRONG></TD></TR> <TR> <TD height=4><STRONG></STRONG></TD></TR> <TR> <TD class=ellipse><span id="3lh3z5t" class=bvTitle id=subjcns!1peK6gp160nydSWlLmNuMm7g!190><STRONG>不用q代法而快速实现的jsp树结?/STRONG></SPAN></TD></TR> <TR> <TD class=bvh8><STRONG></STRONG></TD></TR> <TR> <TD id=msgcns!1peK6gp160nydSWlLmNuMm7g!190> <P> <BR>在web面上实现树状结?有点ȝ.<BR>在最q的一个MISpȝ的开发中,我们目l大量用C树结?比如人员的选择,单位的选择{待.<BR>q个MISpȝ所用的数据库是oracle 9i.  oracle 9i 的sql支持q代查询.我们的树是由牛h彭越写的,不过<BR>也参照了|络上比较著名的xtree(可以到此下蝲:http://webfx.eae.net/),他的树算法支持无限的树l构,不过性能好像<BR>很慢.我持保留态度.<BR>他用到的关键技术就是这句话:<BR>String sql = "select dwxh,dwbh,dwmc,dwfxh,level cc from xt_dw connect by  prior dwxh = dwfxh start with dwfxh = 0";<BR>可是许多数据库不支持q代查询,q且q代查询速度真是不能忍受.有什么更好的办法?下面说说我的解决Ҏ.</P> <P>一:需求的提出<BR>1:客户需要一个关于部门h员的树结?数据库ؓmysql4.1<BR>2:java实现<BR>?:<BR>1:<BR>用户信息?<BR>各字Dؓ:用户序号,用户~号,用户名称,单位序号,密码,用户登陆?BR>create table XT_YH<BR>(<BR>  YHXH  INT(9) NOT NULL auto_increment PRIMARY KEY,<BR>  YHBH  VARCHAR(30),<BR>  YHMC  VARCHAR(30),<BR>  DWXH  INT(9),<BR>  PWD   VARCHAR(20),<BR>  YHDLH VARCHAR(30)<BR>)<BR>--插入三条试数据:<BR>--insert into xt_yh(yhbh,yhmc,dwxh,pwd,yhdlh) values('licl','',2,'password','licl')<BR>--insert into xt_yh(yhbh,yhmc,dwxh,pwd,yhdlh) values('fengx','冯欣',2,'password','fengx')<BR>--insert into xt_yh(yhbh,yhmc,dwxh,pwd,yhdlh) values('wangqx','王庆?,6,'password','wangqx')<BR>2:<BR>单位部门?BR>各字Dؓ:单位序号,单位~号,单位名称,单位父序?BR>create table XT_DW<BR>(<BR>  DWXH  int(9) NOT NULL auto_increment PRIMARY KEY,<BR>  DWBH  VARCHAR(10),<BR>  DWMC  VARCHAR(30),<BR>  DWFXH int(9)<BR>)<BR>--插入5条测试数?BR>--insert into xt_dw(dwbh,dwmc,dwfxh) values('0100000000','武汉U技局',0);<BR>--insert into xt_dw(dwbh,dwmc,dwfxh) values('0101000000','Z?,1);<BR>--insert into xt_dw(dwbh,dwmc,dwfxh) values('0102000000','后勤?,1);<BR>--insert into xt_dw(dwbh,dwmc,dwfxh) values('0101010000','Z处son1',2);<BR>--insert into xt_dw(dwbh,dwmc,dwfxh) values('0101020000','Z处son2',2);<BR>--insert into xt_dw(dwbh,dwmc,dwfxh) values('0102010000','后勤处son1',3);</P> <P>注意:<BR>Z实现快速的树结构实?我需要充分利用单位编号DWBH,DWBH才有10位编?其中,W一W二位表CZU单?W三W四位表CZU单?<BR>W五六位表示三单位...那么10位编码就可以实现五单位的树l构.<BR>比如:试数据的树l构如下:<BR>  1  武汉U技局:<BR> 2  Z?BR>  3  Z处son1<BR>  3  Z处son2<BR> 2  后勤?BR>  3后勤处son1</P> <P>其实XT_DW表中的父序号是多余的.不过如果你要用P代算法来实现,是必须?BR>才有10位编?我只需要一句简单快速的sql语句可以实现树l构:<BR>String sql = "select dwxh,dwbh,dwmc,dwfxh from xt_dw order by dwbh"<BR>q句sql在几乎所有的数据库^台都能执?速度也快.<BR>下面贴出采用xtree,?0位编码而不是P代算法实现的?</P> <P>/*******Constants.java**********/</P> <P>package com.lcl.common;</P> <P>public class Constants {<BR> <BR> public static final String DBDRIVER = "com.mysql.jdbc.Driver";    //MYSQL驱动<BR> <BR> public static final String DBUrl="jdbc:mysql://localhost/beauoa"; //数据库url<BR> <BR> public static final String USERNAME="root";                       //数据库用户名<BR> <BR> public static final String PASSWORD="root";     //数据库密?BR> <BR> <BR>}</P> <P><BR>/**********DbAccess.java****************/</P> <P>package com.lcl.common;</P> <P>import java.sql.*;<BR>import java.lang.*;</P> <P>/**<BR> * @author <BR> *<BR> * TODO 要更Ҏ生成的类型注释的模板Q请转至<BR> * 数据库访问类<BR> */<BR>public class DbAccess<BR>{  <BR> String strDBDriver = Constants.DBDRIVER;<BR> String strDBUrl = Constants.DBUrl;<BR> String username = Constants.USERNAME;<BR> String password = Constants.PASSWORD;<BR> private Connection conn = null;<BR> private Statement stmt = null;<BR> ResultSet rs=null;<BR> //注册数据库驱动程?BR> public DbAccess()<BR> {  <BR>  try <BR>  {  <BR>   Class.forName(strDBDriver);<BR>  }<BR>  //异常处理<BR>  catch( java.lang.ClassNotFoundException e)<BR>  {<BR>   System.err.println("DbAccess():"+e.getMessage());<BR>  }<BR> }<BR> //建立数据库连接及定义数据查询<BR> public ResultSet executeQuery(String sql)<BR> {<BR>  rs=null;<BR>  try<BR>  {<BR>   conn=DriverManager.getConnection(strDBUrl,username,password);<BR>   stmt=conn.createStatement();<BR>   rs=stmt.executeQuery(sql);<BR>  }<BR>  catch(SQLException ex)<BR>  {<BR>   System.err.println("ap.executeQuery:"+ex.getMessage());<BR>  }<BR> <BR>  return rs;<BR> }<BR> //定义数据操库?BR> public void executeUpdate(String sql)<BR> {<BR>  stmt=null;<BR>  rs=null;<BR>  try<BR>  {<BR>   conn=DriverManager.getConnection(strDBUrl,username,password);<BR>   stmt=conn.createStatement();<BR>   stmt.executeQuery(sql);<BR>   stmt.close();<BR>   conn.close();<BR>  }<BR>  catch(SQLException ex)<BR>  {<BR>   System.err.println("ap.executeQuery:"+ex.getMessage());<BR>  }<BR> }<BR> //关闭数据?BR> public void closeStmt()<BR> {<BR>  try<BR>  {<BR>   stmt.close();<BR>  }<BR>  catch(SQLException e)<BR>  {<BR>   e.printStackTrace();<BR>  }<BR> }<BR> public void closeConn()<BR> {<BR>  try<BR>  {<BR>   conn.close();<BR>  }<BR>  catch(SQLException e)<BR>  {<BR>   e.printStackTrace();<BR>  }<BR> }<BR> public static void main(String[] args){<BR>  System.out.println("hello,it's test");<BR>  DbAccess dbaccess = new DbAccess();<BR>  String sql = "select * from xt_yh";<BR>  ResultSet rs = dbaccess.executeQuery(sql);<BR>  try<BR>  {<BR>   while(rs.next()){<BR>    System.out.print(rs.getString(1)+rs.getString(2)+rs.getString(3)+rs.getString(4)+rs.getString(5)+rs.getString(6));<BR>    System.out.println();<BR>   }<BR>  dbaccess.closeStmt();<BR>  dbaccess.closeConn();<BR>  } <BR>  catch (SQLException e) <BR>  {<BR>   // TODO 自动生成 catch ?BR>   e.printStackTrace();<BR>  }<BR> }<BR> }</P> <P> /*********DepEmplConfig.jsp************/</P> <P> <%@ page contentType="text/html; charset=gb2312" language="java" import="java.sql.*,com.lcl.common.*" errorPage="" %><BR><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "<A ><BR><html><BR><head><BR><meta http-equiv="Content-Type" content="text/html; charset=gb2312"><BR><title>无标题文?lt;/title><BR><HEAD><BR><script type="text/javascript" src="../resources/xDataTree.js"></script><BR><link type="text/css" rel="stylesheet" href="../resources/xtree.css" /><BR><style type="text/css"></P> <P>body {<BR> background: white;<BR> color:  black;<BR>}<BR></style><BR><TITLE> New Document </TITLE><BR><META NAME="Generator" CONTENT="EditPlus"><BR><META NAME="Author" CONTENT=""><BR><META NAME="Keywords" CONTENT=""><BR><META NAME="Description" CONTENT=""><BR></HEAD><BR><script type="text/javascript">  <BR>webFXTreeConfig.rootIcon  = "../resources/images/xp/folder.png";<BR>webFXTreeConfig.openRootIcon = "../resources/images/xp/openfolder.png";<BR>webFXTreeConfig.folderIcon  = "../resources/images/xp/folder.png";<BR>webFXTreeConfig.openFolderIcon = "../resources/images/xp/openfolder.png";<BR>webFXTreeConfig.fileIcon  = "../resources/images/xp/file.png";<BR>webFXTreeConfig.lMinusIcon  = "../resources/images/xp/Lminus.png";<BR>webFXTreeConfig.lPlusIcon  = "../resources/images/xp/Lplus.png";<BR>webFXTreeConfig.tMinusIcon  = "../resources/images/xp/Tminus.png";<BR>webFXTreeConfig.tPlusIcon  = "../resources/images/xp/Tplus.png";<BR>webFXTreeConfig.iIcon   = "../resources/images/xp/I.png";<BR>webFXTreeConfig.lIcon   = "../resources/images/xp/L.png";<BR>webFXTreeConfig.tIcon   = "../resources/images/xp/T.png";<BR>webFXTreeConfig.blankIcon       = "../resources/images/blank.png";</P> <P>var tree = new WebFXTree("单位人员基本情况","R0");<BR>var child;<BR>var nodeToAddPerson;</P> <P>function addDeptTreeNode(preNodeLevel,curNodeLevel,dispLabel,sKey,sTag) {<BR>  if(curNodeLevel==1) {<BR>     child = tree.add(new WebFXTreeItem(dispLabel,sKey,sTag));<BR>  }<BR>  else {<BR>    if(curNodeLevel==preNodeLevel) {<BR>       if(child.parentNode)<BR>        child = child.parentNode.add(new WebFXTreeItem(dispLabel,sKey,sTag));<BR>    }<BR>    if(curNodeLevel>preNodeLevel) {<BR>       child = child.add(new WebFXTreeItem(dispLabel,sKey,sTag));<BR>    }<BR>    if(curNodeLevel<preNodeLevel) {<BR>        for(i=0;i<preNodeLevel-curNodeLevel+1;i++) <BR>           child = child.parentNode;<BR>        child = child.add(new WebFXTreeItem(dispLabel,sKey,sTag));<BR>    }<BR>  }<BR>  return child;<BR>}</P> <P>function treeClick() {<BR> if(tree.getSelected()) {<BR>     if(tree.getSelected().childNodes.length==0&&tree.getSelected().key!="R0") <BR>       cmdDelete.disabled = false;<BR>     else <BR>       cmdDelete.disabled = true; <BR>     if(tree.getSelected().key.substr(0,2)=="RZ") {<BR>       cmdAddDept.disabled = true;<BR>       cmdAddPeople.disabled = true;<BR>       var strYhxh;<BR>       strYhxh = tree.getSelected().key.substr(2);<BR>       //window.open("../userAdm/editYh.do?yhxh="+strYhxh,"main");<BR>     }<BR>     else if(tree.getSelected().key.substr(0,2)=="RB") {<BR>       cmdAddDept.disabled = false;<BR>       cmdAddPeople.disabled = false;<BR>       var strDwxh;<BR>       strDwxh = tree.getSelected().key.substr(2);<BR>       //window.open("../userAdm/editBm.do?dwxh="+strDwxh,"main");<BR>     }<BR>     else {<BR>       cmdAddDept.disabled = false;<BR>       cmdAddPeople.disabled = true;<BR>       //window.open("yhroot.jsp","main");<BR>     }<BR> }<BR>}</P> <P>function addPeople() {<BR>    var strDwxh;<BR>    if(tree.getSelected()) {<BR>   if (tree.getSelected().key.substr(0,2)=="RB") {<BR>        strDwxh = tree.getSelected().key.substr(2);<BR>  //window.open("../userAdm/addYh.do?dwxh="+strDwxh,"main");<BR>  alert("addPeople");<BR>   }<BR>    }<BR>}</P> <P>function addDept() {<BR>    var strDwxh;<BR>    if(tree.getSelected()) {<BR>   if (tree.getSelected().key.substr(0,2)=="RB") {<BR>        strDwfxh = tree.getSelected().key.substr(2);<BR>  //window.open("../userAdm/addBm.do?dwfxh="+strDwfxh,"main");<BR>    alert("addDept");<BR>   }<BR>      else if(tree.getSelected().key=="R0") {<BR>        //window.open("../userAdm/addBm.do?dwfxh=0","main");<BR>        alert("addDept");<BR>      }<BR>    }<BR>}</P> <P>function deleSelected() {<BR>  if(!confirm("认删除该节点吗Q?))<BR>      return;<BR>  if(tree.getSelected()) {<BR>    if(tree.getSelected().key.substr(0,2)=="RB") {<BR>       var strDwxh;<BR>       strDwxh = tree.getSelected().key.substr(2);<BR>       //window.open("../userAdm/delBm.do?dwxh="+strDwxh,"main");<BR>       alert("deleSelected");<BR>    }<BR>    else if(tree.getSelected().key.substr(0,2)=='RZ') {<BR>       var strYhxh,strYhbh;<BR>       strYhxh = tree.getSelected().key.substr(2);<BR>       strYhbh = tree.getSelected().tag;<BR>       //window.open("../userAdm/delYh.do?yhxh="+strYhxh+"&yhbh="+strYhbh,"main");<BR>       alert("deleSelected");<BR>    }<BR>  }<BR>}</P> <P>function removeNode() {<BR>  if(tree.getSelected()) {<BR>    var node = tree.getSelected();<BR>    node.remove();<BR>  }<BR>}</P> <P>function addPeopleNode(strParentKey,strKey,strText,strTag) {<BR>  if(tree.getSelected()) {<BR>    var node = tree.getSelected();<BR>    var childNode;<BR>    //node.expand();<BR>    childNode = node.add(new WebFXTreeItem(strText,strKey,strTag,"","","../resources/images/people1.png"));<BR>    node.expand(); //why I do so? I dont want to tell you,hah!<BR>    childNode.focus();<BR>    treeClick();<BR>  }<BR>}</P> <P>function addDeptNode(strParentKey,strKey,strText,strTag) {<BR>  if(tree.getSelected()) {<BR>    var node = tree.getSelected();<BR>    var childNode;<BR>    childNode = node.add(new WebFXTreeItem(strText,strKey,strTag));<BR>    node.expand();<BR>    childNode.focus();<BR>    treeClick();<BR>  }<BR>}</P> <P>function updateDeptNode(strTag,strText) {<BR>  if(tree.getSelected()) {<BR>    var node = tree.getSelected();<BR>    node.text = strText;<BR>    node.tag  = strTag;<BR>    node.focus();<BR>  }<BR>}</P> <P>function updatePeopleNode(strTag,strText) {<BR>  if(tree.getSelected()) {<BR>    var node = tree.getSelected();<BR>    node.text = strText;<BR>    node.tag  = strTag;<BR>    node.focus();<BR>  }<BR>}<BR></script><BR><%<BR>int dwxh;<BR>int dwfxh;<BR>int yhxh;<BR>String dwbh = null;<BR>String dwmc = null;<BR>String yhmc = null;<BR>String yhbh = null;<BR>int preLevel =1;<BR>int level = 1;<BR>DbAccess dbaccess = new DbAccess();<BR>String sql = "select dwxh,dwbh,dwmc,dwfxh from xt_dw order by dwbh";<BR>ResultSet rs = dbaccess.executeQuery(sql);<BR>try<BR>{<BR> while(rs.next())<BR> {<BR>        dwxh = rs.getInt(1);<BR>        dwbh = rs.getString(2);<BR>        dwmc = rs.getString(3);<BR>        dwfxh = rs.getInt(4);<BR>//通过单位~号计算level<BR>  String last = dwbh.substring(9,10);<BR>  int i = 9;<BR>  while(last.equals("0") && i>0){<BR>   i--;<BR>   last = dwbh.substring(i,i+1);<BR>  <BR>  }<BR>  <BR>  if(i==0 || i==1) level =1;<BR>  if(i==2 || i==3) level =2;<BR>  if(i==4 || i==5) level =3;<BR>  if(i==6 || i==7) level =4;<BR>  if(i==8 || i==9) level =5;<BR>//<BR>  %><BR>           <script type="text/javascript">  <BR>     nodeToAddPerson = addDeptTreeNode(<%=preLevel%>,<%=level%>,"<%=dwmc%>","RB<%=dwxh%>","<%=dwbh%>");<BR>        </script>  <BR>  <BR>  <%<BR>  preLevel = level;<BR>  String subsql = "select yhxh,yhmc,yhbh from xt_yh where dwxh = "+Integer.toString(dwxh);<BR>  ResultSet subRs = dbaccess.executeQuery(subsql);<BR>       while(subRs.next()) {<BR>              yhxh = subRs.getInt(1);<BR>              yhmc = subRs.getString(2);<BR>              yhbh = subRs.getString(3); <BR>  %><BR>             <script type="text/javascript">  <BR>     nodeToAddPerson.add(new WebFXTreeItem("<%=yhmc%>","RZ<%=yhxh%>","<%=yhbh%>","","","../resources/images/people1.png"));<BR>        </script><BR>     <%<BR>  }<BR>  <BR> }<BR> dbaccess.closeStmt();<BR> dbaccess.closeConn();<BR>}<BR>catch(Exception e)<BR>{</P> <P>}<BR>%></P> <P><BR><base target="_self"><BR><META HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE"><BR></head><BR><body><BR><table border="0" width="100%" cellspacing="0" cellpadding="0"><BR>  <tr><BR>    <td width="273" colspan="2"><BR>       <font face="宋体" size="3">     <BR>       </font><BR>    </td><BR>  </tr><BR>  <tr><BR>    <th width="33%" align="center" nowrap><BR>      <p align="center"><BR>      <INPUT id=cmdAddDept name="AddDept" type=button value="增加部门" onclick="addDept()" style="FONT-FAMILY: 楷体_GB2312; FONT-SIZE: 12pt; FONT-WEIGHT: bold; HEIGHT: 24px; WIDTH: 80px" ><BR>      </p><BR>    </th><BR>    <th width="33%" align="center" nowrap><BR>      <p align="center"><BR>      <INPUT id=cmdAddPeople name="AddPeople" type=button value="增加用户" onclick="addPeople()" style="FONT-FAMILY: 楷体_GB2312; FONT-SIZE: 12pt; FONT-WEIGHT: bold; HEIGHT: 24px; WIDTH: 80px" ><BR>      </p><BR>    </th><BR>    <th width="33%" align="center" nowrap><BR>      <p align="center"><BR>      <INPUT id=cmdDelete name="Delete" type=button value=" 删除 " onclick="deleSelected()" style="FONT-FAMILY: 楷体_GB2312; FONT-SIZE: 12pt; FONT-WEIGHT: bold; HEIGHT: 24px; WIDTH: 80px" disabled><BR>      </p><BR>    </th><BR>  </tr><BR>  <tr><BR>    <td width="273" height="8"  colspan="2">&nbsp;<BR>      <BR>    </td><BR>  </tr><BR></table><BR></body><BR><div onclick="treeClick()"><BR><script type="text/javascript">  <BR> document.write(tree);<BR></script><BR></div><BR></HTML></P></TD></TR></TBODY></TABLE></SPAN></TD></TR></TBODY></TABLE><img src ="http://m.tkk7.com/lq410/aggbug/15493.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/lq410/" target="_blank">扑扑</a> 2005-10-14 10:26 <a href="http://m.tkk7.com/lq410/archive/2005/10/14/15493.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>struts-menu+ibatis+量的代?通用的自定义菜单和动态加载的?/title><link>http://m.tkk7.com/lq410/archive/2005/10/14/15490.html</link><dc:creator>扑扑</dc:creator><author>扑扑</author><pubDate>Fri, 14 Oct 2005 02:16:00 GMT</pubDate><guid>http://m.tkk7.com/lq410/archive/2005/10/14/15490.html</guid><wfw:comment>http://m.tkk7.com/lq410/comments/15490.html</wfw:comment><comments>http://m.tkk7.com/lq410/archive/2005/10/14/15490.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/lq410/comments/commentRss/15490.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/lq410/services/trackbacks/15490.html</trackback:ping><description><![CDATA[<P>前言Q?BR>    知识准备Q首先你需要懂一些struts的基本知识,会用struts-menuQƈ理解站长对struts-menu的分析那文章,q要知道ibatis的基本知识,如果不懂Q请去google或者站长的论坛里找相关的文章?/P> <P>树Şl构在实际开发中很常用,但是树Şl构的开发往往也是NQ尤其是在显C一条上Q很隑ց到通用。通常有两U典型的树型l构。一U是论坛的帖子,其结构往往通过父子IDLq?数据在一张表里。一U是U别Q比如论坛中的Category->Forum->Threadq种l构Q数据放在不同的表里。因坛恰好包含了q两U结构。因此。我们就能Jive的表l构来做q个例子。首先我们通过RsMetaDataTest来扫描数据库Q得到需要的XML配置文g。拿一个xmlZQ解释一?/P> <TABLE width="100%" border=1> <TBODY> <TR> <TD bgColor=#cccccc><PRE class="smallFont style2"><?xml version="1.0" encoding="UTF-8"?><BR><!DOCTYPE sql-map<BR>PUBLIC "-//iBATIS.com//DTD SQL Map 1.0//EN"<BR>"http://www.ibatis.com/dtd/sql-map.dtd"><BR><sql-map name="jivecategory"><BR><!-- =============================================<BR> mapped-statement find <BR>============================================= --><BR><dynamic-mapped-statement name="findjivecategoryDao" result-class="java.util.HashMap"><BR> select $listfield$ from JIVECATEGORY<BR> <dynamic prepend="where"><BR> <isPropertyAvailable prepend="and" property="CATEGORYID" ><BR> <isNotNull prepend="" property="CATEGORYID" ><BR> CATEGORYID=#CATEGORYID#<BR> </isNotNull><BR> </isPropertyAvailable><BR> <isPropertyAvailable prepend="and" property="NAME" ><BR> <isNotNull prepend="" property="NAME" ><BR> NAME=#NAME#<BR> </isNotNull><BR> </isPropertyAvailable><BR> <isPropertyAvailable prepend="and" property="DESCRIPTION" ><BR> <isNotNull prepend="" property="DESCRIPTION" ><BR> DESCRIPTION=#DESCRIPTION#<BR> </isNotNull><BR> </isPropertyAvailable><BR> <isPropertyAvailable prepend="and" property="CREATIONDATE" ><BR> <isNotNull prepend="" property="CREATIONDATE" ><BR> CREATIONDATE=#CREATIONDATE#<BR> </isNotNull><BR> </isPropertyAvailable><BR> <isPropertyAvailable prepend="and" property="MODIFIEDDATE" ><BR> <isNotNull prepend="" property="MODIFIEDDATE" ><BR> MODIFIEDDATE=#MODIFIEDDATE#<BR> </isNotNull><BR> </isPropertyAvailable><BR> <isPropertyAvailable prepend="and" property="LFT" ><BR> <isNotNull prepend="" property="LFT" ><BR> LFT=#LFT#<BR> </isNotNull><BR> </isPropertyAvailable><BR> <isPropertyAvailable prepend="and" property="RGT" ><BR> <isNotNull prepend="" property="RGT" ><BR> RGT=#RGT#<BR> </isNotNull><BR> </isPropertyAvailable><BR> </dynamic> <BR></dynamic-mapped-statement></PRE> <P class="smallFont style2"></sql-map></P></TD></TR></TBODY></TABLE> <P>可见有一个名叫f<span id="zfpbfx3" class="smallFont style2"><FONT size=2>indjivecategoryDao</FONT></SPAN>Q这是一个典型的动态查询。返回对象是HashMap。其?listfield$表示动态读取的字段。可以这么说Q通过q个查询。有兌栯的Q何方式的查询都已l解决了。由于这个演C只用到四张表,因些我们在sql-map-config-storedb.xml也只加蝲了四张表的定义?/P> <TABLE width="100%" bgColor=#cccccc border=1> <TBODY> <TR> <TD><sql-map resource="sqlmap/jivecategory.xml" /><BR><sql-map resource="sqlmap/jiveforum.xml" /> <BR><sql-map resource="sqlmap/jivethread.xml" /> <BR><sql-map resource="sqlmap/jivemessage.xml" /> </TD></TR></TBODY></TABLE> <P>然后定义MenuDefinec,q个cL一个通用的定义,其主要属性如下。可以通过它徏立一个四张表的树形关pR?/P> <TABLE width="100%" bgColor=#cccccc border=1> <TBODY> <TR> <TD><span id="5r3x55n" class=smallFont>//sql Map的名U?<BR>private String sqlMapName;<BR>//调用的查询名U?BR>private String SqlName;<BR>//子菜单的名称<BR>private String submenuName; </SPAN> <P><span id="tfvlx5b" class=smallFont>//对应字段Q其中keyZ表的字段Qvalue是从表的字段?BR>private HashMap keymap;<BR>//菜单的名U?BR>private String MenuName;<BR>//标题<BR>private String Title;<BR>//标题字段<BR>private String TitleField;<BR>//需要读取的字段<BR>private String listField;<BR>//是否需要显C?BR>private boolean needShow=true;</SPAN><BR></P></TD></TR></TBODY></TABLE> <P>然后建立一个XML的文?此处化了它的功能Q就是把上面q个cd列化了一?。把它放在classes目录下?/P> <TABLE width="100%" bgColor=#cccccc border=1><PRE> </PRE> <TBODY> <TR> <TD><PRE><FONT face=Arial><span id="hrl3d5x" class=style3><?xml version="1.0" encoding="UTF-8"?> <BR><java version="1.4.2_03" class="java.beans.XMLDecoder"> <BR> <object class="java.util.HashMap"> <BR> <void method="put"> <BR> <string>message</string> <BR> <object class="com.ewuxi.champion.MenuDefine"> <BR> <void property="keymap"> <BR> <object class="java.util.HashMap"> <BR> <void method="put"> <BR> <string>MESSAGEID</string> <BR> <string>PARENTMESSAGEID</string> <BR> </void> <BR> </object> <BR> </void> <BR> <void property="listField"> <BR> <string>MESSAGEID,SUBJECT</string> <BR> </void> <BR> <void property="menuName"> <BR> <string>message</string> <BR> </void> <BR> <void property="sqlMapName"> <BR> <string>jivemessage</string> <BR> </void> <BR> <void property="sqlName"> <BR> <string>findjivemessageDao</string> <BR> </void> <BR> <void property="submenuName"> <BR> <string>message</string> <BR> </void> <BR> <void property="title"> <BR> <string>文章</string> <BR> </void> <BR> <void property="titleField"> <BR> <string>SUBJECT</string> <BR> </void> <BR> </object> <BR> </void> <BR> <void method="put"> <BR> <string>category</string> <BR> <object class="com.ewuxi.champion.MenuDefine"> <BR> <void property="keymap"> <BR> <object class="java.util.HashMap"> <BR> <void method="put"> <BR> <string>CATEGORYID</string> <BR> <string>CATEGORYID</string> <BR> </void> <BR> </object> <BR> </void> <BR> <void property="listField"> <BR> <string>CATEGORYID,NAME</string> <BR> </void> <BR> <void property="menuName"> <BR> <string>category</string> <BR> </void> <BR> <void property="sqlMapName"> <BR> <string>jivecategory</string> <BR> </void> <BR> <void property="sqlName"> <BR> <string>findjivecategoryDao</string> <BR> </void> <BR> <void property="submenuName"> <BR> <string>forum</string> <BR> </void> <BR> <void property="title"> <BR> <string>大分c?lt;/string> <BR> </void> <BR> <void property="titleField"> <BR> <string>NAME</string> <BR> </void> <BR> </object> <BR> </void> <BR> <void method="put"> <BR> <string>forum</string> <BR> <object class="com.ewuxi.champion.MenuDefine"> <BR> <void property="keymap"> <BR> <object class="java.util.HashMap"> <BR> <void method="put"> <BR> <string>FORUMID</string> <BR> <string>FORUMID</string> <BR> </void> <BR> </object> <BR> </void> <BR> <void property="listField"> <BR> <string>FORUMID,NAME</string> <BR> </void> <BR> <void property="menuName"> <BR> <string>forum</string> <BR> </void> <BR> <void property="sqlMapName"> <BR> <string>jiveforum</string> <BR> </void> <BR> <void property="sqlName"> <BR> <string>findjiveforumDao</string> <BR> </void> <BR> <void property="submenuName"> <BR> <string>thread</string> <BR> </void> <BR> <void property="title"> <BR> <string>子分c?lt;/string> <BR> </void> <BR> <void property="titleField"> <BR> <string>NAME</string> <BR> </void> <BR> </object> <BR> </void> <BR> <void method="put"> <BR> <string>thread</string> <BR> <object class="com.ewuxi.champion.MenuDefine"> <BR> <void property="keymap"> <BR> <object class="java.util.HashMap"> <BR> <void method="put"> <BR> <string>THREADID</string> <BR> <string>THREADID</string> <BR> </void> <BR> <void method="put"> <BR> <string>FORUMID</string> <BR> <string>FORUMID</string> <BR> </void> <BR> <void method="put"> <BR> <string>ROOTMESSAGEID</string> <BR> <string>MESSAGEID</string> <BR> </void> <BR> </object> <BR> </void> <BR> <void property="listField"> <BR> <string>THREADID,ROOTMESSAGEID</string> <BR> </void> <BR> <void property="menuName"> <BR> <string>thread</string> <BR> </void> <BR> <void property="needShow"> <BR> <boolean>false</boolean> <BR> </void> <BR> <void property="sqlMapName"> <BR> <string>jivethread</string> <BR> </void> <BR> <void property="sqlName"> <BR> <string>findjivethreadDao</string> <BR> </void> <BR> <void property="submenuName"> <BR> <string>message</string> <BR> </void> <BR> <void property="title"> <BR> <string>栏目</string> <BR> </void> <BR> <void property="titleField"> <BR> <string>ROOTMESSAGEID</string> <BR> </void> <BR> </object> <BR> </void> <BR> </object> <BR></java> </SPAN><BR></FONT> </PRE></TD></TR></TBODY></TABLE> <P>兌关系?SPAN class=style3><FONT face=Arial>category</FONT></SPAN>表通过<span id="lfrrd3j" class=style3><FONT face=Arial>CATEGORYID</FONT></SPAN>?SPAN class=style3><FONT face=Arial>forum</FONT></SPAN>兌Q?SPAN class=style3><FONT face=Arial>forum</FONT></SPAN>通过<span id="z3htfxr" class=style3><FONT face=Arial>FORUMID</FONT></SPAN>?SPAN class=style3><FONT face=Arial>thread</FONT></SPAN>兌Q?SPAN class=style3><FONT face=Arial>thread</FONT></SPAN>是一张特D的表。它不昄在树中,只是一个过渡关联,用于d新徏的文章?/P> <P><span id="hbffbb5" class=style3><FONT face=Arial>thread</FONT></SPAN>通过<span id="p3np53h" class=style3><FONT face=Arial>FORUMID</FONT></SPAN>?SPAN class=style3><FONT face=Arial>FORUMID</FONT></SPAN>?SPAN class=style3><FONT face=Arial>ROOTMESSAGEID</FONT></SPAN>?SPAN class=style3><FONT face=Arial>message</FONT></SPAN>表关?<span id="3dnphfh" class=style3><FONT face=Arial>FORUMID</FONT></SPAN>?SPAN class=style3><FONT face=Arial>FORUMID</FONT></SPAN>?SPAN class=style3><FONT face=Arial>MESSAGEID</FONT></SPAN>)。而message表是一个自兌的表?SPAN class=style3><FONT face=Arial>MESSAGEID</FONT></SPAN>?SPAN class=style3><FONT face=Arial>PARENTMESSAGEID</FONT></SPAN>兌建立父子关系?/P> <P>然后我们建立一个sessioncMZ要类</P> <TABLE width="100%" border=1> <TBODY> <TR> <TD bgColor=#cccccc><PRE>public class TreeDemoSession { //通过名称和参数来得到? public MenuComponent getMenu(String name, Map keys) throws Exception { Map menuMap = (Map) (new XmlUtils().read(Service.getPath() + "/menu.xml")); MenuComponent menu = new MenuComponent(); if (menuMap.get(name) != null) { MenuDefine rootMenudefine = (MenuDefine) menuMap.get(name); menu.setTitle(rootMenudefine.getTitle()); menu.setName(rootMenudefine.getMenuName()); menu = submenuAdd(menu, keys, menuMap, name); } return menu; } /**一个典型的递归函数。用以组l树? * @param menu * @param map * @param menuMap * @param menuName * @return * @throws DaoException * @throws Exception */ private MenuComponent submenuAdd( MenuComponent menu, Map map, final Map menuMap, String menuName) throws DaoException, Exception { try { //得到菜单定义 MenuDefine menudefine = (MenuDefine) menuMap.get(menuName); //listfield,表示需要读取哪几个字段 map.put("listfield", menudefine.getListField()); //查询Q返回列表? List list = DaoCommon.findbyName(map, menudefine.getSqlName()); int namei = 0; for (Iterator iter = list.iterator(); iter.hasNext();) { Map element = (Map) iter.next(); //建立当前节点 MenuComponent submenu = new MenuComponent(); submenu.setName(menu.getName() + String.valueOf(namei++)); submenu.setTitle( String.valueOf(element.get(menudefine.getTitleField()))); //如果不需要显C,则用父节点作ؓ当前节点 if (!menudefine.isNeedShow()) submenu = menu; //如果有子菜单Q则递归调用? if (menudefine.getSubmenuName() != null) { submenu = submenuAdd( submenu, getSubMenuInfo(menudefine, element), menuMap, menudefine.getSubmenuName()); } //当前节Ҏ到树中?如果不需要显C就不用? if (menudefine.isNeedShow()) menu.addMenuComponent(submenu); } return menu; } catch (DaoException e) { throw e; } catch (Exception e) { throw e; } } /**父菜单的关键字D늚g为参数给子菜? * @param menudefine * @param element * @return */ private HashMap getSubMenuInfo(MenuDefine menudefine, Map element) { HashMap map = new HashMap(); for (Iterator iter = menudefine.getKeymap().keySet().iterator(); iter.hasNext(); ) { String key = (String) iter.next(); map.put(menudefine.getKeymap().get(key), element.get(key)); } return map; } } </PRE></TD></TR></TBODY></TABLE> <P>三个函数Q非常简单,d数读取配|文件的内容。一个递归函数用来建立树Şl构。这|只有两个属性被讄。一个是名字和标题。其中标题采用从数据库里d的字Dc名字则采用水受读取数据库只有一?其中map是参数的一个列表。后面是sql的名字?/P> <TABLE width="100%" border=1> <TBODY> <TR> <TD>List list = DaoCommon.findbyName(map, menudefine.getSqlName());</TD></TR></TBODY></TABLE> <P>而真正的实现代码也非常简?/P> <TABLE width="100%" border=1> <TBODY> <TR> <TD>public static List findbyName(Object vo,String name) throws DaoException {<BR>try {<BR>SqlMap sqlMap = DaoCommon.getSqlMap(DaoCommon.getDefautDao());<BR>return (List) sqlMap.executeQueryForList(name, vo);<BR>} catch (Exception e) {<BR>throw new DaoException(e);<BR>}<BR>}</TD></TR></TBODY></TABLE> <P>下面我们来做Action的工?/P> <TABLE class=smallFont width="100%" bgColor=#cccccc border=1> <TBODY> <TR> <TD>public ActionForward execute(<BR>ActionMapping mapping,<BR>ActionForm form,<BR>HttpServletRequest request,<BR>HttpServletResponse response)<BR>throws Exception { <P>Service.initSet();<BR>DaoCommon.startTransaction();</P> <P>HashMap parMap = new HashMap();<BR>Enumeration enumeration = request.getParameterNames();<BR>while (enumeration.hasMoreElements()) {<BR>String element = (String) enumeration.nextElement();<BR>parMap.put(element, request.getParameter(element));<BR>}<BR>TreeDemoSession session=new TreeDemoSession();<BR>request.setAttribute("com.ewuxi.champion.menu",session.getMenu(request.getParameter("menuName"),parMap));</P> <P>DaoCommon.rollBack();</P> <P>return mapping.findForward(request.getParameter("type"));<BR>}<BR></P></TD></TR></TBODY></TABLE> <P>q个函数也非常简单,是把从request传来的内容生成一个Map对象。然后调用session,返回结果以com.ewuxi.champion.menu为名字保存到request中去?/P> <P>最后我们需要生成一个自定义的taglib。实际上很简单。只是因为struts-menu自n的taglib是写MQ我们不能利用,不过只要改一个地方就可以?copy UseMenuDisplayerTag到我们的目录下?/P> <TABLE width="100%" bgColor=#cccccc border=1> <TBODY> <TR> <TD class=smallInput><span id="frtv35h" class=smallFont>MenuRepository repository =<BR>(MenuRepository) pageContext.getServletContext().getAttribute(MenuRepository.MENU_REPOSITORY_KEY); </SPAN> <P class=smallFont>if (repository == null) {<BR>throw new JspException("Could not obtain the menu repository");<BR>}</P> <P class=smallFont>MenuComponent menu = repository.getMenu(this.name);</P></TD></TR></TBODY></TABLE> <P>扑ֈ上面q一D,Ҏ</P> <TABLE width="100%" border=1> <TBODY> <TR> <TD class=smallFont bgColor=#cccccc><BR>MenuComponent menu =<BR>(MenuComponent) pageContext.findAttribute(this.name);<BR></TD></TR></TBODY></TABLE> <P>OK了。然后需要徏立一个JSP文g。我们把xtree.jsp借用q来。唯一需要改的就?lt;cp:displayMenu name="com.ewuxi.champion.menu"/>Q当然还有几个link的\径。因为此处用treeDemo来所以就是href="/treeDemo/styles/xtree.css"</P> <TABLE class=smallFont width="100%" border=1> <TBODY> <TR> <TD bgColor=#cccccc><head><BR><title>XTree (with Velocity) Example</title> <P><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></P> <P><link rel="stylesheet" type="text/css" media="screen"<BR>href="/treeDemo/styles/global.css" /><BR><link rel="stylesheet" type="text/css" media="screen"<BR>href="/treeDemo/styles/xtree.css" /><BR><BR><script type="text/javascript" src="/treeDemo/scripts/xtree.js"></script></P> <P></head><BR><body></P> <P><div class="container"><BR>Simple menu with Velocity:<br /><BR><script type="text/javascript"><BR><menu:useMenuDisplayer name="Velocity" config="/templates/xtree.html"<BR>bundle="org.apache.struts.action.MESSAGE"><BR>if (document.getElementById) {<BR><cp:displayMenu name="com.ewuxi.champion.menu"/><BR>} else {<BR>var msg = "Your browser does not support document.getElementById().\n";<BR>msg += "You must use a modern browser for this menu.";<BR>alert(msg);<BR>}<BR></P> <P></menu:useMenuDisplayer><BR></script><BR></div></P> <P></P></TD></TR></TBODY></TABLE> <P>下面可以自q看效果了?/P> <TABLE width="100%" border=1> <TBODY> <TR> <TD><p><a href="demo.do?type=demo&menuName=category" target="_blank">大分cd?lt;/a><BR></p><BR><p><a href="demo.do?type=demo&menuName=forum" target="_blank">子分cd?lt;/a> </p><BR><p><a href="demo.do?type=demo&menuName=forum&FORUMID=1" target="_blank">只看java分类</a> </p><BR><p><a href="demo.do?type=demo&menuName=thread" target="_blank">所有文?lt;/a> </p></TD></TR></TBODY></TABLE> <P>上面是几U不同的参数。主要的差别是menuName不同。然后也可以加数据库需要的参数Q比如java分类的forumId=1。就在参C加FORUMID=1,注意大小写要跟XML中的动态参数相同,此处全是大写?/P> <P>在线演示看这?A >http://demo.ewuxi.com:8000/treejivedemo/,<BR>源码下蝲 <BR>http://champion.ewuxi.com/old/opensource/struts-new/treeDemo.rar</A><A ></A></P><!-- InstanceEndEditable --><img src ="http://m.tkk7.com/lq410/aggbug/15490.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/lq410/" target="_blank">扑扑</a> 2005-10-14 10:16 <a href="http://m.tkk7.com/lq410/archive/2005/10/14/15490.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring Aop单实例入?/title><link>http://m.tkk7.com/lq410/archive/2005/10/14/15472.html</link><dc:creator>扑扑</dc:creator><author>扑扑</author><pubDate>Fri, 14 Oct 2005 01:05:00 GMT</pubDate><guid>http://m.tkk7.com/lq410/archive/2005/10/14/15472.html</guid><wfw:comment>http://m.tkk7.com/lq410/comments/15472.html</wfw:comment><comments>http://m.tkk7.com/lq410/archive/2005/10/14/15472.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://m.tkk7.com/lq410/comments/commentRss/15472.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/lq410/services/trackbacks/15472.html</trackback:ping><description><![CDATA[AOP正在成ؓ软g开发的下一个圣杯。用AOPQ你可以处理aspect的代码注入主E序Q通常ȝ序的主要目的q不在于处理q些aspect。AOP可以防止代码混ؕ?<BR>Z理解AOP如何做到q点Q考虑一下记日志的工作。日志本w不太可能是你开发的ȝ序的主要d。如果能“不可见的”、通用的日志代码注入主E序中,那该多好啊。AOP可以帮助你做到?<BR>Spring framework是很有前途的AOP技术。作ZU非늕性的Q轻型的AOP frameworkQ你无需使用预编译器或其他的元标{,便可以在JavaE序中用它。这意味着开发团队里只需一对付AOP frameworkQ其他hq是象往怸LE?<BR>AOP是很多直觉难以理解的术语的根源。幸q的是,你只要理解三个概念,可以编写AOP模块。这三个概念是:adviceQpointcut和advisor。advice是你惛_别的E序内部不同的地Ҏ入的代码。pointcut定义了需要注入advice的位|,通常是某个特定的cȝ一个publicҎ。advisor是pointcut和advice的装配器Q是advice注入ȝ序中预定义位|的代码? <P>既然我们知道了需要用advisor向主要代码中注入“不可见的”adviceQ让我们实现一个Spring AOP的例子。在q个例子中,我们实C个before adviceQ这意味着advice的代码在被调用的publicҎ开始前被执行。以下是q个before advice的实C码: </P> <P>代码: <BR>package com.company.springaop.test; </P> <P>import java.lang.reflect.Method; <BR>import org.springframework.aop.MethodBeforeAdvice; </P> <P>public class TestBeforeAdvice implements MethodBeforeAdvice { </P> <P>public void before(Method m, Object[] args, Object target) <BR>throws Throwable { <BR>System.out.println("Hello world! (by " <BR>+ this.getClass().getName() <BR>+ ")"); <BR>} <BR>} <BR></P> <P><BR>接口MethodBeforeAdvice只有一个方法before需要实玎ͼ它定义了advice的实现。beforeҎq三个参数Q它们提供了相当丰富的信息。参数Method m是advice开始后执行的方法。方法名U可以用作判断是否执行代码的条g。Object[] args是传l被调用的publicҎ的参数数l。当需要记日志Ӟ参数args和被执行Ҏ的名Uͼ都是非常有用的信息。你也可以改变传lm的参敎ͼ但要心使用q个功能Q编写最初主E序的程序员q不知道ȝ序可能会和传入参数的发生冲突。Object target是执行方法m对象的引用?</P> <P>在下面的BeanImplcMQ每个publicҎ调用前,都会执行adviceQ?</P> <P>代码: <BR>package com.company.springaop.test; </P> <P>public class BeanImpl implements Bean { </P> <P>public void theMethod() { <BR>System.out.println(this.getClass().getName() <BR>+ "." + new Exception().getStackTrace()[0].getMethodName() <BR>+ "()" <BR>+ " says HELLO!"); <BR>} <BR>} </P> <P><BR>cBeanImpl实现了下面的接口BeanQ?</P> <P>代码: <BR>package com.company.springaop.test; </P> <P>public interface Bean { <BR>public void theMethod(); <BR>} </P> <P></P> <P>虽然不是必须使用接口Q但面向接口而不是面向实现编E是良好的编E实践,Spring也鼓p样做?</P> <P>pointcut和advice通过配置文g来实玎ͼ因此Q接下来你只需~写L法的Java代码Q?<BR>代码: </P> <P><BR>package com.company.springaop.test; </P> <P>import org.springframework.context.ApplicationContext; <BR>import org.springframework.context.support.FileSystemXmlApplicationContext; </P> <P>public class Main { </P> <P>public static void main(String[] args) { <BR>//Read the configuration file <BR>ApplicationContext ctx <BR>= new FileSystemXmlApplicationContext("springconfig.xml"); </P> <P>//Instantiate an object <BR>Bean x = (Bean) ctx.getBean("bean"); </P> <P>//Execute the public method of the bean (the test) <BR>x.theMethod(); <BR>} <BR>} </P> <P></P> <P>我们从读入和处理配置文g开始,接下来马上要创徏它。这个配|文件将作ؓ_合E序不同部分的“胶水”。读入和处理配置文g后,我们会得C个创建工厂ctx。Q何一个Spring理的对象都必须通过q个工厂来创建。对象通过工厂创徏后便可正怋用?</P> <P>仅仅用配|文件便可把E序的每一部分l装h?<BR>代码: </P> <P><?xml version="1.0" encoding="UTF-8"?> <BR><!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> </P> <P><beans> <BR><!--CONFIG--> <BR><bean id="bean" class="org.springframework.aop.framework.ProxyFactoryBean"> <BR><property name="proxyInterfaces"> <BR><value>com.company.springaop.test.Bean</value> <BR></property> <BR><property name="target"> <BR><ref local="beanTarget"/> <BR></property> <BR><property name="interceptorNames"> <BR><list> <BR><value>theAdvisor</value> <BR></list> <BR></property> <BR></bean> </P> <P><!--CLASS--> <BR><bean id="beanTarget" class="com.company.springaop.test.BeanImpl"/> </P> <P><!--ADVISOR--> <BR><!--Note: An advisor assembles pointcut and advice--> <BR><bean id="theAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <BR><property name="advice"> <BR><ref local="theBeforeAdvice"/> <BR></property> <BR><property name="pattern"> <BR><value>com\.company\.springaop\.test\.Bean\.theMethod</value> <BR></property> <BR></bean> </P> <P><!--ADVICE--> <BR><bean id="theBeforeAdvice" class="com.company.springaop.test.TestBeforeAdvice"/> <BR></beans> <BR></P> <P><BR>四个bean定义的次序ƈ不重要。我们现在有了一个adviceQ一个包含了正则表达式pointcut的advisorQ一个主E序cd一个配|好的接口,通过工厂ctxQ这个接口返回自己本w实现的一个引用?</P> <P>BeanImpl和TestBeforeAdvice都是直接配置。我们用一个唯一的ID创徏一个bean元素Qƈ指定了一个实现类。这是全部的工作?</P> <P>advisor通过Spring framework提供的一个RegexMethodPointcutAdvisorcL实现。我们用advisor的一个属性来指定它所需的advice-bean。第二个属性则用正则表辑ּ定义了pointcutQ确保良好的性能和易L?</P> <P>最后配|的是beanQ它可以通过一个工厂来创徏。bean的定义看h比实际上要复杂。bean是ProxyFactoryBean的一个实玎ͼ它是Spring framework的一部分。这个bean的行为通过一下的三个属性来定义Q?</P> <P></P> <P><BR>属性proxyInterface定义了接口类?</P> <P>属性target指向本地配置的一个beanQ这个beanq回一个接口的实现?</P> <P>属性interceptorNames是唯一允许定义一个值列表的属性。这个列表包含所有需要在beanTarget上执行的advisor。注意,advisor列表的次序是非常重要的?</P> <P></P> <P>Spring工具 </P> <P>虽然你可以手工修改Ant构徏脚本Q但使用SpringUIQ译注:SpringUI现在是Spring framework的一部分Qƈ改名为spring-ideQ,使用Spring AOP变得很简单,只要点点鼠标卛_。你可以把SpringUI安装成Eclipse的一个plug-in。然后,你只需在你的project上右击鼠标,q择“add Spring Project Nature”。在project属性中Q你可以在“Spring Project”下dSpring配置文g。在~译前把下面的类库加入projectQaopalliance.jarQcommons-logging.jarQjakarta-oro-2.0.7.jar和spring.jar。运行程序时你会看到下面的信息: </P> <P>... (logging information) <BR>Hello world! (by com.company.springaop.test.TestBeforeAdvice) <BR>com.company.springaop.test.BeanImpl.theMethod() says HELLO! </P> <P><BR>优点和缺?</P> <P>Spring比v其他的framework更有优势Q因为除了AOP以外Q它提供了更多别的功能。作Z个轻型frameworkQ它在J2EE不同的部分都可以发挥作用。因此,即不想使用Spring AOPQ你可能q是想用Spring。另一个优ҎQSpringq不要求开发团队所有的人员都会用它。学习Spring应该从Spring reference的第一开始。读了本文后Q你应该可以更好地理解Spring reference了。Spring唯一的缺Ҏ~Z更多的文档,但它的mailing list是个很好的补充,而且会不断地出现更多的文?/P><img src ="http://m.tkk7.com/lq410/aggbug/15472.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/lq410/" target="_blank">扑扑</a> 2005-10-14 09:05 <a href="http://m.tkk7.com/lq410/archive/2005/10/14/15472.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>多对多关?/title><link>http://m.tkk7.com/lq410/archive/2005/09/23/13831.html</link><dc:creator>扑扑</dc:creator><author>扑扑</author><pubDate>Fri, 23 Sep 2005 05:59:00 GMT</pubDate><guid>http://m.tkk7.com/lq410/archive/2005/09/23/13831.html</guid><wfw:comment>http://m.tkk7.com/lq410/comments/13831.html</wfw:comment><comments>http://m.tkk7.com/lq410/archive/2005/09/23/13831.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/lq410/comments/commentRss/13831.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/lq410/services/trackbacks/13831.html</trackback:ping><description><![CDATA[郁闷了好久的Hibernate的many-to-many双向兌搞定?BR> <P>在做hbiernate的many-to-many的双向关联时Q一方要讄inverse="true"Q另一方要讄inverse="false"。inverse="false"的一方保存时Q维护多对多之间的关p,且只要将怺的关pd诉这一方即可?/P> <P>如果inverse都设|ؓtrueQ双方的关系都不到l护?/P> <P>如果都设|ؓfalseQ双方将共同l护之间的关p,q时Q要双方的包含关系都要讄清楚Q否则将会导致关pȝ护؜乱?/P> <P>如果讄了casade="save-update"Q只能设|一方,如果双方都设|的话,当更C方的时候,同时会更新另一方,另一方的更新又会D一方的更新?BR><BR>lazy loading指的是当实际要用到某个数据字段时候,才将其从数据库中dQ避免内存的费?BR><BR>inverse . inverse默认是false .当你指定inverse="true" cascade="none"  Ӟq个实体对这个属性是没有持久更新的权利的Q它把这个属性的理权利完全交给了关联的另一方了?/P><img src ="http://m.tkk7.com/lq410/aggbug/13831.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/lq410/" target="_blank">扑扑</a> 2005-09-23 13:59 <a href="http://m.tkk7.com/lq410/archive/2005/09/23/13831.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Eclipse快速上手指南之使用Anthttp://m.tkk7.com/lq410/archive/2005/09/02/11821.html扑扑扑扑Fri, 02 Sep 2005 03:13:00 GMThttp://m.tkk7.com/lq410/archive/2005/09/02/11821.htmlhttp://m.tkk7.com/lq410/comments/11821.htmlhttp://m.tkk7.com/lq410/archive/2005/09/02/11821.html#Feedback0http://m.tkk7.com/lq410/comments/commentRss/11821.htmlhttp://m.tkk7.com/lq410/services/trackbacks/11821.html  Ant是Javaq_下非常棒的批处理命o执行E序Q能非常方便地自动完成编译,试Q打包,部v{等一pddQ大大提高开发效率。如果你现在q没有开始用AntQ那p赶快开始学习用,使自q开发水q上一个新台阶?/P>

  Eclipse 中已l集成了AntQ我们可以直接在Eclipse中运行Ant?/P>

  以前面徏立的Hello工程ZQ创Z下目录结构:

  新徏一个build.xmlQ放在工E根目录下。build.xml定义了Ant要执行的批处理命令。虽然Ant也可以用其它文件名Q但是遵循标准能更开发更规范Q同时易于与别h交流?/P>

  通常Qsrc存放Java源文Ӟclasses存放~译后的class文gQlib存放~译和运行用到的所有jar文gQweb存放JSP{web文gQdist存放打包后的jar文gQdoc存放API文档?/P>

  然后在根目录下创建build.xml文gQ输入以下内容:

<xml version="1.0"?>
<roject name="Hello world" default="doc">

<-- properies -->
<roperty name="src.dir" value="src" />
<roperty name="report.dir" value="report" />
<roperty name="classes.dir" value="classes" />
<roperty name="lib.dir" value="lib" />
<roperty name="dist.dir" value="dist" />
<roperty name="doc.dir" value="doc"/>

<-- 定义classpath -->
<ath id="master-classpath">
<ileset file="${lib.dir}/*.jar" />
<athelement path="${classes.dir}"/>
<path>

<-- 初始化Q?-->
<arget name="init">
<target>

<-- ~译 -->
<arget name="compile" depends="init" description="compile the source files">
<kdir dir="${classes.dir}"/>
<avac srcdir="${src.dir}" destdir="${classes.dir}" target="1.4">
<lasspath refid="master-classpath"/>
<javac>
<target>

<-- 试 -->
<arget name="test" depends="compile" description="run junit test">
<kdir dir="${report.dir}"/>
<unit printsummary="on"
haltonfailure="false"
failureproperty="tests.failed"
showoutput="true">
<lasspath refid="master-classpath" />
<ormatter type="plain"/>
<atchtest todir="${report.dir}">
<ileset dir="${classes.dir}">
<nclude name="**/*Test.*"/>
<fileset>
<batchtest>
<junit>
<ail if="tests.failed">
***********************************************************
**** One or more tests failed! Check the output ... ****
***********************************************************
<fail>
<target>

<-- 打包成jar -->
<arget name="pack" depends="test" description="make .jar file">
<kdir dir="${dist.dir}" />
<ar destfile="${dist.dir}/hello.jar" basedir="${classes.dir}">
<xclude name="**/*Test.*" />
<xclude name="**/Test*.*" />
<jar>
<target>

<-- 输出api文档 -->
<arget name="doc" depends="pack" description="create api doc">
<kdir dir="${doc.dir}" />
<avadoc destdir="${doc.dir}"
author="true"
version="true"
use="true"
windowtitle="Test API">
<ackageset dir="${src.dir}" defaultexcludes="yes">
<nclude name="example/**" />
<packageset>
<octitle>[CDATA[<1>ello, test<h1>]>doctitle>
<ottom>[CDATA[<>ll Rights Reserved.<i>]>bottom>
<ag name="todo" scope="all" description="To do:" />
<javadoc>
<target>
<project>

  以上xml依次定义了initQ初始化Q,compileQ编译)QtestQ测试)QdocQ生成文档)QpackQ打包)dQ可以作为模ѝ?/P>

  选中Hello工程Q然后选择“Project”,“Properties”,“Builders”,“New…”,选择“Ant Build”:

  填入NameQAnt_BuilderQBuildfileQbuild.xmlQBase DirectoryQ?{workspace_loc:/Hello}Q按“Browse Workspace”选择工程根目录)Q由于用Cjunit.jar包,搜烦Eclipse目录Q找到junit.jarQ把它复制到Hello/lib目录下,q添加到Ant的Classpath中:

  然后在Builder面板中钩上Ant_BuildQ去掉Java BuilderQ?/P>

  再次~译Q即可在控制台看到Ant的输出:

Buildfile: F:\eclipse-projects\Hello\build.xml

init:

compile:
[mkdir] Created dir: F:\eclipse-projects\Hello\classes
[javac] Compiling 2 source files to F:\eclipse-projects\Hello\classes

test:
[mkdir] Created dir: F:\eclipse-projects\Hello\report
[junit] Running example.HelloTest
[junit] Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 0.02 sec

pack:
[mkdir] Created dir: F:\eclipse-projects\Hello\dist
[jar] Building jar: F:\eclipse-projects\Hello\dist\hello.jar

doc:
[mkdir] Created dir: F:\eclipse-projects\Hello\doc
[javadoc] Generating Javadoc
[javadoc] Javadoc execution
[javadoc] Loading source files for package example...
[javadoc] Constructing Javadoc information...
[javadoc] Standard Doclet version 1.4.2_04
[javadoc] Building tree for all the packages and classes...
[javadoc] Building index for all the packages and classes...
[javadoc] Building index for all classes...
[javadoc] Generating F:\eclipse-projects\Hello\doc\stylesheet.css...
[javadoc] Note: Custom tags that could override future standard tags: @todo. To avoid potential overrides, use at least one period character (.) in custom tag names.
[javadoc] Note: Custom tags that were not seen: @todo
BUILD SUCCESSFUL
Total time: 11 seconds

  Ant依次执行初始化,~译Q测试,打包Q生成API文档一pddQ极大地提高了开发效率。将来开发J2EE目Ӟq可加入部v{Q务。ƈ且,即q了Eclipse环境Q只要正安装了AntQ配|好环境变量ANT_HOME=<nt解压目录>Path=?%ANT_HOME%\binQ在命o行提C符下切换到Hello目录Q简单地键入ant卛_?/P>

扑扑 2005-09-02 11:13 发表评论
]]>
使用spring MVC框架q行文g上传http://m.tkk7.com/lq410/archive/2005/09/02/11819.html扑扑扑扑Fri, 02 Sep 2005 03:04:00 GMThttp://m.tkk7.com/lq410/archive/2005/09/02/11819.htmlhttp://m.tkk7.com/lq410/comments/11819.htmlhttp://m.tkk7.com/lq410/archive/2005/09/02/11819.html#Feedback1http://m.tkk7.com/lq410/comments/commentRss/11819.htmlhttp://m.tkk7.com/lq410/services/trackbacks/11819.html使用spring MVC框架q行文g上传Q步骤如下:

1Q配|web.xml文g。定义DispatcherServletQDispatcherServlet处理的请求(.htmQ也在同一个web.xml文g里用url-mapping定义映射?/P>

 <servlet>
  <servlet-name>upload</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet
  </servlet-class>
  <load-on-startup>1</load-on-startup>
 </servlet>
 
 <servlet-mapping>
  <servlet-name>upload</servlet-name>
  <url-pattern>*.htm</url-pattern>
 </servlet-mapping>
2Q定义upload-servlet.xml文g?BR><bean id="multipartResolver"
       class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!-- set the max upload size100MB -->
        <property name="maxUploadSize">
        <value>104857600</value>
    </property>
    <property name="maxInMemorySize">
        <value>4096</value>
    </property>
   </bean>
 <bean id="urlMapping"
  class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">       
 <property name="mappings">           
  <props>               
  <prop key="/upload.htm">uploadController</prop>           
  </props>       
 </property>   
 </bean>
     <bean id="uploadController" class="FileUploadController">
      <property name="commandClass"><value>FileUploadBean</value></property>
      <property name="uploadDir"><value>E:/</value></property>
      <property name="formView"><value>fail</value></property>
  <property name="successView"><value>confirmation</value></property>
</bean>  
3Q定义控制类QcommandClass及方法。控制类中最重要的方法是initBinder()它给spring注册了一个编辑器?BR>request中的multipart实体q行处理Q如果没有这个方法,上传不能进行?BR><--------------------------控制c?------------------>
public class FileUploadController extends SimpleFormController {
    private static Log log =
        LogFactory.getLog(FileUploadController.class);
    private String uploadDir;//上传文g路径

    protected ModelAndView onSubmit(HttpServletRequest request,
            HttpServletResponse response, Object cmd, BindException errors)
            throws Exception {

            FileUploadBean bean = (FileUploadBean) cmd;
            byte[] bytes = bean.getFile();
          
            //cast to multipart file so we can get additional information
            MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
            CommonsMultipartFile file = (CommonsMultipartFile) multipartRequest.getFile("file");

            String uploadDir = this.getUploadDir();

            File dirPath = new File(uploadDir);
            if (!dirPath.exists()) {
                dirPath.mkdirs();
            }
            String sep = System.getProperty("file.separator");
            if (log.isDebugEnabled()) {
                log.debug("uploading to: " + uploadDir + sep +
                file.getOriginalFilename());
                }
            File uploadedFile = new File(uploadDir + sep
                    + file.getOriginalFilename());
            FileCopyUtils.copy(bytes, uploadedFile);
            System.out.println("********************************");
            System.out.println(uploadedFile.getAbsolutePath());
            System.out.println(bytes.length);
            System.out.println("********************************");
           
     
        return new ModelAndView(getSuccessView() + ".jsp");
    }

    protected void initBinder(HttpServletRequest request,
            ServletRequestDataBinder binder) throws ServletException {
        binder.registerCustomEditor(byte[].class,
                new ByteArrayMultipartFileEditor());
    }
    public void setUploadDir(String uploadDir){
        this.uploadDir = uploadDir;
    }
    public String getUploadDir(){
        return this.uploadDir;
    }
}
<--------------------------控制c?------------------------>
<---------------------定义commandClass-------------------->
public class FileUploadBean {

    private byte[] file;

    public void setFile(byte[] file) {
        this.file = file;
    }

    public byte[] getFile() {
        return file;
    }

}
<---------------------定义commandClass-------------------->
4Q定义一个form表单index.jsp
<form method="post" action="upload.htm" enctype="multipart/form-data">
<input type="file" name="file"/>
<input type="submit"/>
5Q定义confirmation.jsp及fail.jsp
confirmation.jsp如下Q?BR><%@ page contentType="text/html; charset=GBK" %>
<html>
<head>
<title>
successView
</title>
</head>
<body bgcolor="#ffffff">
<h1>
Upload Successful
</h1>
</body>
</html>

fail.jsp如下Q?BR><html>
<head>
<title>Upload a file please</title>
</head>
<body>
<h1>no file,Please upload a file</h1>
<form method="post" action="uploadfile.htm" enctype="multipart/form-data">
<input type="file" name="file"/>
<input type="submit"/>
</form>
</body>
</html>
6Q运行tomcat?BR>预览 ie里面:http://localhost/springmvc/index.jsp
注:
aQ文件目录ؓtomcat-HOME/webapps/springmvc/
.jsp文g都放在根目录下,.class文g攑֜/WEB-INF/classes/?/P>

其他文g攑֜/WEB-INF/里面?BR>bQ如果连上面的你都有疑问Q那q是ȝ看spring的基知识吧?/P>

扑扑 2005-09-02 11:04 发表评论
]]>
(转蝲)文档的作用与分类http://m.tkk7.com/lq410/archive/2005/09/02/11809.html扑扑扑扑Fri, 02 Sep 2005 02:29:00 GMThttp://m.tkk7.com/lq410/archive/2005/09/02/11809.htmlhttp://m.tkk7.com/lq410/comments/11809.htmlhttp://m.tkk7.com/lq410/archive/2005/09/02/11809.html#Feedback0http://m.tkk7.com/lq410/comments/commentRss/11809.htmlhttp://m.tkk7.com/lq410/services/trackbacks/11809.html

软g文档(document)也称文gQ通常指的是一些记录的数据 和数据媒体,它具有固定不变的形式Q可被h和计机阅读。它?计算机程序共同构成了能完成特定功能的计算Y?有h把源 E序也当作文档的一部分)。我们知道,g产品和品资料在?个生产过E中都是有Ş可见的,软g生则有很大不同Q文档本 w就是Y件品。没有文档的软gQ不成其YӞ更谈不到软g 产品。Y件文档的~制(documentation)在Y件开发工作中占有H?出的C和相当的工作量。高效率、高质量地开发、分发、管理和l?护文档对于{让、变更、修正、扩充和使用文档Q对于充分发挥Y 件品的效益有着重要意义?/P>

    然而,在实际工作中Q文档在~制和用中存在着许多?题,有待于解冟뀂Y件开发h员中较普遍地存在着对编制文档不?兴趣的现象。从用户斚w看,他们又常常抱怨:文档售h太高、文 档不够完整、文档编写得不好、文档已l陈旧或是文档太多,难于 使用{等。究竟应该怎样要求它,文档应该写哪些,说明什么问 题,起什么作?q里给出简要的介绍?/P>

?.2 文档桥梁作用

    文档在Y件开发h员、Y件管理h员、维护h员、用户以及计 机之间的多U桥梁作用可从图9Q?中看出。Y件开发h员在?个阶D中以文档作为前阶段工作成果的体现和后阶D工作的?据,q个作用是显而易见的。Y件开发过E中软g开发h员需制定 一些工作计划或工作报告Q这些计划和报告都要提供l管理h员, q得到必要的支持。管理h员则可通过q些文档了解软g开发项 目安排、进度、资源用和成果{。Y件开发h员需为用户了解Y 件的使用、操作和l护提供详细的资料,我们U此为用h档。以 上三U文档构成了软g文档的主要部分。我们把q三U文档所?括的内容列在?中。其中列举了十三个文档,q里对它们作 一些简要说明:

可行性研I报?/STRONG>Q说明该软g开发项目的实现在技术上、经 上和社会因素上的可行性,评述Z合理地达到开发目标可?选择的各U可能实施的ҎQ说明ƈ所选定实施Ҏ的理 由?BR> 
目开发计?/STRONG>Qؓ软g目实施Ҏ制定出具体计划,?该包括各部分工作的负责h员、开发的q度、开发经费的预算、所 需的硬件及软g资源{。项目开发计划应提供l管理部门,q作 为开发阶D评审的参考?

软g需求说明书Q也UY件规D明书Q其中对所开发Y 件的功能、性能、用L面及q行环境{作l的说明。它是用 户与开发h员双方对软g需求取得共同理解基上达成的协议Q?也是实施开发工作的基础?

数据要求说明?/STRONG>Q该说明书应l出数据逻辑描述和数据采 集的各项要求Qؓ生成和维?pȝ数据文卷作好准备?

概要设计说明?/STRONG>Q该?明书是概要设计阶D늚工作 成果Q它应说明功能分配、模 块划分、程序的Ml构、输 入输Z及接口设计、运行设 计、数据结构设计和出错处理 设计{,l设计奠定基 ?BR>
 详细设计说明?/STRONG>Q着?描述每一模块是怎样实现的, 包括实现法、逻辑程{?

用户手册Q本手册详细 描述软g的功能、性能和用?界面Q用户了解如何使用该Y件?BR>
文档 用户文档 用户手册
操作手册
l护修改
软g需求(规格Q说明书
开发文?/TD> 软g需求(规格Q说明书
数据要求说明?/TD>
概要设计说明?/TD>
详细设计说明?/TD>
可行性研I报?/TD>
目开发计?/TD>
理文档 目开发计?/TD>
试计划
试报告
开发进度月?/TD>
开发ȝ报告

?.3 三种文档

操作手册Q本手册为操作h员提供该软g各种q行情况?有关知识Q特别是操作Ҏ的具体细节?

试计划Qؓ做好l装试和确认测试,需为如何组l测?制定实施计划。计划应包括试的内宏V进度、条件、h员、测试用 例的选取原则、测试结果允许的偏差范围{?

试分析报告Q测试工作完成以后,应提交测试计划执?情况的说明。对试l果加以分析Qƈ提出试的结论意见?

开发进度月报:该月报系软g人员按月向管理部门提交的 目q展情况报告。报告应包括q度计划与实际执行情늚比较?阶段成果、遇到的问题和解决的办法以及下个月的打算{?

目开发ȝ报告QY仉目开发完成以后,应与目?施计划对照,ȝ实际执行的情况,如进度、成果、资源利用、成?和投入的人力。此外还需对开发工作作Pȝ出经验和?训?

l护修改QY件品投入运行以后,发现了需对其q?行修正、更改等问题Q应存在的问题、修改的考虑以及修改的媄 响估计作详细的描qͼ写成l护修改Q提交审扏V?以上q些文档是在软g生存期中Q随着各阶D工作的开展?时编制。其中有的仅反映一个阶D늚工作Q有的则需跨越多个?Dc表5l出了各个文档应在Y件生存期中哪个阶D늼写。这 些文档最l要向Y件管理部门,或是向用户回{以下的问题Q?BR>?.2 软g生存期各阶段~制的文?

阶段

文档        

可行性药酒与计划 需求分?/TD> 设计 代码~写 q行与维?/TD>
可行性研I报?/TD>            
目开发计?/TD>            
软g需求说?/TD>            
数据要求说明            
概要设计说明            
星系设计说明            
试计划            
用户手册            
操作手册            
试分析报告            
开发进度月?/TD>            
目开发ȝ            
l护修改            



哪些需求要被满I卛_{“做什??

所开发的软g在什么环境中实现以及所需信息从哪里来Q?卛_{“从何处??

某些开发工作的旉如何安排Q即回答“何时干??

某些开?或维?工作打算由“谁来干??

某些需求是怎么实现?

Z么要q行那些软g开发或l护修改工作?

    上述十三个文档都在一定程度上回答了这六个斚w的问题。这可从表中看到?/P>

?.3 文档所回答的问?/P>

     所提问?/P>

文档 

什?/CENTER>
何处
何时
?/CENTER>
如何
Z
可行性研I报?/CENTER>
?/FONT>
 
 
 
 
?/FONT>
目开发计?/CENTER>
?/FONT>
 
?/FONT>
?/FONT>
 
 
软g需求说?/CENTER>
?/FONT>
?/FONT>
 
 
 
 
数据要求说明
?/FONT>
?/FONT>
 
 
 
 
概要设计说明
 
 
 
 
?/FONT>
 
详细设计说明
 
 
 
 
?/FONT>
 
试计划
 
 
?/FONT>
?/FONT>
?/FONT>
 
用户手册
 
 
 
 
?/FONT>
 
操作手册
 
 
 
 
?/FONT>
 
试分析报告
?/FONT>
 
 
 
 
 
开发进度月?/CENTER>
?/FONT>
 
?/FONT>
 
 
 
目开发ȝ
?/FONT>
 
 
 
 
 
l护修改
?/FONT>
 
 
?/FONT>
 
?/FONT>

    xQ我们对文档的作用有了进一步的理解。每一个文档的?务也是明的QQ何一个文档都此是多余的?/P>

扑扑 2005-09-02 10:29 发表评论
]]> վ֩ģ壺 պƷһ| ޳AVƬ| ˿wwwƵ| þþƷۺ| ѿοһ| һһһˬһһƵѵ| ޹Ʒר| Ƶ| պӰ߹ۿվ| ߹ۿ| þþƷ69Ʒ| Ұ߹ۿ3 | һƵ| ձ㽶ƵۿƵ| ޾ƷƷ벻| ɫվַ| һ3Ƶ| 91Ʒ鶹ϵ| ҳ˿| վɫѿ| ˳վ߹ۿ | Ƭ߹ۿѴȫ| һaƵ| | ŷ޹Ʒ㶮| ޹ۺһ | ԻƵ30ӳ| wwwѻɫ| պƷĻ| һ| ۺϹһ | СƵ߲| 97ۺɫ| ˬִ̼ëƬ| 鶹ƷƵ| Ʒ99Ʒþ| fc2˳ΪƵ| þAV| ѻɫַ| ޹þ| ޾ƷƷ|