posts - 64,comments - 22,trackbacks - 0
1  $(document).ready(function () {
2    $('#test tr').each(function (){    
3        alert($(this).children('td').eq(1).html());
4             });
5         });
posted @ 2012-03-22 12:07 hellxoul 阅读(6831) | 评论 (4)编辑 收藏
鉴于项目需要,开始边看Demo边使用JQuery。现将项目中暂时遇到的三种使用JQuery进行Ajax提交的方式做个总结。因为没有系统学习,有点山寨,只求在项目中实现功能。
    1.URL+GET参数提交
       这种方式是最普遍的,只要包含jquery.js就可以正常使用。
     
Java代码  收藏代码
  1. $.ajax({  
  2.     type: "get",  
  3.     url: "/openshop/control/getCustomerAddress",  
  4.     data:"customerId="+$.trim($("#customerId")[0].value),  
  5.     cache: false,  
  6.     success: function(msg){  
  7.           $("#addressInfo")[0].innerHTML = msg;  
  8.           showTipWindow(newid,oldid,0,e);  
  9.     }  
  10. });   
  11.      


    2.整个form的提交
        如果不使用JQuery的form ajax提交,则必须手动组装所有的表单元素键值对。现在使用JQuery的一个插件:jquery.form.js。将jquery.js,jquery.form.js文件都包含到项目中。然后使用如下代码:
      
Java代码  收藏代码
  1. $('#'+newid+'_frmNewAddr').ajaxForm({ beforeSubmit: validate ,success: showResponse});  
  2.   
  3. ....  
  4.   
  5. function validate(formData, jqForm, options){  
  6.     var form = jqForm[0];   
  7.     if (!form.new_recipient.value ) {   
  8.         alert('收件人必须填写!');   
  9.         return false;   
  10.     }   
  11.     if (!form.new_address.value ) {   
  12.         alert('收件地址必须填写!');   
  13.         return false;   
  14.     }   
  15.   
  16.    ....  
  17.   
  18.    return true;   
  19. }  
  20.   
  21. function showResponse(responseText, statusText, xhr, $form){  
  22.     var address = eval("("+removeDivTag(responseText)+")");   
  23.     $("#address_recipient")[0].innerHTML = address.recipient;  
  24.     $("#address_address")[0].innerHTML = address.address;  
  25.     $("#address_organization")[0].innerHTML = address.organization;  
  26.          ......  
  27. }  
  28.          

      其中$('#'+newid+'_frmNewAddr')获取表单对象,其中beforeSubmit对应的validate()是一个表单提交前调用 的方法,可以在此方法中做表单验证,只有该方法返回true,表单才会提交。而success对应的showResponse则是ajax对象成功返回后 的回调方法,可以将回调得到的内容无刷新呈现到当前页面的相应区域中。较方便的做法是在服务器端以JSON格式返回数据,然后在回调函数中使用 eval("("+removeDivTag(responseText)+")")方法获取具有指定结构的js对象。

     3.使用JQuery做文件上传的ajax提交
     本人寻找并比较了多种ajax或类ajax方式上传文件的做法,譬如使用iframe等。最终觉得使用JQuery是最方便的,不知各位使用后是否与我有 同感。我将我目前的做法总结如下,首先须在项目中包含jquery.js,ajaxfileupload.js,ajaxfileupload.css。
Java代码  收藏代码
  1. <script type="text/javascript">  
  2. function ajaxFileUpload(imgName)  
  3. {  
  4.     $("#loading")  
  5.     .ajaxStart(function(){  
  6.         $(this).show();  
  7.     })  
  8.     .ajaxComplete(function(){  
  9.         $(this).hide();  
  10.     });  
  11.   
  12.     $.ajaxFileUpload  
  13.     (  
  14.         {  
  15.             url:'/productmgr/control/uploadProductImg',  
  16.             secureuri:false,  
  17.             fileElementId: imgName+'File',  
  18.             dataType: 'text',  
  19.             success: function (data, status)  
  20.             {  
  21.                 data = removeDivTag(data);  
  22.                 if(data=="ImgEmptyErr"){  
  23.                     alert("请选择上传图片!");  
  24.                     return;  
  25.                 }  
  26.                 if(data=="sysErr"){  
  27.                     alert("上传失败,请重试!");  
  28.                     return;  
  29.                 }  
  30.                 $("#"+imgName)[0].value = data;  
  31.                 $("#"+imgName+"Div")[0].innerHTML = "上传成功!"  
  32.                 //alert($("#"+imgName)[0].value);  
  33.             },  
  34.             error: function (data, status, e)  
  35.             {  
  36.                 alert("添加产品图片时发生如下错误:"+e);  
  37.             }  
  38.         }  
  39.     )     
  40.     return false;  
  41.   
  42. }  
  43. </script>  

      本人服务器端使用的是beanshell脚本,代码如下:
Java代码  收藏代码
  1. /* 
  2.  * 产品图片上传 
  3.  *  
  4.  * author : Emerson 
  5.  * 
  6.  * Yiihee , Inc. */  
  7.   
  8.   
  9. import org.ofbiz.base.util.*;  
  10. import org.ofbiz.base.util.string.*;  
  11. import org.ofbiz.entity.*;  
  12. import java.text.SimpleDateFormat;  
  13. import java.util.*;  
  14. import java.io.*;  
  15. import org.apache.commons.fileupload.disk.*;  
  16. import org.apache.commons.fileupload.servlet.*;  
  17. import org.apache.commons.fileupload.*;  
  18.   
  19.   
  20.     configProperties = UtilProperties.getProperties("opencommon.properties");  
  21.     String imageUploadServerPath = configProperties.get("openb2c.image.upload.server.path");  
  22.   
  23.     //SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmss");     
  24.     //Date date = new Date();     
  25.     //String filename = sf.format(date);  
  26.     String fileName;  
  27.   
  28.     File uploadPath = new File(imageUploadServerPath);//上传文件目录  
  29.     if (!uploadPath.exists()) {  
  30.        uploadPath.mkdirs();  
  31.     }  
  32.     // 临时文件目录  
  33.     File tempPathFile = new File(imageUploadServerPath+"\\temp\\");  
  34.     if (!tempPathFile.exists()) {  
  35.        tempPathFile.mkdirs();  
  36.     }  
  37.     try {  
  38.        // Create a factory for disk-based file items  
  39.        DiskFileItemFactory factory = new DiskFileItemFactory();  
  40.    
  41.        // Set factory constraints  
  42.        factory.setSizeThreshold(4096); // 设置缓冲区大小,这里是4kb  
  43.        factory.setRepository(tempPathFile);//设置缓冲区目录  
  44.    
  45.        // Create a new file upload handler  
  46.        ServletFileUpload upload = new ServletFileUpload(factory);  
  47.    
  48.        // Set overall request size constraint  
  49.        upload.setSizeMax(4194304); // 设置最大文件尺寸,这里是4MB  
  50.    
  51.        List items = null;  
  52.        items = upload.parseRequest(request);//得到所有的文件  
  53.          
  54.        if(items==null||items.size()==0){  
  55.            String msg = "ImgEmptyErr";  
  56.            context.put("result", msg);  
  57.            return;  
  58.        }  
  59.          
  60.        Iterator i = items.iterator();  
  61.          
  62.        //此处实际只有一个文件  
  63.        while (i.hasNext()) {  
  64.            FileItem fi = (FileItem) i.next();  
  65.            fileName = fi.getName();  
  66.            if (!UtilValidate.isEmpty(fileName)) {  
  67.                File fullFile = new File(fi.getName());  
  68.                //File fullFile = new File(filename);  
  69.                File savedFile = new File(uploadPath, fullFile.getName());  
  70.                int j = 0;  
  71.                while(savedFile.exists()){  
  72.                    j++;  
  73.                    savedFile = new File(uploadPath, savedFile.getName().substring(0,savedFile.getName().lastIndexOf(".")-1)+"("+j+")"+savedFile.getName().substring(savedFile.getName().lastIndexOf("."),savedFile.getName().length()));  
  74.                }  
  75.                fi.write(savedFile);  
  76.                fileName = savedFile.getName();  
  77.            }else{  
  78.                String msg = "ImgEmptyErr";  
  79.                context.put("result", msg);  
  80.                return;  
  81.            }             
  82.        }  
  83.        context.put("result", fileName);  
  84.     } catch (Exception e) {  
  85.         Debug.log("上传产品图片发生错误:"+e);  
  86.         String msg = "sysErr";  
  87.         context.put("result", msg);  
  88.         return;  
  89.     }  

  然后将result结果渲染到freemarker模板,并经回调函数解析后展示给用户。

