跟着汤阳光同志做一个OA系统(六):系统管理、实体映射、类图设计

79 篇文章 1 订阅
35 篇文章 0 订阅

@实现一组功能的步骤

1充分了解需求,包括所有的细节,需要知道要做一个什么样的功能

2,设计实体/

•   正向工程:实体à映射文件à建表

•   反向工程:建表 à映射文件à实体

3,分析功能

•   分析到每个请求的粒度。

•   得到的结果是我们需要处理多少种请求,其中每种请求对应一个Action方法,如此就能写Action了。

4,实现功能:

•   1,创建Action,并定义出其中的方法。

•   2,实现Action方法,并创建出所用到的新的Service方法。

•   3,实现Service方法,并创建出所用到的新的Dao方法。

•   4,实现Dao方法。

•   5,创建并完成JSP页面。

5,测试、运行

@设计实体

1,有几个实体?

•   一般是一组增删改查对应一个实体。

2,实体之间有什么关系?

•   一般是页面引用了其他的实体时,就表示与这个实体有关联关系。

3,每个实体中都有什么属性?

•   1主键

•   2关联关系属性。在类图中,关联关系是一条线,有两端,每一端对应一个表达此关联关系的属性。有几个端指向本类,本类中就有几个关联关系属性。

•   3一般属性。分析所有有关的页面,找出表单中要填写的或是在显示页面中要显示的信息等。

•   4特殊属性:为解决某问题而设计的属性。比如要显示年龄,但不会设计一个int age字段,而是一个Date birthday字段,年龄是在显示时实时计算出来的。

@hibernate实体映射

1,写注释

•   格式为:?属性,表达的是本对象与?的?关系。

•   例:“department属性,本对象与Department的多对一”

2,拷模板:

多对一

<many-to-one name=“” class=“” column=“”/>

一对多

Set

<set name="">

        <key column=""></key>

        <one-to-many class=""/>

</set>

多对多

Set

<set name="" table="">

        <key column=""></key>

        <many-to-many class="" column=""/>

</set>

 

3,填空:

•   name属性:属性名(注释中的第1问号)

•   class属性:关联的实体类型(注释中的第2个问号)

•   column属性:

•   <many-to-onecolumn="..">:一般可以写成属性名加Id后缀,如属性为department,则column值写成departmentId。

•   一对多中的<keycolumn="..">:从关联的对方(对方是多对一)映射中把column值拷贝过来。

•   多对多中的<key column=“..”>:一般可以写成本对象的名加Id后缀,如本对象名为User,则写为userId。

•   多对多中的<many-to-manycolumn=“..”>:一般可以写为关联对象的名称加Id后缀。

例子:

【实体类】

public class Role {

    privateLong id;

    privateString name;

    privateString description;

    privateSet<User> users = new HashSet<User>();

 

public class User {

    privateLong id;

    privateDepartment department;

    privateSet<Role> roles = new HashSet<Role>();

 

    privateString loginName; // 登录名

    privateString password; // 密码

    privateString name; // 真实姓名

    privateString gender; // 性别

    privateString phoneNumber; // 电话号码

    privateString email; // 电子邮件

    privateString description; // 说明

 

public class Department {

    privateLong id;

    privateSet<User> users = new HashSet<User>();

    privateDepartment parent;

    privateSet<Department> children = new HashSet<Department>();

 

    privateString name;

    privateString description;

【映射文件】

Role.hbm.xml

<hibernate-mappingpackage="cn.itcast.oa.domain">

 

    <classname="Role" table="itcast_role">

        <idname="id">

           <generator class="native"/>

        </id>

        <propertyname="name"/>

        <propertyname="description"/>

       

        <!-- users属性,本类与User的多对多 -->

        <setname="users" table="itcast_user_role">

            <keycolumn="roleId"></key>

            <many-to-manyclass="User" column="userId"></many-to-many>

        </set>

       

    </class>

   

</hibernate-mapping>

 

User.hbm.xml

<hibernate-mappingpackage="cn.itcast.oa.domain">

 

    <classname="User" table="itcast_user">

        <idname="id">

           <generator class="native"/>

        </id>

        <propertyname="loginName"/>

        <propertyname="password"/>

        <propertyname="name"/>

        <propertyname="gender" />

        <propertyname="phoneNumber"/>

        <propertyname="email"/>

        <propertyname="description"/>

       

        <!-- department属性,本类与Department的多对一 -->

        <many-to-onename="department" class="Department" column="departmentId"></many-to-one>

 

        <!-- roles属性,本类与Role的多对多 -->

