Hibernate应用开发完全手册(第18章:五)

【转】Hibernate应用开发完全手册(第18章:五)

18.11  物资出库模块

18.11.1  物资出库模块总体架构

物资出库模块主要包括以下功能:

  ●   部门领用:用于对部门领用信息进行登记;

  ●   物资借出:用于对物资借出信息进行登记;

  ●   借出审核:用于对物资借出信息进行审核。

18.11.2  创建物资出库模块的持久化类及映射文件

1.创建持久化类和映射文件

物资出库模块涉及到的数据表的持久化类和映射文件如表18.18所示。持久化类及映射文件的具体实现方法请参见18.8.2节。

表18.18                         物资出库模块涉及到的数据表的持久化类和映射文件

数据表名称

持久化类名称

映射文件名称

tb_getUse

GetUseForm

GetUseForm.hbm.xml

tb_branch

BranchForm

BranchForm.hbm.xml

tb_loan

LoanForm

LoanForm.hbm.xml

tb_goods

GoodsForm

GoodsForm.hbm.xml

tb_storage

StorageForm

StorageForm.hbm.xml

2.映射关联关系

在物资出库模块中,涉及到3对关联关系,如表18.19所示。

表18.19                                                 物资出库模块的表间关系

主  键  表

外  键  表

名    称

字  段  名

名    称

字  段  名

tb_goods

id

tb_getUse

goodsid

tb_branch

id

tb_getUse

branchid

tb_goods

id

tb_loan

goodsid

说明:在Hibernate中映射关联关系的具体方法请参见18.10.2节。

3.修改Hibernate配置文件

在创建持久化类、映射文件和关联关系后,还需要在Hibernate配置文件hibernate.cfg.xml中指定持久化类映射文件,关键代码如下:

<mapping resource="com/actionForm/GetUseForm.hbm.xml"/>

<mapping resource="com/actionForm/LoanForm.hbm.xml"/>

<mapping resource="com/actionForm/BranchForm.hbm.xml"/>

说明:由于物资信息持久化类及映射文件已经在18.9.2节介绍了,所以此时不需要再配置了。

18.11.3  创建物资出库的Action实现类

物资出库模块涉及到两个Action实现类,一个是用于部门领用操作的GetUse类,另一个是用于物资借出操作的Loan类,下面将分别介绍。

1.创建部门领用操作的Action实现类GetUse

在部门领用操作的Action实现类GetUse中首先需要在构造方法中实例化物资出库模块的OutStorageDAO类(该类用于实现业务逻辑操作),然后通过Action实现类的主要方法execute()执行相应的业务逻辑操作。Action实现类的execute()方法会被自动执行,这个方法本身没有具体的事务,它是根据HttpServletRequest的getParameter()方法获取的action参数值执行相应方法的。

实现部门领用操作的Action实现类的关键代码如下。

例程18-92:光盘\mr\18\MaterialManage\src\com\action\GetUse.java

public class GetUse extends Action {

    private OutStorageDAO outStorageDAO = null;

    public GetUse() {

        outStorageDAO = new OutStorageDAO();

    }

    public ActionForward execute(ActionMapping mapping, ActionForm form,

                                 HttpServletRequest request,

                                 HttpServletResponse response) {

        String action = request.getParameter("action");

        if (action.equals("") || action == null) {

            request.setAttribute("error", "您的操作有误!");

            return mapping.findForward("error");

        } else if (action.equals("getuseaddquery")) {     //查询库存中的物资信息

            return getuseadd_request(mapping, form, request, response);

        } else if (action.equals("getuseadd")) {     //部门领用

            return getuseadd(mapping, form, request, response);

        }

        request.setAttribute("error", "您的操作有误!");

        return mapping.findForward("error");

    }

    ……  //此处省略了该类中其他方法,这些方法将在后面的具体过程中给出

}

2.创建用于物资借出操作的Action实现类Loan

在用于物资借出操作的Action实现类Loan中,首先需要在构造方法中实例化物资出库模块的OutStorageDAO类(该类用于实现业务逻辑操作),然后通过Action实现类的主要方法execute()执行相应的业务逻辑操作。Action实现类的execute()方法会被自动执行,这个方法本身没有具体的事务,它是根据通过HttpServletRequest的getParameter()方法获取的action参数值执行相应方法的。实现物资借出操作的Action实现类Loan的关键代码如下。