总结:JQuery强大异常,本文仅从自身使用角度列举了其部分用法,未曾深究最新最优最简用法,暂以此文作为经验总结,以待日后参考修正。代码片段山寨之处实属本人技拙,而非JQuery之过。   
posted @ 2012-03-22 12:04 hellxoul 阅读(6992) | 评论 (1)编辑 收藏
    <html>  
    <head>  
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.0/jquery.min.js"></script>
    <title>表格</title>  
    <style type="text/css">  
    .editText  
    {  
        border-width:1px;  
        border-top-style:none;  
        border-left-style:none;  
        border-right-style:none;  
        border-bottom-style:solid;  
        border-color:#030;  
        width:100%;  
    }  
    </style>  
    <script src="jquery-1.3.2.js" type="text/javascript">  
    </script>  
    <script type="text/javascript">  
    function moveUp(obj)  
    {  
        var current=$(obj).parent().parent();  
        var prev=current.prev();  
        if(prev)  
        {  
            current.insertBefore(prev);  
        }  
    }  
    function moveDown(obj)  
    {  
        var current=$(obj).parent().parent();  
        var next=current.next();  
        if(next)  
        {  
            current.insertAfter(next);  
        }  
    }  
    </script>  
    </head>  
    <body>  
    <table class="grid" width="100%" border="1" cellspacing="0" cellpadding="0">  
      <tr>  
        <td>字段英文名</td>  
        <td>字段中文名</td>  
        <td>字段数据类型</td>  
        <td>列宽</td>  
        <td>是否显示</td>  
        <td>是否作为查询条件</td>  
        <td>调整顺序</td>  
      </tr>  
      <tr>  
        <td>1</td>  
        <td><input type="text" name="textfield" class="editText" id="textfield"></td>  
        <td> </td>  
        <td><input type="text" name="textfield5" id="textfield5"></td>  
        <td><input type="checkbox" name="checkbox" id="checkbox"></td>  
        <td><input type="checkbox" name="checkbox5" id="checkbox5"></td>  
        <td><a href="javascript:void(0)" onClick="moveUp(this)">上移</a><a href="javascript:void(0)" onClick="moveDown(this)">下移</a></td>  
      </tr>  
      <tr>  
        <td>2</td>  
        <td><input type="text" name="textfield2" id="textfield2"></td>  
        <td> </td>  
        <td><input type="text" name="textfield6" id="textfield6"></td>  
        <td><input type="checkbox" name="checkbox2" id="checkbox2"></td>  
        <td><input type="checkbox" name="checkbox6" id="checkbox6"></td>  
        <td><a href="javascript:void(0)" onClick="moveUp(this)">上移</a><a href="javascript:void(0)" onClick="moveDown(this)">下移</a></td>  
      </tr>  
      <tr>  
        <td>3</td>  
        <td><input type="text" name="textfield3" id="textfield3"></td>  
        <td> </td>  
        <td><input type="text" name="textfield7" id="textfield7"></td>  
        <td><input type="checkbox" name="checkbox3" id="checkbox3"></td>  
        <td><input type="checkbox" name="checkbox7" id="checkbox7"></td>  
        <td><a href="javascript:void(0)" onClick="moveUp(this)">上移</a><a href="javascript:void(0)" onClick="moveDown(this)">下移</a></td>  
      </tr>  
      <tr>  
        <td>4</td>  
        <td><input type="text" name="textfield4" id="textfield4"></td>  
        <td> </td>  
        <td><input type="text" name="textfield8" id="textfield8"></td>  
        <td><input type="checkbox" name="checkbox4" id="checkbox4"></td>  
        <td><input type="checkbox" name="checkbox8" id="checkbox8"></td>  
        <td><a href="javascript:void(0)" onClick="moveUp(this)">上移</a><a href="javascript:void(0)" onClick="moveDown(this)">下移</a></td>  
      </tr>  
    </table>  
    </body>  
    </html> 
posted @ 2012-03-22 12:02 hellxoul 阅读(2069) | 评论 (0)编辑 收藏
if($ ("#id")){

}else{}

jquery不管对象存不存在都会返回object。

应该用

if($ ("#id").length>0){}else{}

or     

 if($ ("#id")[0]){    } else {   }

or 

 if(document.getElementById("id")){} else {}

posted @ 2012-03-22 12:01 hellxoul 阅读(376) | 评论 (1)编辑 收藏

不可否认,OFBiz这个开源的系统功能是非常强大的,涉及到的东西太多了,其实对我们现在而言,最有用的只有这么几个:实体引擎、服务引擎、WebTools、用户权限管理。

最先要提醒各位的是,在配置一个OFBiz时,路径中千万不要包含空格,要不然老提示出错,无外乎是scoket write error之类的信息,会让你郁闷得不停^_^

用户登录鉴权这一块我们完全可以照搬OFBiz现有的东西,其实也就是调用包org.ofbiz.securityext.login.LoginEvents里面的一些方法来进行处理。

Component定义:component-load.xml,可根据需要调整需在启动时引入的Component,比如增加一个Study,定义:

<load-component component-location="${ofbiz.home}/components/study"/>



首先需要进行如下几个项目的总体配置:

1、 entityengine.xml:实体引擎配置,主要是配置该数据的方式,如通过oracle访问,就配置一下localoracle,特别需要注意的 是,在dataSource中配置中,一定要配置一个属性 - schema-name="OFBIZ",这个主要是为了在OFBiz启动时能够正常同数据库的对象进行匹配,如果没有进行配置,每次都会试图重新建立对 象,会报对象名已经被占用的情况。

2、 serviceengine.xml:服务引擎配置,这个基本上不用作太大的修改,如要必要,可在这里边进行一些参数的调优,比如访问线程数配置等。

之后需要在components目录下新建一个目录study,目录里面的一些文件可直接从模板中拷贝,之后再进行必要的修改,涉及修改内容:
1、 entitygroup.xml & entitymodel 实体定义(3.0版本开始,各实体定义可在各自的Component下定义,而不必统一集中在commonapp下);定义实体及实体的相关属性(其实也 就是相当于数据库的各种对象,需要注意的是,后续进行数据提取时,如果需要关联到多张表,也需要在这里面定义一个view-entity);

2、 services.xml:如果必要的话,可以这里边定义一些服务;

3、 data:一些初始配置数据,应该是相对固定,不经常变动的才放在这边,可通过Webtool工具导入到数据库中;

4、 src:如改动了一些Java源文件内容后,需要重新编译该目录的文件,可通过UltraEdit的工具配置来进行ant编译,非常方便,推荐使用,编译 后的文件将生成到build目录下,生成的文件有各个class文件,也有一些.jar包(放在lib目录下),这些jar包是我们在Web应用中需要引 用到的,当然,引用哪些包也是可配置的,下面会讲到;

5、 ofbiz-component.xml:主要的配置文件,需要注意的一些东西:

(1)<classpath type="jar" location="build/lib/*"/> 这是jar引用路径,我在考虑是否可改成直接引用class文件,也就是直接设置class文件所在的目录;

(2)title="Study" 这个就是我们通过appbar.ftl文件在主界面显示的那一排按钮上显示的内容,可根据需要调整,调整完要重启OFBiz,麻烦,可以考虑通过hot-deploy目录进行发布。

至于其他一些配置,很简单,看看就晓得。

下 面讲一下Web应用配置,Web应用配置中涉及到的最重要的两个文件是:controller.xml和regions.xml, controller.xml文件主要是配置request-map,也就是请求映射关系,所有的请求映射都需要在这里边进行配置,也就是我们在Web页 面上常看到的/login等,如果涉及到view-map类型是region,就需要从region.xml文件中去读取配置,其实也就是配置各个 region引用的处理页面(可以是各种开发语言,比如Jsp、ftl等等)。另外,在region.xml配置文件中最重要的一部分就是 MAIN_REGION的配置,就是整个网页布局的配置,包括header、appbar、error、content、footer等等,其中 appbar就是我们在前面刚刚提到的主界面上那一排按钮的配置了,header、footer和error太简单,不说了,我们主要要修改的东西都是在 content这一块上进行展现。
网页中用到的一些样式、公用的定义都是在main_template.jsp中写入的,也需要在MAIN_REGION的属性中配置引用的文件。样式定义文件是引用images这个component,所以这个也是关键,不能缺的。

最 后,讲一讲我对数据库访问的一些简单的了解:对数据库的访问主要是通过GenericDelegator进行控制,包括一些常用的方法,如 findAll、remove、store、create等等,具体的用法要去研究一下,其实也不算复杂,先建立一个GenericDelegator, 如果是create、store就可以通过makeValue方法将一些字段的值设置到GenericValue,之后再进行store或是 create,具体语法要去参考一些文档,还没去看这一块的东西。

最最需要访问的一些文档:OFBizChina 实体引擎配置指南、OFBizChina 区块(Region)指南、OFBizChina 服务引擎配置指南、OFBizChina JSP标签库指南,当然,研究OFBiz的前提是要首先要理解MVC模式的概念,也就是View-Model-Control,否则一切都是空谈。

补充几点:
1、 对于Ofbiz构造动态查询语句
(1) 构造查询条件
(2) 给每个条件之间加上逻辑关系,用mainCond = new EntityConditionList(andExprs, EntityOperator.AND);
(3) 设置要显示的字段列表
(4) 设置排序字段列表
(5) 设置Distinct列表
EntityFindOptions findOpts = new EntityFindOptions(true, EntityFindOptions.TYPE_SCROLL_INSENSITIVE, EntityFindOptions.CONCUR_READ_ONLY, true);
(6) 获取实体列表
EntityListIterator pli = delegator.findListIteratorByCondition(entityName, mainCond, null, fieldsToSelect, orderBy, findOpts);
(7) 一个动态查询语句的具体实例
<%
String entityName="study";
List andExprs = new ArrayList();
String number="";
String name="";
String sex="";
String tel="";
//GenericDelegator delegator = GenericDelegator.getGenericDelegator("default");
EntityConditionList mainCond=null;
if (request.getParameter("number")!=null)
number=request.getParameter("number").toString();
if (request.getParameter("name")!=null)
name=request.getParameter("name").toString();
if (request.getParameter("sex")!=null)
sex=request.getParameter("sex").toString();
if (request.getParameter("tel")!=null)
tel=request.getParameter("tel").toString();
//构造查询条件
if (number.compareTo("")!=0)
andExprs.add(new EntityExpr("number",EntityOperator.EQUALS,number));
if (name.compareTo("")!=0)
andExprs.add(new EntityExpr("name1",true,EntityOperator.LIKE,"%"+name+"%",true));
if (sex.compareTo("")!=0)
andExprs.add(new EntityExpr("sex1",true,EntityOperator.LIKE,"%"+sex+"%",true));
if (tel.compareTo("")!=0)
andExprs.add(new EntityExpr("tel",true,EntityOperator.LIKE,"%"+tel+"%",true));
//每个条件间的逻辑关系
if (andExprs.size() > 0)
mainCond = new EntityConditionList(andExprs, EntityOperator.AND);
//要显示的字段列表
List fieldsToSelect = new ArrayList();
fieldsToSelect.add("number");
fieldsToSelect.add("name1");
fieldsToSelect.add("sex1");
fieldsToSelect.add("tel");
//排序字段列表
List orderBy = UtilMisc.toList("number", "name1");
//Distinct列表
EntityFindOptions findOpts = new EntityFindOptions(true, EntityFindOptions.TYPE_SCROLL_INSENSITIVE, EntityFindOptions.CONCUR_READ_ONLY, true);
//获取实体列表
EntityListIterator pli = delegator.findListIteratorByCondition(entityName, mainCond, null, fieldsToSelect, orderBy, findOpts);
while(pli.hasNext())
{
GenericValue cust = (GenericValue)pli.next();%>
<tr>
<td><%=cust.getString("number")%></td>
<td><%=cust.getString("name1")%></td>
<td><%=cust.getString("sex1")%></td>
<td><%=cust.getString("tel")%></td>
</tr>
<%}%>

</table>