        <setname="roles" table="itcast_user_role">

            <keycolumn="userId"></key>

            <many-to-manyclass="Role" column="roleId"></many-to-many>

        </set>

       

    </class>

   

</hibernate-mapping>

 

Department.hbm.xml

<hibernate-mappingpackage="cn.itcast.oa.domain">

 

    <classname="Department" table="itcast_department">

        <idname="id">

            <generatorclass="native" />

        </id>

        <propertyname="name" />

        <propertyname="description" />

 

        <!-- users属性,本类与User的一对多 -->

        <setname="users">

            <keycolumn="departmentId"></key>

            <one-to-manyclass="User" />

        </set>

 

        <!-- parent属性,本类与Department(上级)的多对一 -->

        <many-to-onename="parent" class="Department"column="parentId"></many-to-one>

 

        <!--children属性,本类与Department(下级)的一对多 -->

        <setname="children">

            <keycolumn="parentId"></key>

            <one-to-manyclass="Department" />

        </set>

 

    </class>

 

</hibernate-mapping>


每一个功能可能有好多请求(一般使用转发),功能与功能之间的切换就需要使用重定向。

 

@处理部门中的树状结构

说明:部门显示的两种方式:

①List页面直接显示部门的树状层级结构,可以使用树状列表样式

②列表页面只显示一层的(同级的)部门数据,默认显示最顶级的部门列表;点击部门名称,可以查看此部门相应的下级部门列表。

③删除部门时,同时删除此部门的所有下级部门【层级删除】。

 

下拉选择框

<s:select name="parentId"cssClass="SelectStyle"

           list="#departmentList"listKey="id" listValue="name"

            headerKey="" headerValue="==请选择部门=="/>

其中name="parentId"表示传输给服务器的key

    list="#departmentList"表示从map中找到这个列表

    listKey="id"listValue="name"分别表示从departmentList中的每个元素找idname属性

    headerKey="" headerValue="==请选择部门=="表示什么都不选的话keyvalue

指定了parentId后就能回显

 

级联删除

<!-- children属性,本类与Department(下级)的一对多 -->

       <set name="children"cascade="delete">

           <key column="parentId"></key>

           <one-to-many class="Department"/>

       </set>

 

 

@list方法中通过parentId确定层级

/** 列表 */

    public String list() throws Exception {

      

       List<Department> departmentList = null;

       if(null == parentId){//说明是从部门管理连接过来的

           departmentList = departmentService.findTopList();

       }else{

           departmentList = departmentService.findMyChildren(parentId);

           Department parent = departmentService.getById(parentId);

           ActionContext.getContext().put("parent", parent);

       }

      

       ActionContext.getContext().put("departmentList", departmentList);

       return"list";

    }

@添加和修改完成后,通过parentId加载原来层级的部门

<result  name="toList"type="redirectAction">

department_list?parentId=${parentId}</result>

 

@删除超链接的action

department_delete?id=%{id}&parentId=%{parent.id}

 

@<!-- 这个小细节就可以使新建页面事先选中当前部门的上级部门,于是默认添加的部门就是当前的兄弟部门 -->

   <s:a action="department_addUI?parentId=%{parentId}">新建</s:a>      

@<!-- 返回上一级部门,那么需要指定的parentId=parent.parent.id

         Departmentparent = departmentService.getById(parentId);

       ActionContext.getContext().put("parent", parent);

             -->

  <s:aaction="department_list?parentId=%{#parent.parent.id}">返回上一级</s:a>

 

 

懒加载问题:could not initialize proxy - no Session

懒加载异常的分析与解决

懒加载是由于session的关闭时间在访问关联对象属性之前。一般发生在页面中使用EL表达式或者OGNL表达式的时候访问与懒加载有关的属性,由于session已经关闭的时候所以异常。

解决办法就是关闭懒加载(适用于怎么都会加载的)延迟session的关闭时间,使用spring的OpenSessionInViewFilter

 

配置方式是:

在web.xml中添加一个filter

 

<filter>

         <filter-name>OpenSessionInViewFilter</filter-name>

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

</filter>

<filter-mapping>

         <filter-name>OpenSessionInViewFilter</filter-name>

         <url-pattern>*.action</url-pattern>

</filter-mapping>

看url-pattern,这个过滤器知识对action请求进行过滤,而不对其他请求过滤,例如图片、其他没有用到session的请求,这样兼顾了效率和懒加载。这就是为什么struts2中要配置那个<constantname="struts.action.extension" value="action"/>,就是要明确说明struts2要处理的类型。


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值