例程18-93:光盘\mr\18\MaterialManage\src\com\action\Loan .java

public class GetUse extends Action {

    ……     //此处省略了在构造方法中实例化OutStorageDAO类的方法

    public ActionForward execute(ActionMapping mapping, ActionForm form,

                                 HttpServletRequest request,

                                 HttpServletResponse response) {

        String action = request.getParameter("action");

        if (action.equals("") || action == null) {

            request.setAttribute("error", "您的操作有误!");

            return mapping.findForward("error");

        } else if (action.equals("loanaddquery")) {     //查询库存中的物资信息

            return loanadd_request(mapping, form, request, response);

        } else if (action.equals("loanadd")) {     //物资借出

            return loanadd(mapping, form, request, response);

        }else if(action.equals("approveloan")){     //借出审核

            return approveloan(mapping, form, request, response);

        }else if(action.equals("backloan")){     //借出归还

            return backloan(mapping, form, request, response);

        }else{

            request.setAttribute("error", "您的操作有误!");

            return mapping.findForward("error");

        }

    ……  //此处省略了该类中其他方法,这些方法将在后面的具体过程中给出

}

18.11.4  部门领用设计

使用的数据表:tb_getuse、tb_branch、tb_goods、tb_storage
主要技术:通过Hibernate API操作数据库

用户登录后,选择“物资出库”→“部门领用”菜单项,进入到部门领用登记页面。在部门领用页面中,首先从“物资名称”下拉列表框中选择要领用的物资(系统将自动检索出该物资的生产厂家、单价、计量单位和库存数量等信息),然后在“领用数量”文本框中输入领用数量(系统会自动检验库存数量,如果库存数量不足,系统将给予提示),最后选择领用部门并输入负责人名称,单击【保存】按钮,保存部门领用信息,运行结果如图18.22所示。

图18.22  部门领用页面运行结果

1.设计部门领用页面

从系统主菜单中选择“物资出库”→“部门领用”菜单项或是在部门领用页面中改变“物资名称”下拉列表框的值时都会触发一个URL地址,这个URL地址是“getUse.do?action=getuseaddquery”,从这个URL地址中可以知道部门领用页面所涉及到的action的参数值为“getuseaddquery”,当action=getuseaddquery时,会调用查询库存中的物资信息的方法getuseadd_request(),具体代码如下。

例程18-94:光盘\mr\18\MaterialManage\src\com\action\GetUse.java

if (action.equals("getuseaddquery")) {

    return getuseadd_request(mapping, form, request, response);

}

在查询库存物资信息的方法getuseadd_request()中,首先需要获取从页面中传递的参数id的值并保存到HttpServletRequest的对象id中,然后调用OutStorageDAO类中的storage_query()方法查询出库存中的物资信息,再将返回的查询结果保存到HttpServletRequest的对象GoodsStorage中。查询库存中物资信息的方法getuseadd_request()的具体代码如下。

例程18-95:光盘\mr\18\MaterialManage\src\com\action\GetUse.java

public ActionForward getuseadd_request(ActionMapping mapping,ActionForm form,

                                  HttpServletRequest request,HttpServletResponse response) {

    int goodsid = 0;

    if (request.getParameter("id") != null) {

        goodsid = Integer.parseInt(request.getParameter("id"));

    }

    request.setAttribute("id", goodsid);

    request.setAttribute("GoodsStorage", outStorageDAO.storage_query()); //获取物资信息

    return mapping.findForward("selStorageGoods");

}

从上面的代码中可以知道查询库存中物资信息使用的OutStorageDAO类的方法是storage_query(),在该方法中首先需要利用Hibernate的本地SQL查询从两个表中获取库存中物资的详细信息,然后将查询结果保存到List集合list中,并返回list。storage_query()方法的具体代码如下。

例程18-96:光盘\mr\18\MaterialManage\src\com\action\OutStorageDAO.java

public List storage_query() {

    session = MySession.openSession(); //打开Session

    String sql = "select {goods.*},{storage.*} from tb_goods goods inner join tb_storage storage on goods.id= storage.goodsid where storage.number>0"; //使用内连接查询库存信息

    List list = null;

    try {

        SQLQuery query = session.createSQLQuery(sql);

        query.addEntity("goods", GoodsForm.class); //将数据表与持久化类关联在一起

        query.addEntity("storage", StorageForm.class);

        list = query.list();

    } catch (Exception e) {

        System.out.println("查询时的错误信息:" + e.getMessage());

    }

    return list;

}

在struts-config.xml文件中配置查询库存中物资信息所涉及的<forward>元素,代码如下:

<forward name="selStorageGoods" path="/getUseAdd.jsp" />

接下来的工作是将Action实现类中的storage_query()方法返回的查询结果显示在部门领用页面getUseAdd.jsp中。在getUseAdd.jsp中通过request.getAttribute()方法获取查询结果并将其显示在相应的位置或表单元素中。

2.保存部门领用信息

在部门领用页面中录入部门领用信息后,单击【保存】按钮,系统会访问一个URL,这个URL是“getUse.do?action=getuseadd”。从该URL地址中可以知道保存部门领用信息涉及到的action的参数值为“getuseadd”,也就是当action=getuseadd时,会调用保存部门领用信息的方法getuseadd(),具体代码如下。

例程18-97:光盘\mr\18\MaterialManage\src\com\action\GetUse.java

if (action.equals("getuseadd")) {

    return getuseadd(mapping, form, request, response);

}

在保存部门领用信息的方法getuseadd()中,首先需要将接收到的表单信息强制转换成ActionForm类型,然后调用OutStorageDAO类中的getuseAdd()方法保存部门领用信息到相应的数据表中,并将返回值保存到变量rtn中。如果返回值为1,表示信息修改成功,将页面重定向到部门领用页面,否则将错误提示信息“部门领用信息添加失败!”保存到HttpServletRequest的对象error中,然后将页面重定向到错误提示信息页面。保存部门领用信息的方法getuseadd()的关键代码如下。

例程18-98:光盘\mr\18\MaterialManage\src\com\action\GetUse.java

public ActionForward getuseadd(ActionMapping mapping, ActionForm form,

                               HttpServletRequest request,HttpServletResponse response) {

    GetUseForm getUseForm = (GetUseForm) form;

    int rtn = outStorageDAO.getuseAdd(getUseForm);

    ……    //此处省略了根据返回值重定向页面的代码

}

3.编写保存部门领用信息的OutStorageDAO类的方法

从上面的代码中可以知道保存部门领用信息时使用的OutStorageDAO类的方法是getuseAdd()。实现getuseAdd()方法主要分为以下4个步骤。

(1)将部门领用信息保存到部门领用信息表中,由于映射了关联关系,所以需要建立“GoodsForm和GetUseForm的关联关系”以及“BranchForm和GetUseForm的关联关系”。

(2)获取部门领用信息表中最大的自动编号,与字符“LY”和系统日期组合成“LYYYYY-MM-DDnnnnn”格式的领用单号,并插入到部门领用信息表中。

(3)修改库存信息表。

(4)如果在执行过程中不抛出异常,则将标志变量赋值为1,否则将标志变量赋值为0,最后返回该标志变量。

getuseAdd()方法的具体代码如下。

例程18-99:光盘\mr\18\MaterialManage\src\com\dao\OutStorageDAO.java

public int getuseAdd(GetUseForm getUseForm) {

    session = MySession.openSession();     //打开Session

    Transaction tx = null;

    int rtn = 1;

    try {

        //保存部门领用信息

        tx = session.beginTransaction();

        int goodsid = getUseForm.getGoodsid();

        GoodsForm goodsForm = (GoodsForm) session.get(GoodsForm.class,goodsid);

        getUseForm.setGoods(goodsForm);

        int branchid = getUseForm.getBranchid();

        BranchForm branchForm = (BranchForm) session.get(BranchForm.class,branchid);

        getUseForm.setBranch(branchForm);

        getUseForm.setCreatetime(new Date());

        session.save(getUseForm);

        NumberFormat formater = NumberFormat.getNumberInstance();

        int id = getUseForm.getId();

        formater.setMinimumIntegerDigits(5);

        java.util.Date createTime = getUseForm.getCreatetime();

        java.sql.Date date = new java.sql.Date(createTime.getTime());

        String gNo = "LY" + date +formater.format(id).toString().replace(",", "");   //组合领用单号

        GetUseForm getUseF = (GetUseForm) session.get(

                GetUseForm.class, id);

        getUseF.setGno(gNo);

        session.update(getUseF);

            //修改库存信息

        List list = session.createQuery("FROM StorageForm WHERE goodsid=" +

                                        getUseForm.getGoodsid() + "").list();

        StorageForm storageF = (StorageForm) list.get(0);

        int storageNum = storageF.getNumber() - getUseForm.getNumber();

        if (storageNum >= 0) {

            storageF.setNumber(storageNum);

            session.update(storageF);

        } else {      //库存数量不足

            rtn = 0;

        }

        if (rtn == 1) {

            tx.commit();

        } else {

            if (tx != null) {

                tx.rollback();

            }

        }

    } catch (Exception e) {

        ……   //此处省略了事务回滚和输出错误信息的代码

        rtn = 0;

    } finally {

        MySession.closeSession(session); //关闭Session

    }

    return rtn;

}

4.struts-config.xml文件配置

在struts-config.xml文件中配置保存部门领用信息所涉及的<forward>元素,代码如下:

<forward name="getUseAddok" path="/getUseAdd_ok.jsp?para=1" />

18.11.5  物资借出设计

使用的数据表:tb_loan、tb_goods、tb_storage      主要技术:通过Hibernate API操作数据库

用户登录后,选择“物资出库”→“物资借出”菜单项,进入到 物资借出登记页面。在物资借出页面中。首先从“物资名称”下拉列表框中选择要借出的物资(系统将自动检索出该物资的生产厂家、单价、计量单位和库存数量等信息),然后在“借出数量”文本框中输入借出数量(系统会自动检验库存数量,如果库存数量不足,系统将给予提示),最后输入借用人基本信息及负责人名称,单击【保存】按钮,保存物资借出信息,运行结果如图18.23所示。

图18.23  物资借出页面运行结果

1.设计物资借出页面

从系统主菜单中选择“物资出库”→“物资借出”菜单项或是在物资借出页面中改变“物资名称”下拉列表框的值时都会触发一个URL地址,这个URL地址是“loan.do?action=loanaddquery”,从这个URL地址中可以知道物资借出页面所涉及到的action参数值为“loanaddquery”,当action=loanaddquery时,会调用查询库存中的物资信息的方法loanadd_request(),具体代码如下。

例程18-100:光盘\mr\18\MaterialManage\src\com\action\GetUse.java

if (action.equals("loanaddquery")) {

    return loanadd_request(mapping, form, request, response);

}

在查询库存中物资信息的方法loanadd_request()中,首先需要获取从页面中传递的参数id的值并保存到HttpServletRequest的对象id中,然后调用OutStorageDAO类中的storage_query()方法查询出库存中的物资信息,再将返回的查询结果保存到HttpServletRequest的对象GoodsStorage中。查询库存中物资信息的方法getuseadd_request()的具体代码同例程18-98类似,这里就不再赘述。

查询库存中物资信息使用的OutStorageDAO类的方法是storage_query(),在该方法中首先需要利用Hibernate的本地SQL查询从两个表中获取库存中物资的详细信息,然后将查询结果保存到List集合list中,并返回list。storage_query()方法的具体代码请参见例程18-99。

在struts-config.xml文件中配置查询库存中物资信息所涉及的<forward>元素,代码如下:

<forward name="selStorageGoods" path="/getUseAdd.jsp" />

接下来的工作是将Action实现类中storage_query()方法返回的查询结果显示在物资借出页面loanAdd.jsp中。在loanAdd.jsp中通过request.getAttribute()方法获取查询结果并将其显示在相应的位置或表单元素中。

2.保存物资借出信息

在物资借出页面中录入物资借出信息后,单击【保存】按钮,系统会访问一个URL,这个URL是“loan.do?action=loanadd”。从该URL地址中可以知道保存物资借出信息涉及到的action的参数值为“loanadd”,也就是当action=loanadd时,会调用保存物资借出信息的方法loanadd(),具体代码如下。

例程18-101:光盘\mr\18\MaterialManage\src\com\action\Loan.java

if (action.equals("loanadd")) {

    return loanadd(mapping, form, request, response);

}

在保存物资借出信息的方法loanadd()中,首先需要将接收到的表单信息强制转换成ActionForm类型,然后调用OutStorageDAO类中的getuseAdd()方法保存物资借出信息到相应的数据表中,并将返回值保存到变量rtn中,如果返回值为1,表示信息保存成功,将页面重定向到物资借出页面,否则将错误提示信息“物资借出信息添加失败!”保存到HttpServletRequest的对象error中,然后将页面重定向到错误提示信息页面。保存物资借出信息的方法loanadd()的关键代码如下。

例程18-102:光盘\mr\18\MaterialManage\src\com\action\Loan.java

public ActionForward loanadd(ActionMapping mapping, ActionForm form,

                               HttpServletRequest request,HttpServletResponse response) {

    LoanForm loanForm = (LoanForm) form;

    int rtn = outStorageDAO.loanAdd(loanForm);

    ……    //此处省略了根据返回值重定向页面的代码

}

3.编写保存物资借出信息的OutStorageDAO类的方法

从上面的代码中可以知道保存物资借出信息时使用的OutStorageDAO类的方法是loanAdd()。实现loanAdd()方法主要分为以下3个步骤。

(1)将物资借出信息保存到物资借出信息表tb_loan中。

(2)获取物资借出信息表中最大的自动编号,与字符“LY”和系统日期组合成“JCYYYY-MM-DDnnnnn”格式的借出单号,并插入到物资借出信息表中。

(3)如果在执行过程中不抛出异常,则将标志变量赋值为1,否则将标志变量赋值为0,最后返回该标志变量。

loanAdd()方法的具体代码如下。

例程18-103:光盘\mr\18\MaterialManage\src\com\dao\OutStorageDAO.java

public int loanAdd(LoanForm loanForm) {

    session = MySession.openSession(); //打开Session

    Transaction tx = null;

    int rtn = 0;

    try {

        //保存物资借出信息

        tx = session.beginTransaction();

        int goodsid = loanForm.getGoodsid();

        GoodsForm goodsForm = (GoodsForm) session.get(GoodsForm.class,goodsid);

        loanForm.setGoods(goodsForm);

        loanForm.setCreatetime(new Date());

        session.save(loanForm);

        NumberFormat formater = NumberFormat.getNumberInstance();

        int id = loanForm.getId();

        formater.setMinimumIntegerDigits(5);

        java.util.Date createTime = loanForm.getCreatetime();

        java.sql.Date date = new java.sql.Date(createTime.getTime());

        String lNo = "JC" + date +formater.format(id).toString().replace(",", ""); //组合借出单号

        LoanForm loanF = (LoanForm) session.get(

                LoanForm.class, id);

        loanF.setLno(lNo);

        session.update(loanF);

        tx.commit();

        rtn = 1;

    } catch (Exception e) {

        ……   //此处省略了事务回滚和输出错误信息的代码

        rtn = 0;

    } finally {

        MySession.closeSession(session); //关闭Session

    }

    return rtn;

}

4.struts-config.xml文件配置

在struts-config.xml文件中配置保存物资借出信息所涉及的<forward>元素,代码如下:

<forward name="loanAddok" path="/loanAddok_ok.jsp?para=1" />

18.11.6  借出审核设计

使用的数据表:tb_loan、tb_goods、tb_storage    主要技术:通过Hibernate API操作数据库

用户登录后,选择“物资出库”→“借出审核”命令,进入到借出审核页面,在该页面中将显示全部未审核的借出单列表,单击审核图标,即可完成借出审核操作。借出审核页面的运行结果如图18.24所示。

图18.24  借出审核页面运行结果

在“借出审核”页面中可以找到审核图标的超级链接代码,如下所示:

例程18-104:光盘\mr\18\MaterialManage\defaultroot\loanApproveQuery.jsp

<a href="loan.do?action=approveloan&id=<%=id%>">

<img src="images/enforce.gif" width="16" height="16" border="0"></a>

从上面的URL地址中可以知道实现借出审核操作所涉及到的action的参数值为“approveloan”,当action=approveloan时,会调用实现借出审核操作的方法approveloan(),具体代码如下。

例程18-105:光盘\mr\18\MaterialManage\src\com\action\Loan.java

if(action.equals("approveloan")){

    return approveloan(mapping, form, request, response);

}

在实现借出审核操作的方法approveloan()中,首先需要判断用户是否登录,如果没登录则跳转到登录页面强制其登录,这样可以提高系统的安全性,然后获取从页面中传递的参数id,并将id的值赋给int型变量id,赋值后将该变量作为OutStorageDAO类中approveloanAdd()方法的参数,最后调用approveloanAdd()方法实现借出审核操作,并根据执行结果转到相应的页面。approveloan()方法的具体代码如下。

例程18-106:光盘\mr\18\MaterialManage\src\com\action\Instorage.java

public ActionForward approveloan(ActionMapping mapping,ActionForm form,

                                HttpServletRequest request,HttpServletResponse response){

    HttpSession httpsession = request.getSession();

    ……     //此处省略了判断用户是否登录的代码

    int id=Integer.valueOf(request.getParameter("id"));

    int rtn=outStorageDAO.approveloanAdd(id,request);

    if(rtn==1){

        return mapping.findForward("loanApproveAddok");

    }else if(rtn==2){

        request.setAttribute("error","库存数量不足,不能完成借出审核!");

        return mapping.findForward("error");

    }else{

        request.setAttribute("error","借出审核操作失败!");

        return mapping.findForward("error");

     }

}

从上面代码中可以知道实现借出审核操作使用的OutStorageDAO类的方法是approveloanAdd()。在approveloanAdd()方法中首先将借出审核信息保存到物资借出信息表tb_loan中,然后修改相应物资的库存数量,当库存数量不足时,不能完成借出审核操作。approveloanAdd()方法的具体代码如下。

例程18-107:光盘\mr\18\MaterialManage\src\com\dao\OutStorageDAO.java

public int approveloanAdd(int id, HttpServletRequest request) {

    int rtn = 1;

    session = MySession.openSession();                                                                //打开session

    Transaction tx = null;

    try {

        tx = session.beginTransaction();

        LoanForm loanForm = (LoanForm) session.get(LoanForm.class, id);

        loanForm.setApprovetime(new Date());

        HttpSession httpsession = request.getSession();

        loanForm.setTaster((String) httpsession.getAttribute("username"));//设置审核员

        loanForm.setState(new Short("1"));                                                //修改借出单状态为已审核

        session.update(loanForm);                                                         //保存借出审核信息

        GoodsForm goodsF = loanForm.getGoods();

        int goodsid = goodsF.getId();

        int goodsnumber = loanForm.getNumber();

        String hql_goods = "FROM StorageForm WHERE goodsid=" + goodsid + "";

        List list_goods = session.createQuery(hql_goods).list();

        if (list_goods.size() > 0) {

            StorageForm storageF = (StorageForm) list_goods.get(0);

            if (storageF.getNumber() - goodsnumber >= 0) {

                String hql_up = "UPDATE StorageForm set number=number-" +

                                goodsnumber + " WHERE goodsid=" + goodsid +"";

                session.createQuery(hql_up).executeUpdate();

            } else {

                rtn = 2; //库存不足

            }

        } else {

            rtn = 0;

        }

        if (rtn == 1) {

            tx.commit();

        } else {

            if (tx != null) {

                tx.rollback();

            }

        }

    } catch (Exception e) {

        ……   //此处省略了事务回滚和输出错误信息的代码

        rtn = 0;

    } finally {

        MySession.closeSession(session); //关闭Session

    }

    return rtn;

}

在struts-config.xml文件中配置实现借出审核操作所涉及的<forward>元素,代码如下:

<forward name="loanApproveAddok" path="/loanAddok_ok.jsp?para=2" />

你可能感兴趣的:(Hibernate应用开发完全手册(第18章:五))