2、 对于所有的图片文件,都放在images目录下
3、 设置图片的标签<ofbiz:contenturl>图片路径</ofbiz:contenturl>
4、 链接Tag <ofbiz:url>control.xml里面设置的请求</ofbiz.url>
5、 <region:render section=‘header‘/>引入header定义的文件
header这个标识在regions.xml里面定义
<define id=‘MAIN_REG‘ template=‘/templates/main_template1.jsp‘>
<put section=‘title‘>Application Page</put> <!-- this is a default and is meant to overridden -->
<put section=‘header‘ content=‘/includes/bottom.jsp‘/>
<put section=‘leftbar‘ content=‘/includes/left.jsp‘/>
<put section=‘middle‘ content=‘/includes/middle.jsp‘/>
<put section=‘content‘ content=‘/includes/middle.jsp‘/> <!-- this is a default and is meant to overridden -->
<put section=‘top‘ content=‘/includes/top.jsp‘/>
<put section=‘error‘ type="jpublish" content=‘/includes/errormsg.ftl‘/>
<!--<put section=‘footer‘ type="jpublish" content=‘/includes/footer.ftl‘/>-->
</define>
然后其它页面只要如下定义即可
<define id=‘BasePubEmp‘ region=‘MAIN_REG‘>
<put section=‘title‘>View BasePubEmp</put>
<put section=‘content‘ content=‘/BasePubEmp.jsp‘/>
</define>
注意,这边的content所指定的区块就是我们上面定义的content
6、 这些标签都挺简单的,Ofbiz里面都有例子,参照一下就可以了

后续将对Ofbiz中的shark工作流进行描述。
http://www.cnpoint.com/mvnforum/mvnforum/viewthread?thread=67

posted @ 2012-03-21 11:47 hellxoul 阅读(2416) | 评论 (0)编辑 收藏
ofbiz 之entity实体
1. 实体定义文件
实体定义文件一般存放位置是在对应模块的entity文件夹下面,以party为例,party的实体定义文件路径为%ofbiz-home%\applications\party\entitydef\entitymodel.xml。
通过对应模块的ofbiz-component.xml进行加载。
   <entity-resource type="model" reader-name="main" loader="main" location="entitydef/entitymodel.xml"/>
<entity-resource type="model" reader-name="main" loader="main" location="entitydef/entitymodel_old.xml"/>
实体定义文件可以为多个。
2. 实体类型
2.1. 普通实体
<entity entity-name="TenantDataSource" package-name="org.ofbiz.entity.tenant">
        <description>
            There should be one record for each tenant and each group-map for the active delegator.
            The jdbc fields will override the datasource -> inline-jdbc values for the per-tenant delegator.
        </description>
        <field name="tenantId" type="id-ne"/>
        <field name="entityGroupName" type="name"/>
        <field name="jdbcUri" type="long-varchar"/>
        <field name="jdbcUsername" type="long-varchar"/>
        <field name="jdbcPassword" type="long-varchar"></field>
        <prim-key field="tenantId"/>
        <prim-key field="entityGroupName"/>
        <relation type="one" fk-name="TNTDTSRC_TNT" rel-entity-name="Tenant">
        <key-map field-name="tenantId"/>
        </relation>
</entity>
普通实体和数据库中的表是一一对应的。程序会根据实体定义在数据库中创建表,索引,外键约束等。
2.2. 视图实体
<view-entity entity-name="WorkEffortAssocView"
            package-name="org.ofbiz.workeffort.workeffort"
            title="Work Effort Association Entity with Name">
      <member-entity entity-alias="WA" entity-name="WorkEffortAssoc"/>
      <member-entity entity-alias="WETO" entity-name="WorkEffort"/>
      <alias-all entity-alias="WA"/>
      <alias entity-alias="WETO" name="workEffortToName" field="workEffortName"/>
      <alias entity-alias="WETO" name="workEffortToSetup" field="estimatedSetupMillis"/>
      <alias entity-alias="WETO" name="workEffortToRun" field="estimatedMilliSeconds"/>
      <alias entity-alias="WETO" name="workEffortToParentId" field="workEffortParentId"/>
      <alias entity-alias="WETO" name="workEffortToCurrentStatusId" field="currentStatusId"/>
      <alias entity-alias="WETO" name="workEffortToWorkEffortPurposeTypeId" field="workEffortPurposeTypeId"/>
      <alias entity-alias="WETO" name="workEffortToEstimatedStartDate" field="estimatedStartDate"/>
      <alias entity-alias="WETO" name="workEffortToEstimatedCompletionDate" field="estimatedCompletionDate"/>
      <alias entity-alias="WETO" name="workEffortToActualStartDate" field="actualStartDate"/>
      <alias entity-alias="WETO" name="workEffortToActualCompletionDate" field="actualCompletionDate"/>
      <view-link entity-alias="WA" rel-entity-alias="WETO">
        <key-map field-name="workEffortIdTo" rel-field-name="workEffortId"/>
      </view-link>
      <relation type="one-nofk" fk-name="WK_EFFRTASSV_FWE" title="From" rel-entity-name="WorkEffort">
        <key-map field-name="workEffortIdFrom" rel-field-name="workEffortId"/>
      </relation>
</view-entity>
View entity 一般用做多表连接复杂查询,view entity 不会在数据库中反映出来。
2.3. 扩展实体
<extend-entity entity-name="UserLogin">
        <field name="partyId" type="id"></field>
        <relation type="one" fk-name="USER_PARTY" rel-entity-name="Party">
            <key-map field-name="partyId"/>
        </relation>
        <relation type="one-nofk" rel-entity-name="Person">
            <key-map field-name="partyId"/>
        </relation>
        <relation type="one-nofk" rel-entity-name="PartyGroup">
            <key-map field-name="partyId"/>
        </relation>
</extend-entity>
继承已存在的实体并对其进行扩展。
2.4. 动态实体
DynamicViewEntity salesUsageViewEntity = new DynamicViewEntity();
            salesUsageViewEntity.addMemberEntity("OI", "OrderItem");
            salesUsageViewEntity.addMemberEntity("OH", "OrderHeader");
            salesUsageViewEntity.addMemberEntity("ItIss", "ItemIssuance");
            salesUsageViewEntity.addMemberEntity("InvIt", "InventoryItem");
            salesUsageViewEntity.addViewLink("OI", "OH", Boolean.valueOf(false), ModelKeyMap.makeKeyMapList("orderId"));
            salesUsageViewEntity.addViewLink("OI", "ItIss", Boolean.valueOf(false), ModelKeyMap.makeKeyMapList("orderId", "orderId", "orderItemSeqId", "orderItemSeqId"));
            salesUsageViewEntity.addViewLink("ItIss", "InvIt", Boolean.valueOf(false), ModelKeyMap.makeKeyMapList("inventoryItemId"));
    salesUsageViewEntity.addAlias("OI", "productId");
    salesUsageViewEntity.addAlias("OH", "statusId");
    salesUsageViewEntity.addAlias("OH", "orderTypeId");
    salesUsageViewEntity.addAlias("OH", "orderDate");
    salesUsageViewEntity.addAlias("ItIss", "inventoryItemId");
    salesUsageViewEntity.addAlias("ItIss", "quantity");
