效果说明:
前面分析过购销合同的Excel报表需要四张表,这篇讲的是合同货物表。
这个合同货物表是购销合同的子表,是一个购销合同有多个合同货物的关系。在合同货物表中有购销合同的主键作为外键。所以这张表的操作比较复杂。
我们在增加一个合同货物时要传入它所属的购销合同的主键值,最后做出的界面效果是:
1.在购销合同列表中选中一个合同,在操作中点击货物。
点击"货物"这个按钮就定位到:
并把购销合同的主键值传递到下一个请求中,这里的contractId要与
这里的contractId一模一样,这样springmvc才能映射。
2.来到新增合同货物的页面,这里有这么几点要注意的就是
1.厂家名称的填写是用下拉框的形式来完成的。
2.新增的合同货物表中的购销合同中的主键来自于上一个页面传过来的。
3.在新增合同货物的页面下面是一个列表,这个列表是查看你选择新增的购销合同里面已经存在的合同货物。这样就可以知道合同货物有没有增加进去了。
4.在填写好新增的合同货物时,按下确定键,还是来到这个页面,因为我们给一个购销合同添加合同货物时不可能就只添加一个货物,肯定会一次添加很多的合同货物,这么写的话就方便了。
项目结构:
前面带红色框框的就是这个需要的domain->Dao层->Service层->到控制层。
先把合同货物表的单表的增加写好。
具体代码如下:
domain就是数据库中对应的CONTRACT_PRODUCT_C这张表。
如下:
所以domain包中的po类就是:
package cn.itcast.jk.domain; //合同货物 public class ContractProduct { private String id;// 主键 private String contractid;// 外键,在这里就是普通的键; private String factoryid; private String factoryname;//厂家名称 private String productno;//货号 private String productimage;//货物照片 private String productdesc;//货物描述 private String cnumber;//数量 private String outnumber;//实际出货数量 private String loadingrate;//装率 private String boxnum;//箱数 private String packingunit;//包装单位 private String price;//单价 private String amount;//总金额 private String finished;//是否出货完毕 private String exts;//附件 private String orderno;//排序号 public String getId() { return id; } public void setId(String id) { this.id = id; } public String getContractid() { return contractid; } public void setContractid(String contractid) { this.contractid = contractid; } public String getFactoryid() { return factoryid; } public void setFactoryid(String factoryid) { this.factoryid = factoryid; } public String getFactoryname() { return factoryname; } public void setFactoryname(String factoryname) { this.factoryname = factoryname; } public String getProductno() { return productno; } public void setProductno(String productno) { this.productno = productno; } public String getProductimage() { return productimage; } public void setProductimage(String productimage) { this.productimage = productimage; } public String getProductdesc() { return productdesc; } public void setProductdesc(String productdesc) { this.productdesc = productdesc; } public String getCnumber() { return cnumber; } public void setCnumber(String cnumber) { this.cnumber = cnumber; } public String getOutnumber() { return outnumber; } public void setOutnumber(String outnumber) { this.outnumber = outnumber; } public String getLoadingrate() { return loadingrate; } public void setLoadingrate(String loadingrate) { this.loadingrate = loadingrate; } public String getBoxnum() { return boxnum; } public void setBoxnum(String boxnum) { this.boxnum = boxnum; } public String getPackingunit() { return packingunit; } public void setPackingunit(String packingunit) { this.packingunit = packingunit; } public String getPrice() { return price; } public void setPrice(String price) { this.price = price; } public String getAmount() { return amount; } public void setAmount(String amount) { this.amount = amount; } public String getFinished() { return finished; } public void setFinished(String finished) { this.finished = finished; } public String getExts() { return exts; } public void setExts(String exts) { this.exts = exts; } public String getOrderno() { return orderno; } public void setOrderno(String orderno) { this.orderno = orderno; } }
ContractProductMapper.xml文件:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="cn.itcast.jk.mapper.ContractProductMapper"> <resultMap type="cn.itcast.jk.domain.ContractProduct" id="contractProductRM"> <id property="id" column="CONTRACT_PRODUCT_ID"/> <result property="contractid" column="CONTRACT_ID"/> <result property="factoryid" column="FACTORY_ID"/> <result property="factoryname" column="FACTORY_NAME"/> <result property="productno" column="PRODUCT_NO"/> <result property="productimage" column="PRODUCT_IMAGE"/> <result property="productdesc" column="PRODUCT_DESC"/> <result property="cnumber" column="CNUMBER"/> <result property="outnumber" column="OUT_NUMBER"/> <result property="loadingrate" column="LOADING_RATE"/> <result property="boxnum" column="BOX_NUM"/> <result property="packingunit" column="PACKING_UNIT"/> <result property="price" column="PRICE"/> <result property="amount" column="AMOUNT"/> <result property="finished" column="FINISHED"/> <result property="exts" column="CONTRACT_ID"/> <result property="orderno" column="CONTRACT_ID"/> </resultMap> <!-- 开始写sql语句
注意这里的写法:
<if test="contractId != null">and CONTRACT_ID=#{contractId}</if>
这句代码的作用是:我们在新增合同货物中下面不是有一个列表吗?显示这个购销合同中存在的合同货物。我们要查询在指定的购销合同中有几个货物,
--> <select id="find" parameterType="map" resultMap="contractProductRM" > select * from contract_product_c where 1=1 <if test="contractId != null">and CONTRACT_ID=#{contractId}</if> </select> <!-- 取一个数据 --> <select id="get" parameterType="string" resultMap="contractProductRM"> <!-- 这个pid可以随便取的 --> select * from contract_product_c where CONTRACT_PRODUCT_ID=${pid} </select> <insert id="insert" parameterType="cn.itcast.jk.domain.ContractProduct"> insert into contract_product_c ( CONTRACT_PRODUCT_ID,CONTRACT_ID,FACTORY_ID,FACTORY_NAME,PRODUCT_NO,PRODUCT_IMAGE,PRODUCT_DESC,CNUMBER,OUT_NUMBER,LOADING_RATE,BOX_NUM,PACKING_UNIT,PRICE,AMOUNT,FINISHED,EXTS,ORDER_NO ) values ( <!-- 因为 id,contractid,factoryid肯定不能为空,所以jdbcType就不用写了。--> #{id}, #{contractid}, #{factoryid}, #{factoryname,jdbcType=VARCHAR}, #{productno,jdbcType=VARCHAR}, #{productimage,jdbcType=VARCHAR}, #{productdesc,jdbcType=VARCHAR}, #{cnumber,jdbcType=INTEGER}, #{outnumber,jdbcType=INTEGER}, #{loadingrate,jdbcType=VARCHAR}, #{boxnum,jdbcType=INTEGER}, #{packingunit,jdbcType=VARCHAR}, #{price,jdbcType=VARCHAR}, #{amount,jdbcType=VARCHAR}, #{finished,jdbcType=INTEGER}, #{exts,jdbcType=VARCHAR}, #{orderno,jdbcType=INTEGER} ) </insert> <update id="update" parameterType="cn.itcast.jk.domain.ContractProduct"> update contract_product_c <set> <if test="factoryname!=null">FACTORY_NAME=#{factoryname}</if> <if test="productno!=null">PRODUCT_NO=#{productno}</if> <if test="productimage!=null">PRODUCT_IMAGE=#{productimage}</if> <if test="productdesc!=null">PRODUCT_DESC=#{productdesc}</if> <if test="cnumber!=null">CNUMBER=#{cnumber}</if> <if test="outnumber!=null">OUT_NUMBER=#{outnumber}</if> <if test="loadingrate!=null">LOADING_RATE=#{loadingrate}</if> <if test="boxnum!=null">BOX_NUM=#{boxnum}</if> <if test="packingunit!=null">PACKING_UNIT=#{packingunit}</if> <if test="price!=null">PRICE=#{price}</if> <if test="amount!=null">AMOUNT=#{amount}</if> <if test="finished!=null">FINISHED=#{finished}</if> <if test="exts!=null">EXTS=#{exts}</if> <if test="orderno!=null">ORDER_NO=#{orderno}</if> </set> <!-- 这里的id是 ContractProduct这个类里面的id--> where CONTRACT_PRODUCT_ID=#{id} </update> </mapper>
Dao层的代码:
就是BaseDaoImpl.java 的代码:
package cn.itcast.jk.dao.impl; import java.io.Serializable; import java.util.List; import java.util.Map; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.support.SqlSessionDaoSupport; import org.springframework.beans.factory.annotation.Autowired; import cn.itcast.jk.dao.BaseDao; import cn.itcast.jk.pagination.Page; public abstract class BaseDaoImpl<T> extends SqlSessionDaoSupport implements BaseDao<T>{ @Autowired //mybatis-spring 1.0无需此方法;mybatis-spring1.2必须注入。 public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory){ super.setSqlSessionFactory(sqlSessionFactory); } private String ns; //命名空间 public String getNs() { return ns; } public void setNs(String ns) { this.ns = ns; } public List<T> findPage(Page page){ List<T> oList = this.getSqlSession().selectList(ns + ".findPage", page); return oList; } public List<T> find(Map map) { List<T> oList = this.getSqlSession().selectList(ns + ".find", map); return oList; } public T get(Serializable id) { return this.getSqlSession().selectOne(ns + ".get", id); } public void insert(T entity) { this.getSqlSession().insert(ns + ".insert", entity); } public void update(T entity) { this.getSqlSession().update(ns + ".update", entity); } public void deleteById(Serializable id) { this.getSqlSession().delete(ns + ".deleteById", id); } public void delete(Serializable[] ids) { this.getSqlSession().delete(ns + ".delete", ids); } }
Service层:
package cn.itcast.jk.service.impl; import java.io.Serializable; import java.util.List; import java.util.Map; import java.util.UUID; import javax.annotation.Resource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import cn.itcast.jk.dao.ContractProductDao; import cn.itcast.jk.domain.Contract; import cn.itcast.jk.domain.ContractProduct; import cn.itcast.jk.pagination.Page; import cn.itcast.jk.service.ContractProductService; @Service public class ContractProductServiceImpl implements ContractProductService{ @Resource ContractProductDao contractProductDao; @Override public List<ContractProduct> findPage(Page page) { return contractProductDao.findPage(page); } @Override public List<ContractProduct> find(Map paraMap) { return contractProductDao.find(paraMap); } @Override public ContractProduct get(Serializable id) { return contractProductDao.get(id); } @Override public void insert(ContractProduct contractproduct) { contractproduct.setId(UUID.randomUUID().toString()); contractProductDao.insert(contractproduct); } @Override public void update(ContractProduct contractproduct) { contractProductDao.update(contractproduct); } @Override public void deleteById(Serializable id) { contractProductDao.deleteById(id); } @Override public void delete(Serializable[] ids) { contractProductDao.delete(ids); } }
控制层:ContractProductController.java:
package cn.itcast.jk.controller.cargo.contract; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.annotation.Resource; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import cn.itcast.jk.controller.BaseController; import cn.itcast.jk.domain.ContractProduct; import cn.itcast.jk.domain.Factory; import cn.itcast.jk.service.ContractProductService; import cn.itcast.jk.service.FactoryService; @Controller public class ContractProductController extends BaseController { @Resource ContractProductService contractProductService; @Resource FactoryService factoryService;//为了得到生产厂家的列表,我引入FactoryService的服务,因为合同货物表中,有factory_id和factoryname字段,所以要用这个服务区查询。 //跳转到新增的页面 @RequestMapping("/cargo/contractproduct/tocreate.action") public String tocreate(String contractId,Model model) { List<Factory> listfactory=factoryService.getFactoryList(); //得到工厂的列表。 Map<String, Object> map=new HashMap<String, Object>(); map.put("contractId",contractId);//这里的contractId是页面传进来的购销合同的主键, List<ContractProduct> datalist=contractProductService.find(map);//根据购销合同的主键,去查询合同货物表中这个主键的数据,
//在新增合同货物的页面下面是一个列表,这个列表是查看你选择新增的购销合同里面已经存在的合同货物。这样就可以知道合同货物有没有增加进去了。 model.addAttribute("contractId", contractId); model.addAttribute("listfactory", listfactory); model.addAttribute("datalist", datalist); return "/cargo/contract/jContractProductCreate.jsp";//调到新增页面 } //新增保存数据 @RequestMapping("/cargo/contractproduct/insert.action") public String insert(ContractProduct contractProduct,Model model) { contractProductService.insert(contractProduct); model.addAttribute("contractId", contractProduct.getContractid());//这里的contractId需要的,因为在这个函数最终跳转到
//"redirect:/cargo/contractproduct/tocreate.action",把contractId传入到tocreate.action请求中,这样才能显示出购销合同中的存在的合同货物
//重新回到新增的页面。为什么这么做呢?因为我们在录入货物的信息时不可能是只录入了一个 //肯定是录入了很多个的。所以要重新跳转到新增的页面。 return "redirect:/cargo/contractproduct/tocreate.action"; } }
新增合同货物的页面:
<%@ page language="java" pageEncoding="UTF-8"%> <%@ include file="../../base.jsp"%> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> <!-- 设置 id为factoryname的input的值--> <script type="text/javascript"> function setfactoryName(val) { var ere=document.getElementById("factoryname"); ere.value=val; } </script> <!-- <script type="text/javascript" src="../../js/datepicker/WdatePicker.js"></script> --> </head> <body> <form method="post"> <input text="text" name="contractid" value="${contractId}"> <div id="menubar"> <div id="middleMenubar"> <div id="innerMenubar"> <div id="navMenubar"> <ul> <li id="save"><a href="#" onclick="formSubmit('insert.action','_self');">确定</a></li> <li id="back"><a href="list.action">返回</a></li> </ul> </div> </div> </div> </div> <div class="textbox" id="centerTextbox"> <div class="textbox-header"> <div class="textbox-inner-header"> <div class="textbox-title">新增合同货物信息</div> </div> </div> <div> <div> <table class="commonTable" cellspacing="1"> <tr> <td class="columnTitle_mustbe">厂家名称:</td> <td class="tableContent"> <!-- <input type= name="factoryname" /> --> <!-- this.selectedIndex当前选中的索引值 -->
<!-- 做成下拉列表的效果-->
<select name="factoryid" onchange="setfactoryName(this.options[this.selectedIndex].text)"> <option value="">--请选择--</option> <c:forEach items="${listfactory}" var="f"> <option value="${f.id}">${f.factoryName }</option> </c:forEach> </select> <input type="hidden" id="factoryname" name="factoryname"> </td> <td class="columnTitle_mustbe">货号</td> <td class="tableContent"><input type="text" name="productno" /></td> </tr> <tr> <td class="columnTitle_mustbe">货物照片</td> <td class="tableContent"><input type="text" name="productimage" /></td> <td class="columnTitle_mustbe">货物描述</td> <td class="tableContent"><input type="text" name="productdesc" /></td> </tr> <tr> <td class="columnTitle_mustbe">数量</td> <td class="tableContent"><input type="text" name="cnumber" /></td> <td class="columnTitle_mustbe">实际出货数量</td> <td class="tableContent"><input type="text" name="outnumber" /></td> </tr> <tr> <td class="columnTitle_mustbe">装率</td> <td class="tableContent"><input type="text" name="loadingrate" /></td> <td class="columnTitle_mustbe">箱数</td> <td class="tableContent"><input type="text" name="boxnum" /></td> </tr> <tr> <td class="columnTitle_mustbe">包装单位</td> <td class="tableContent"><input type="text" name="packingunit" /></td> <td class="columnTitle_mustbe">单价</td> <td class="tableContent"><input type="text" name="price" /></td> </tr> <tr> <td class="columnTitle_mustbe">总金额</td> <td class="tableContent"><input type="text" name="amount" /></td> <td class="columnTitle_mustbe">是否出货完毕</td> <td class="tableContent"><input type="text" name="finished" /></td> </tr> <tr> <td class="columnTitle_mustbe">附件</td> <td class="tableContent"><input type="text" name="exts" /></td> <td class="columnTitle_mustbe">排序号</td> <td class="tableContent"><input type="text" name="orderno" /></td> </tr> </table> </div> </div> </form> <!-- 显示购销合同中所有的合同货物--> <div class="eXtremeTable" > <table id="ec_table" class="tableRegion" width="98%" > <thead> <tr> <td class="tableHeader"><input type="checkbox" name="selid" onclick="checkAll('id',this)"></td> <td class="tableHeader">厂家名称</td> <td class="tableHeader">货号</td> <td class="tableHeader">数量</td> <td class="tableHeader">实际出货数量</td> <td class="tableHeader">装率</td> <td class="tableHeader">箱数</td> <td class="tableHeader">包装单位</td> <td class="tableHeader">单价</td> <td class="tableHeader">总金额</td> </tr> </thead> <tbody class="tableBody" > <!--var="o"的意思是给datalist取个别名,之后用起来就简单了--> <c:forEach items="${datalist}" var="o" varStatus="status"> <tr class="odd" onmouseover="this.className='highlight'" onmouseout="this.className='odd'" > <!-- 做了一个选择框 --> <td><input type="checkbox" name="id" value="${o.id}"/></td> <td>${status.index+1}</td> <td>${o.factoryname}</td> <td>${o.productno}</td> <td>${o.cnumber}</td> <td>${o.outnumber}</td> <td>${o.loadingrate}</td> <td>${o.boxnum}</td> <td>${o.packingunit}</td> <td>${o.price}</td> <td>${o.amount}</td> </tr> </c:forEach> </tbody> </table> </div> </body> </html>
到这里,就完成了合同货物的新增功能。