salesUsageViewEntity.addAlias("InvIt", "facilityId");
EntityListIterator salesUsageIt = delegator.findListIteratorByCondition(salesUsageViewEntity,
EntityCondition.makeCondition(
UtilMisc.toList(
         EntityCondition.makeCondition("facilityId", EntityOperator.EQUALS, facilityId),
          EntityCondition.makeCondition("productId", EntityOperator.EQUALS, productId),
            EntityCondition.makeCondition("statusId",
EntityOperator.IN,
UtilMisc.toList("ORDER_COMPLETED", "ORDER_APPROVED", "ORDER_HELD")),
        EntityCondition.makeCondition("orderTypeId", EntityOperator.EQUALS, "SALES_ORDER"),
           EntityCondition.makeCondition("orderDate", EntityOperator.GREATER_THAN_EQUAL_TO, checkTime)
),
EntityOperator.AND),null, null, null, null
);
在程序中手动创建实体,对其进行查询。
3实体定义
3.1. 命名规则
实体名称(entity-name)首字母大写,如果实体名称由多个关键字组成,那么关键字首字母大写,例如entity- name="TenantDataSource",ofbiz 会在创建数据库表的时候根据entity-name 实体名称除首字母之外的大写字母前加“_”,所以entity-name="TenantDataSource"生成的数据库表名为 “Tenant_Data_Source”.
所以要控制entity-name 实体名称不要超过25个字母。
Field 表字段,命名规则与实体名称差不多,唯一不同的是首字母小写。
3.2. 实体与数据库的关联
    <entity-group group="org.ofbiz.olap" entity="SalesInvoiceItemFact"/>
<entity-group group="org.ofbiz.olap" entity="SalesInvoiceItemStarSchema"/>
Entity-group(一般定义在各个模块的\entitydef\entitygroupXXX.xml中) 对实体进行分组,使不同的实体分属不同的entity-group。
也许你会发现并不是每个entity都进行了entity-group 分组。事实上如果你没有对实体进行分组归类的话,系统启动的时候他会将实体默认归类到"org.ofbiz"中。
查看数据库定义文件%ofbiz_home%/framework/entity/config/entityengine.xml
可以发现:
<delegator name="default" entity-model-reader="main" entity-group-reader="main" entity-eca-reader="main" distributed-cache-clear-enabled="false">
        <group-map group-name="org.ofbiz" datasource-name="localderby"/>
        <group-map group-name="org.ofbiz.olap" datasource-name="localderbyolap"/>
        <group-map group-name="org.ofbiz.tenant" datasource-name="localderbytenant"/>
</delegator>
可以发现delegator 将多个group-name组织到一起并将group-name与 datasource-name对应起来,datasource-name又是什么?通过查看 entityengine.xml 我们可以发现:
<datasource name="localderby"
            helper-class="org.ofbiz.entity.datasource.GenericHelperDAO"
            schema-name="OFBIZ"
            field-type-name="derby"
            check-on-start="true"
            add-missing-on-start="true"
            use-pk-constraint-names="false"
            use-indices-unique="false"
            alias-view-columns="false"
            use-order-by-nulls="true">
        <read-data reader-name="seed"/>
        <read-data reader-name="seed-initial"/>
        <read-data reader-name="demo"/>
        <read-data reader-name="ext"/>
        <inline-jdbc
                jdbc-driver="org.apache.derby.jdbc.EmbeddedDriver"
                jdbc-uri="jdbc:derby:ofbiz;create=true"
                jdbc-username="ofbiz"
                jdbc-password="ofbiz"
                isolation-level="ReadCommitted"
                pool-minsize="2"
                pool-maxsize="250"
                time-between-eviction-runs-millis="600000"/>
</datasource>
Datasource定义了数据库驱动,数据库用户名、密码等,所以datasource就是我们说的数据库。
总结一下:我们通过entity-group将各个实体和数据库之间关联起来,然后再将一个或多个数据库归属到一个delegator 中,那我们又是怎么使用数据库进行数据库操作的呢??查看每个模块应用底下的web.xml 我们可以发现:
<context-param>
        <param-name>entityDelegatorName</param-name>
        <param-value>default</param-value>
        <description>The Name of the Entity Delegator to use, defined in entityengine.xml</description>
</context-param>
针对不同的应用,我们可以使用不同的delegator .如果不定义则使用default.
在启动各个应用模块的时候,系统会根据web.xml 中的 entityDelegatorName
生成delegator 对象,然后将delegator 对象存放到servletContext 中备用。
我们就是使用这个delegator对象执行数据库操作,以后会介绍如何使用。
delegator = DelegatorFactory.getDelegator(delegatorName);
    servletContext.setAttribute("delegator", delegator);


3.3. no-auto-stamp
no-auto-stamp="false"
entity 属性之一: 将此值设置为true , 则 创建数据库表时将来不创建lastUpdatedStamp、lastUpdatedTxStamp、createdStamp、createdTxStamp
这四个字段。
3.4. Field.type
<field name="tenantId" type="id-ne"/>
Type , 将数据字段类型 与 java 类型关联起来的设置。 定义文件路径为:
%ofbiz_home%\framework\entity\fieldtype\fieldtypeXXXXX.xml
其中XXXX为你使用的数据库名称。
<field-type-def type="email" sql-type="VARCHAR(255)" java-type="String"/>
3.5. prim-key
<prim-key field="agreementId"/>
定义主键,其中field 需要是已经被定义过的字段,即field 定义过。
实体支持组合主键,即一个实体定义中可以有多个prim-key节点。
如果不定义主键的话,数据库是不会创建表的。

3.6. relation
relation 定义当前实体和其他实体之间的关系,一般用做创建外键和根据关系查询使用。
:rel-entity-name:被关联实体名称。
:fk-name:如果创建外键,那么定义外键的名称。
:title:给当前关系起个别名。
: field-name:当前实体的字段,指明当前实体的哪个字段与被关系实体有关系。
:rel-entity-name:被关系实体名称
:rel-field-name:被关系的实体的字段名称。指明field-name和被关系实体的哪个字段有关系。如果rel-field-name与field-name相同,那么rel-field-name可以不定义。
:type="one-nofk":关联类型,主要有三类 “one”、”one-nofk”、”many”
很多资料上将one 解释为 one-to-one ,将 many 解释为 one-to-many .
个人感觉不是很好理解,如果从数据库方面去理解的话,one、one-nofk  的使用条件是被关系实体的rel-field-name为主键,而many 的使用条件是被关系实体的rel-field-name为非主键。而one 与 one-nofk 的区别在于one会在数据库表结构中创建外键约束,而one-nofk 则不会。
Relation 除了用来创建外键约束之外还被用来做关系查询。
当访问关系的时候可以用 .getRelated("") 或者 .getRelatedOne("") 。用 title+entityName 作为参数。
当实体一个"many"关系的时候使用getRelated 返回一个列表,当实体一个"one"关系的时候使用getRelatedOne 返回一个实体对象。

3.7. Index
<index name="WEFF_KWD_KWD" unique="false">
            <index-field name="keyword" function="lower"/>
</index>
创建索引。
: name:给索引起个别名。
: unique:是否唯一索引。
:index-field:name:对实体哪个字段创建索引,function待确定。
4. 定义视图实体
4.1. Member-entity
<member-entity entity-alias="EMPPOS" entity-name="EmplPosition"/>
      <member-entity entity-alias="EMPPOSFUL" entity-name="EmplPositionFulfillment"/>
member-entity首先定义当前视图实体可能会用到的实体。entity-name实体名称
entity-alias实体别名。实体定义顺序很重要,除了第一个实体之外其他都是被关联实体。

4.2. alias
<alias entity-alias="EMPPOSFUL" name="partyId" field="partyId"/>
    <alias entity-alias="EMPPOSFUL" name="emplPositionId" function="count"/>
<alias entity-alias="EMPPOSREPST" name="emplPositionIdReportingTo" group-by="true"/>

Alias 定义当前视图实体中会用到的字段。entity-alias为实体别名,指当前字段是哪个实体的,field实体字段名称,name字段别名。 group-by依据当前字段进行group-by 分组查询。function对当前字段执行function 函数处理 。
4.3. alias-all
<alias-all entity-alias="ODD" prefix="orderDate" group-by="true">
            <exclude field="dimensionId"/>
</alias-all>
alias-all 将某个实体的全部字段定义进来。Prefix定义以规定字段字符开头的字段。
Exclude 将实体中某些字段剔除出去。

4.4. View-link
<view-link entity-alias="SOIF" rel-entity-alias="ODD" rel-optional="false">
    <key-map field-name="orderDateDimId" rel-field-name="dimensionId"/>
   </view-link>
视图实体中relation 只能用来做关系查询。
而view-link 用来做 join 关联查询。在entityengine.xml中<datasource ..>元素当中的join-style属性当中设置你的数据库join语法。
: rel-optional:关联类型,默认是内连接,如果将此属性值设为true ,则为外连接

4.5. Entity-condition
<entity-condition>
     <order-by field-name="sequenceId"/>
</entity-condition>
待定

4.6. 复杂字段
<alias entity-alias="OI" name="quantityOrdered" function="sum">
          <complex-alias operator="-">
              <complex-alias-field entity-alias="OI" field="quantity" default-value="0"/>
              <complex-alias-field entity-alias="OI" field="cancelQuantity" default-value="0"/>
          </complex-alias>
</alias>
结果为:
Select  SUM((COALESCE(OI.QUANTITY, 0) - COALESCE(OI.CANCEL_QUANTITY, 0))) 。。。。。。
一个缺省值是一个良好的习惯,否则当他们之中有一个为空就会导致结果为空
  这个操作可以支持你使用数据库的所有函数例如  +, -, * 和 /,字符串连接符||。
你也可以添加一个 function="" 实现min, max, sum, avg, count, count-distinct, upper 和 lower 在 complex-alias-field中。比如:
<alias entity-alias="OI" >
      <complex-alias operator="-">
          <complex-alias-field entity-alias="OI" field="quantity" default-value="0" function="sum"/>
          <complex-alias-field entity-alias="OI" field="cancelQuantity" default-value="0"
function="sum"/>
      </complex-alias>
  </alias>
结果为SELECT (SUM(COALESCE(OI.QUANTITY,'0')) - SUM(COALESCE(OI.CANCEL_QUANTITY,'0')))
posted @ 2012-03-08 08:34 hellxoul 阅读(1061) | 评论 (0)编辑 收藏
* 保持实体名称少于25个字符
这个限制主要是为了Oracle只支持30字符以内的数据库对象名称,再加上OFBiz会自动在单词之间加上"_",所以就得出了这么个限制.

* 关联的工作方式
它们定义于entitymodel.xml文件中的<entity>段,示例如下:
      <relation type="one" fk-name="PROD_CTGRY_PARENT" title="PrimaryParent" rel-entity-name="ProductCategory">
        
<key-map field-name="primaryParentCategoryId" rel-field-name="productCategoryId"/>
      
</relation>
      
<relation type="many" title="PrimaryChild" rel-entity-name="ProductCategory">
        
<key-map field-name="productCategoryId" rel-field-name="primaryParentCategoryId"/>
      
</relation>
     type这个属性标签定义关联类型: "one"表示一对一,"many"表示从此实体引出的一对多关系
     fk-name的属性值是数据库外键名.为自己的外键命名是一个好的习惯,虽然如果你不设置此属性,OFiz也会自己建外建.
     rel-entity-name的属性值指向关联的实体名称
     title用来区分两个实体之间的多重关系
     <key-map>节点定义关联中使用到的字段.field-name指向本实体内的引用字段,rel-field-name定义关联的实体字段,你可以通过多个字段组合关联
     当你访问一个关联,你可以使用title+entityName作为参数调用.getRelated("")或.getRelatedOne("")方 法.在关联为"many"时使用.getRelated("")是恰当的,因为它返回一个List,同样在关联为"one"时通 过.getRelatedOne("")方法获得一个值.

* view-entities相关内容
view-entities的功能非常强大,它允许你可以创建一个join-like查询,即使你的数据库不支持join.
关于你数据库的join语法存放在entityengine.xml的datasource节点下的join-style属性中.
当你通过<view-link...>节点将两上实体连接起来时,记住:
1. 实体名称顺序是重要的
2. 默认的连接方式是inner join(即同样的值存在于两个实体类中),外连接需要使用rel-optional="true"
如果多个实体中拥有相同的字段名称,比如statusId,结果集中的statusId使用第一个实体中的该列,其它实体中的同名列将被丢弃.如果你想要 同时获得这些列,你需要通过在其之前加入<alias-all>节点,一个方式是使用<alias ..>节点来为不同实体的同名字段起别名,示例:
<alias entity="EntityOne" name="entityOneStatusId" field="statusId"/>
<alias entity="EntityTwo" name="entityTwoStatusId" field="statusId"/>
另一种方法是在<alias-all>节点中使用<exclude field="">,如下:
<alias-all entity-alias="EN">
  
<exclude field="fieldNameToExclude1"/>
  
<exclude field="fieldNameToExclude2"/>
</alias-all>

这样也可以排除掉很多不打算使用到的信息,特别是在一个非常大的表中查询时.
如果你打算执行类似于以下的查询语句时:
SELECT count(visitId) FROM GROUP BY trackingCodeId WHERE fromDate > '2005-01-01'
需要包含字段visitId以及function="count" 标签,trackingCodeId需加上group-by="true"标签,fromDate需要加上group-by="false"标签

在你进行查询时,有一件非常重要的事情需要注意,比如说delegator.findByCondition方法,你必须指定检出的字段列表,并且你不能 指定fromDate字段,否则你将得到一个错误.这就是为webtools不能够使用view-entities来查看的原因.

你可以查看applications/marketing/entitydef/entitymodel.xml的底部内容学习,及通过 applications/marketing/webapp/marketing/WEB-INF/actions/reports学习 beanshell脚本的调用.

* 我可以在entitymodel.xml文件中定义自己的view-entities吗?

不能, 你可以动态定义它们.你可以查看org.ofbiz.party.party.PartyServices中的findParty方法学习它的使用

* 如果为有效期间创建条件?

我们提供了一组非常有用的方法EntityUtil.getFilterByDateExpr ,它能返回一个EntityConditionList根据有效期间来筛选一个结果集.

* 如何在大数据结果集下工作

如果你检出一个大的数据结果集,你应当使用EntityListIterator通过迭代方式读取数据,而非List.
示例,如果你使用:

List products = delegator.findAll("Product");


你可能获得一个"java.lang.OutOfMemoryError". 这是由于你通过findAll, findByAnd, findByCondition等方法来获得一个大的内存数据结果集导致内存溢出. 在这种情况下, 应该使用EntityListIterator迭代方式来读取你的数据. 这个示例应改写成:

productsELI = delegator.findListIteratorByCondition("Product", new EntityExpr("productId", EntityOperator.NOT_EQUAL, null), UtilMisc.toList("productId"), null);

注意获得EntityListIterator的方法只用通过条件, 所以你需要将你的条件重写为EntityExpr (在此次情况下,productId是主键字段不可能为空的, 所以将返回所有Proudct实例,)或 EntityConditionList.

此方法参数中包含检出的字段(这里为productId)以及排序字段(这里不需要,所以赋了null)

你可以传递一个null作为EntityCondition参数来获得所有结果.然后这不一定在所有数据库下都能正常工作! 在maxdb及其它不常用的数据库下时你要小心使用这些高级功能.

* 如何使用EntityListIterator

当我们通过EntityListIterator迭代访问数据时, 通常是这样:

while ((nextProduct = productsELI.next()) != null) {
.
    
// operations on nextProduct
}


在EntityListIterator 中使用 .hasNext()方法是一种不经济的做法.

在你完成你的操作后,要记得关闭此迭代

productsELI.close();

* 如何查询无重结果集

当前只能通过list iterator方法并指定EntityFindOptions参数,示例如下:

     listIt = delegator.findListIteratorByCondition(entityName, findConditions,
            
null, // EntityConditions参数
             fieldsToSelectList,
             fieldsToOrderByList,  
            
            
//关键部分.   第一个true表示"specifyTypeAndConcur"
            
// 第二个true指完是一个滤重查询.   显然在实体引擎中只能通过这个方法来进行滤重查询
            new EntityFindOptions(true, EntityFindOptions.TYPE_SCROLL_INSENSITIVE, EntityFindOptions.CONCUR_READ_ONLY, true));

在minilang, 它会更简单:

  <entity-condition entity-name="${entityName}" list-name="${resultList}" distinct="true">
     
<select field="${fieldName}"/>
     .

原文:
http://hi.baidu.com/longer84/blog/item/dbf027cf6e58933af9dc6117.html
posted @ 2012-03-08 08:32 hellxoul 阅读(2236) | 评论 (1)编辑 收藏

“又 是一年毕业时”,看到一批批学子离开人生的象牙塔,走上各自的工作岗位;想想自己也曾经意气风发、踌躇满志,不觉感叹万千……本文是自己工作6年的经历沉 淀或者经验提炼,希望对所有的软件工程师们有所帮助,早日实现自己的人生目标。本文主要是关于软件开发人员如何提高自己的软件专业技术方面的具体建议,前 面几点旨在确定大的方向,算是废话吧。  
谨以此文献给那个自己为你奉献3年青春与激情的开发团队。还有团队成员:PPL、YT、YK 、TYF、LGL、CHL、CDY、CB、DPD。  
1、 分享第一条经验:“学历代表过去、能力代表现在、学习力代表未来。”其实这是一个来自国外教育领域的一个研究结果。相信工作过几年、十几年的朋友对这个道 理有些体会吧。但我相信这一点也很重要:“重要的道理明白太晚将抱憾终生!”所以放在每一条,让刚刚毕业的朋友们早点看到哈!
2、 一定要确定自己的发展方向,并为此目的制定可行的计划。不要说什么,“我刚毕业,还不知道将来可能做什么?”,“跟着感觉走,先做做看”。因为,这样的观 点会通过你的潜意识去暗示你的行为无所事事、碌碌无为。一直做技术,将来成为专家级人物?向管理方向走,成为职业经理人?先熟悉行业和领域,将来自立门 户?还是先在行业里面混混,过几年转行做点别的?这很重要,它将决定你近几年、十年内“做什么事情才是在做正确的事情!”。

3、 软件开发团队中,技术不是万能的,但没有技术是万万不能的!在技术型团队中,技术与人品同等重要,当然长相也比较重要哈,尤其在MM比较多的团队中。在软 件项目团队中,技术水平是受人重视和尊重的重要砝码。无论你是做管理、系统分析、设计、编码,还是产品管理、测试、文档、实施、维护,多少你都要有技术基 础。算我孤陋寡闻,我还真没有亲眼看到过一个外行带领一个软件开发团队成功地完成过软件开发项目,哪怕就一个,也没有看到。倒是曾经看到过一个“高学历的 牛人”(非技术型)带一堆人做完过一个项目,项目交付的第二天,项目组成员扔下一句“再也受不了啦!”四分五裂、各奔东西。那个项目的“成功度”大家可想 而知了。
4、 详细制定自己软件开发专业知识学习计划,并注意及时修正和调整(软件开发技术变化实在太快)。请牢记:“如果一个软件开发人员在1、2年内都没有更新过自 己的知识,那么,其实他已经不再属于这个行业了。”不要告诉自己没有时间。来自时间管理领域的著名的“三八原则”告诫我们:另外的那8小时如何使用将决定 你的人生成败!本人自毕业以来,平均每天实际学习时间超过2小时。  
5、 书籍是人类进步的阶梯,对软件开发人员尤其如此。书籍是学习知识的最有效途径,不要过多地指望在工作中能遇到“世外高人”,并不厌其烦地教你。对于花钱买 书,我个人经验是:千万别买国内那帮人出的书!我买的那些家伙出的书,!00%全部后悔了,无一本例外。更气愤的是,这些书在二手市场的地摊上都很难卖 掉。“拥有书籍并不表示拥有知识;拥有知识并不表示拥有技能;拥有技能并不表示拥有文化;拥有文化并不表示拥有智慧。”只有将书本变成的自己智慧,才算是 真正拥有了它。  
6、 不要仅局限于对某项技术的表面使用上,哪怕你只是偶尔用一、二次。“对任何事物不究就里”是任何行业的工程师所不应该具备的素质。开发Windows应用 程序,看看Windows程序的设计、加载、执行原理,分析一下PE文件格式,试试用SDK开发从头开发一个Windows应用程序;用VC++、 Delphi、Java、.Net开发应用程序,花时间去研究一下MFC、VCL、J2EE、.Net它们框架设计或者源码;除了会用J2EE、 JBoss、Spring、Hibernate等等优秀的开源产品或者框架,抽空看看大师们是如何抽象、分析、设计和实现那些类似问题的通用解决方案的。 试着这样做做,你以后的工作将会少遇到一些让你不明就里、一头雾水的问题,因为,很多东西你“知其然且知其所以然”!  
7、 在一种语言上编程,但别为其束缚了思想。“代码大全”中说:“深入一门语言编程,不要浮于表面”。深入一门语言开发还远远不足,任何编程语言的存在都有其 自身的理由,所以也没有哪门语言是“包治百病”的“灵丹妙药”。编程语言对开发人员解决具体问题的思路和方式的影响与束缚的例子俯拾皆是。我的经验是:用 面对对象工具开发某些关键模块时,为什么不可以借鉴C、C51、汇编的模块化封装方式?用传统的桌面开发工具(目前主要有VC++、Delphi)进行系 统体统结构设计时,为什么不可以参考来自Java社区的IoC、AOP设计思想,甚至借鉴像Spring、Hibernate、JBoss等等优秀的开源 框架?在进行类似于实时通信、数据采集等功能的设计、实现时,为什么不可以引用来自实时系统、嵌入式系统的优秀的体系框架与模式?为什么一切都必须以个 人、团队在当然开发语言上的传统或者经验来解决问题???“他山之石、可以攻玉”。  
8、 养成总结与反思的习惯,并有意识地提炼日常工作成果,形成自己的个人源码库、解决某类问题的通用系统体系结构、甚至进化为框架。众所周知,对软件开发人员 而言,有、无经验的一个显著区别是:无经验者完成任何任务时都从头开始,而有经验者往往通过重组自己的可复用模块、类库来解决问题(其实这个结论不应该被 局限在软件开发领域、可以延伸到很多方面)。这并不是说,所有可复用的东西都必须自己实现,别人成熟的通过测试的成果也可以收集、整理、集成到自己的知识 库中。但是,最好还是自己实现,这样没有知识产权、版权等问题,关键是自己实现后能真正掌握这个知识点,拥有这个技能。  
9、 理论与实践并重,内外双修。工程师的内涵是:以工程师的眼光观察、分析事物和世界。一个合格的软件工程师,是真正理解了软件产品的本质及软件产品研发的思 想精髓的人(个人观点、欢迎探讨)。掌握软件开发语言、应用语言工具解决工作中的具体问题、完成目标任务是软件工程师的主要工作,但从软件工程师这个角度 来看,这只是外在的东西,并非重要的、本质的工作。学习、掌握软件产品开发理论知识、软件开发方法论,并在实践中理解、应用软件产品的分析、设计、实现思 想来解决具体的软件产品研发问题,才是真正的软件工程师的工作。站在成熟理论与可靠方法论的高度思考、分析、解决问题,并在具体实践中验证和修正这些思想 与方式,最终形成自己的理论体系和实用方法论。  
10、心态有多开放,视野就有多开阔。不要抱着自己的技术和成果,等到它们都已经过时变成垃圾 了,才拿出来丢人现眼。请及时发布自己的研究成果:开发的产品、有创意的设计或代码,公布出来让大家交流或者使用,你的成果才有进化和升华的机会。想想自 己2000年间开发的那些Windows系统工具,5、6年之后的今天,还是那个样子,今天流行的好多Windows系统工具都比自己的晚,但进化得很 好,且有那么多用户在使用。并且,不要保守自己的技术和思想,尽可能地与人交流与分享,或者传授给开发团队的成员。“与人交换苹果之后,每个人还是只有一 个苹果;但交换思想之后,每个人都拥有两种思想”,道理大家都懂,但有多少人真正能做到呢?  
11、尽量参加开源项目的开发、或者与朋友共同研 制一些自己的产品,千万不要因为没有钱赚而不做。网络早已不再只是“虚拟世界”,网上有很多的开源项目、合作开发项目、外包项目,这都是涉猎工作以外的知 识的绝好机会,并且能够结识更广的人缘。不要因为工作是做ERP,就不去学习和了解嵌入式、实时、通信、网络等方面的技术,反过来也是一样。如果当他别人 拿着合同找你合作,你却这也不会,那也不熟时,你将后悔莫及。  
12、书到用时方恨少,不要将自己的知识面仅仅局限于技术方面。诺贝尔经济学奖 得主西蒙教授的研究结果表明: “对于一个有一定基础的人来说,他只要真正肯下功夫,在6个月内就可以掌握任何一门学问。”教育心理学界为感谢西蒙教授的研究成果,故命名为西蒙学习法。 可见,掌握一门陌生的学问远远没有想想的那么高难、深奥。多方吸取、广泛涉猎。极力夯实自己的影响圈、尽量扩大自己的关注圈。财务、经济、税务、管理等等 知识,有空花时间看看,韬光养晦、未雨绸缪。  
13、本文的总结与反思:  
A:不要去做技术上的高手,除非你的目标如此。虽然本文是关于提高软件开发知识的建议,做技术的高手是我一向都不赞同的。你可以提高自己的专业知识,但能胜任工作即止。  
B:提高软件知识和技术只是问题的表面,本质是要提高自己认识问题、分析问题、解决问题的思想高度。软件专业知识的很多方法和原理,可以很容易地延伸、应用到生活的其它方面。
C:在能胜任工作的基础上,立即去涉猎其它领域的专业知识,丰富自己的知识体系、提高自己的综合素质,尤其是那些目标不在技术方面的朋友。
出处:http://hi.baidu.com/glaivelee/blog/item/45ea8638b1eff4d0d46225f2.html
posted @ 2012-02-13 00:10 hellxoul 阅读(175) | 评论 (0)编辑 收藏
     摘要: 在2012新的一年里,对程序员们来说挑战自我是非常重要的,要么不断创新,要么技术停滞不前。新年伊始,我整理了12个月的目标,每个目标都是对技术或个人能力的挑战,而且可以年复一年循环使用。  阅读全文
posted @ 2012-01-31 23:00 hellxoul 阅读(187) | 评论 (0)编辑 收藏
     摘要: 我们已经踏进了2012年,很自然的也会为新的一年定下目标,那么我们在生活中真正能够实现的有哪一些目标呢?本文将详细地给您解说新年要做的10个决定。  阅读全文
posted @ 2012-01-31 22:50 hellxoul 阅读(187) | 评论 (0)编辑 收藏
仅列出标题
共7页: 上一页 1 2 3 4 5 6 7 下一页