阅读SSM项目之scm

供应链管理系统的分析 企业之间的竞争正日趋演变为供应链与供应链之间的角逐,SCM(供应链管理)系统也正在企业用户中形成广阔的市场。目前国内SCM建设情况如何?哪些企业正在实践SCM?国内用户在建设SCM系统中存在什么问题?他们如何看待SCM厂商? 立即下载


导入项目

项目是由eclipse来编写的,我使用的开发环境是Idea,那么就需要将eclipse项目导入进去Idea中。要想项目能够启动起来。是这样干的:

导入eclipse的项目

640?wx_fmt=png

添加对应的Web Model,添加完毕之后,默认会提示要我们创建对应的Facts的。

640?wx_fmt=png

接着修改Facets中标出的值,因为我们手动创建的话,指向的是Idea中的web目录的。可是项目是用eclipse编写的,因此要改成是WebRoot对应的文件!

640?wx_fmt=png

接着配置Tomcat,就基本可以让eclipse中的项目在Idea环境下运行了。

主菜单跳转JSP页面

在主菜单页面上有很多的URL跳转到不同的JSP页面。

640?wx_fmt=png

这些超链接是不同的模块下的。但是我们可以使用BaseAction对他们进行统一管理起来!

        //方法参数folder通过@PathVariable指定其值可以从@RequestMapping的{folder}获取,同理file也一样        @RequestMapping("/goURL/{folder}/{file}")        public String goURL(@PathVariable String folder,@PathVariable String file) {            return "forward:/WEB-INF/"+folder+"/"+file+".jsp";        }

       @RequestMapping("/goURL/{folder}/{file}")
       public String goURL(@PathVariable String folder,@PathVariable String file) {
           return "forward:/WEB-INF/"+folder+"/"+file+".jsp";
       }

我们常常在跳转页面之前都要查询数据库的数据的,那如果是这样设计的话,我们可以将常用数据放在application域对象中,或者使用ajax来进行获取数据!

分页对象设计

之前我们做的分页对象就仅仅把我们分页所用到的基本属性封装起来。如果页面上有查询条件的话,我们另外创建了一个查询对象。

当时候创建出来的查询对象的属性是根据页面上的条件来编写的。这样做得不够好,没有通用性!

这次看见这个项目的Page设计就非常通用了,虽然把查询条件都放在了Page对象中,但我感觉比之前那个好!

public class Page<T> implements Serializable {    private static final long serialVersionUID = 337297181251071639L;    private Integer page;//当前页    private Integer rows;//页大小    private Integer totalRecord;// 总记录 数    private List<T> list;//页面数据列表    private String keyWord;//查询关键字    private T paramEntity;//多条件查询    private Integer start;//需要这里处理    //因为它用的是easyUI,所以没有设置总页数的属性,使用Map集合来替代了。    private Map<String, Object> pageMap = new HashMap<String, Object>() ;    public Map<String, Object> getPageMap() {        return pageMap;    }    /*public void setPageMap(Map<String, Object> pageMap) {        this.pageMap = pageMap;    }*/    public T getParamEntity() {        return paramEntity;    }    public void setParamEntity(T paramEntity) {        this.paramEntity = paramEntity;    }    public Integer getPage() {        return page;    }    public void setPage(Integer page) {        this.page = page;    }    public Integer getRows() {        return rows;    }    public void setRows(Integer rows) {        this.rows = rows;    }    /*public Integer getTotalRecord() {        return totalRecord;    }*/    public void setTotalRecord(Integer totalRecord) {        pageMap.put("total", totalRecord);        this.totalRecord = totalRecord;    }/*    public List<T> getList() {        return list;    }*/    public void setList(List<T> list) {        pageMap.put("rows", list);        this.list = list;    }    public String getKeyWord() {        return keyWord;    }    public void setKeyWord(String keyWord) {        this.keyWord = keyWord;    }    public Integer getStart() {        this.start = (page-1)*rows;        return start;    }    public void setStart(Integer start) {        this.start = start;    }    @Override    public String toString() {        return "Page [page=" + page + ", rows=" + rows + ", totalRecord="                + totalRecord + ", list=" + list + ", keyWord=" + keyWord                + ", paramEntity=" + paramEntity + ", start=" + start + "]";    }}class Page<T> implements Serializable {


   private static final long serialVersionUID = 337297181251071639L;

   private Integer page;//当前页
   private Integer rows;//页大小
   private Integer totalRecord;// 总记录 数

   private List<T> list;//页面数据列表

   private String keyWord;//查询关键字

   private T paramEntity;//多条件查询

   private Integer start;//需要这里处理

   //因为它用的是easyUI,所以没有设置总页数的属性,使用Map集合来替代了。
   private Map<String, Object> pageMap = new HashMap<String, Object>() ;
   public Map<String, Object> getPageMap() {
       return pageMap;
   }
   /*public void setPageMap(Map<String, Object> pageMap) {
       this.pageMap = pageMap;
   }*/

   public T getParamEntity() {
       return paramEntity;
   }
   public void setParamEntity(T paramEntity) {
       this.paramEntity = paramEntity;
   }
   public Integer getPage() {
       return page;
   }
   public void setPage(Integer page) {
       this.page = page;
   }
   public Integer getRows() {
       return rows;
   }
   public void setRows(Integer rows) {
       this.rows = rows;
   }
   /*public Integer getTotalRecord() {
       return totalRecord;
   }*/

   public void setTotalRecord(Integer totalRecord) {
       pageMap.put("total", totalRecord);
       this.totalRecord = totalRecord;
   }
/*    public List<T> getList() {
       return list;
   }*/

   public void setList(List<T> list) {
       pageMap.put("rows", list);
       this.list = list;
   }
   public String getKeyWord() {
       return keyWord;
   }
   public void setKeyWord(String keyWord) {
       this.keyWord = keyWord;
   }
   public Integer getStart() {
       this.start = (page-1)*rows;
       return start;
   }
   public void setStart(Integer start) {
       this.start = start;
   }
   @Override
   public String toString() {
       return "Page [page=" + page + ", rows=" + rows + ", totalRecord="
               + totalRecord + ", list=" + list + ", keyWord=" + keyWord
               + ", paramEntity=" + paramEntity + ", start=" + start + "]";
   }
}

抽取Service层

之前我们也抽取过Service层的代码,当时候也觉得用得十分巧妙:

然而,这次看到的baseService就用得更加巧妙了,并且设计得更加好!

如下代码:

package cn.itcast.scm.service.impl;import java.lang.reflect.Field;import java.lang.reflect.ParameterizedType;import javax.annotation.PostConstruct;import org.springframework.beans.factory.annotation.Autowired;import cn.itcast.scm.dao.AccountMapper;import cn.itcast.scm.dao.AccountRecordsMapper;import cn.itcast.scm.dao.BaseMapper;import cn.itcast.scm.dao.BuyOrderDetailMapper;import cn.itcast.scm.dao.BuyOrderMapper;import cn.itcast.scm.dao.GoodsMapper;import cn.itcast.scm.dao.SupplierMapper;import cn.itcast.scm.dao.SysParamMapper;import cn.itcast.scm.entity.Page;import cn.itcast.scm.service.BaseService;public class BaseServiceImpl<T> implements BaseService<T> {    protected  BaseMapper<T> baseMapper;    @Autowired    protected  SupplierMapper supplierMapper;    @Autowired    protected  AccountMapper accountMapper;    @Autowired    protected  GoodsMapper goodsMapper;    @Autowired    protected  BuyOrderMapper buyOrderMapper;    @Autowired    protected  BuyOrderDetailMapper buyOrderDetailMapper;    @Autowired    protected  AccountRecordsMapper accountRecordsMapper;    @Autowired    protected  SysParamMapper sysParamMapper;    @PostConstruct//在构造方法后,初化前执行    private void initBaseMapper() throws Exception{        //完成以下逻辑,需要对研发本身进行命名与使用规范        //this关键字指对象本身,这里指的是调用此方法的实现类(子类)        System.out.println("=======this :"+this);        System.out.println("=======父类基本信息:"+this.getClass().getSuperclass());        System.out.println("=======父类和泛型的信息:"+this.getClass().getGenericSuperclass());        ParameterizedType type =(ParameterizedType) this.getClass().getGenericSuperclass();        //获取第一个参数的class        Class clazz = (Class)type.getActualTypeArguments()[0];        System.out.println("=======class:"+clazz);        //转化为属性名(相关的Mapper子类的引用名)Supplier  supplierMapper        String localField = clazz.getSimpleName().substring(0,1).toLowerCase()+clazz.getSimpleName().substring(1)+"Mapper";        System.out.println("=======localField:"+localField);        //getDeclaredField:可以使用于包括私有、默认、受保护、公共字段,但不包括继承的字段        Field field=this.getClass().getSuperclass().getDeclaredField(localField);        System.out.println("=======field:"+field);        System.out.println("=======field对应的对象:"+field.get(this));        Field baseField = this.getClass().getSuperclass().getDeclaredField("baseMapper");        System.out.println("=======baseField:"+baseField);        System.out.println("=======baseField对应的对象:"+baseField.get(this));        //field.get(this)获取当前this的field字段的值。例如:Supplier对象中,baseMapper所指向的对象为其子类型SupplierMapper对象,子类型对象已被spring实例化于容器中        baseField.set(this, field.get(this));        System.out.println("========baseField对应的对象:"+baseMapper);    }   }

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.annotation.Autowired;

import cn.itcast.scm.dao.AccountMapper;
import cn.itcast.scm.dao.AccountRecordsMapper;
import cn.itcast.scm.dao.BaseMapper;
import cn.itcast.scm.dao.BuyOrderDetailMapper;
import cn.itcast.scm.dao.BuyOrderMapper;
import cn.itcast.scm.dao.GoodsMapper;
import cn.itcast.scm.dao.SupplierMapper;
import cn.itcast.scm.dao.SysParamMapper;
import cn.itcast.scm.entity.Page;
import cn.itcast.scm.service.BaseService;

public class BaseServiceImpl<T> implements BaseService<T> {
   protected  BaseMapper<T> baseMapper;

   @Autowired
   protected  SupplierMapper supplierMapper;

   @Autowired
   protected  AccountMapper accountMapper;

   @Autowired
   protected  GoodsMapper goodsMapper;

   @Autowired
   protected  BuyOrderMapper buyOrderMapper;

   @Autowired
   protected  BuyOrderDetailMapper buyOrderDetailMapper;

   @Autowired
   protected  AccountRecordsMapper accountRecordsMapper;

   @Autowired
   protected  SysParamMapper sysParamMapper;

   @PostConstruct//在构造方法后,初化前执行
   private void initBaseMapper() throws Exception{

       //完成以下逻辑,需要对研发本身进行命名与使用规范
       //this关键字指对象本身,这里指的是调用此方法的实现类(子类)
       System.out.println("=======this :"+this);
       System.out.println("=======父类基本信息:"+this.getClass().getSuperclass());
       System.out.println("=======父类和泛型的信息:"+this.getClass().getGenericSuperclass());

       ParameterizedType type =(ParameterizedType) this.getClass().getGenericSuperclass();
       //获取第一个参数的class
       Class clazz = (Class)type.getActualTypeArguments()[0];
       System.out.println("=======class:"+clazz);
       //转化为属性名(相关的Mapper子类的引用名)Supplier  supplierMapper
       String localField = clazz.getSimpleName().substring(0,1).toLowerCase()+clazz.getSimpleName().substring(1)+"Mapper";
       System.out.println("=======localField:"+localField);

       //getDeclaredField:可以使用于包括私有、默认、受保护、公共字段,但不包括继承的字段
       Field field=this.getClass().getSuperclass().getDeclaredField(localField);
       System.out.println("=======field:"+field);
       System.out.println("=======field对应的对象:"+field.get(this));


       Field baseField = this.getClass().getSuperclass().getDeclaredField("baseMapper");
       System.out.println("=======baseField:"+baseField);
       System.out.println("=======baseField对应的对象:"+baseField.get(this));
       //field.get(this)获取当前this的field字段的值。例如:Supplier对象中,baseMapper所指向的对象为其子类型SupplierMapper对象,子类型对象已被spring实例化于容器中
       baseField.set(this, field.get(this));
       System.out.println("========baseField对应的对象:"+baseMapper);

   }  

}

这个baseService并没有给出对应的setDao的方法,那它是怎么将BaseDao实例化的呢???关键就在于initBaseMapper()这个方法!

我们来看一下方法内部打印数据的内容吧:

=======this :cn.itcast.scm.service.impl.BuyOrderServiceImpl@13a739e=======父类基本信息:class cn.itcast.scm.service.impl.BaseServiceImpl=======父类和泛型的信息:cn.itcast.scm.service.impl.BaseServiceImpl<cn.itcast.scm.entity.BuyOrder>=======class:class cn.itcast.scm.entity.BuyOrder=======localField:buyOrderMapper=======field:protected cn.itcast.scm.dao.BuyOrderMapper cn.itcast.scm.service.impl.BaseServiceImpl.buyOrderMapper=======field对应的对象:org.apache.ibatis.binding.MapperProxy@7cc946=======baseField:protected cn.itcast.scm.dao.BaseMapper cn.itcast.scm.service.impl.BaseServiceImpl.baseMapper=======baseField对应的对象:null========baseField对应的对象:org.apache.ibatis.binding.MapperProxy@7cc946BuyOrderServiceImpl@13a739e
=======父类基本信息:class cn.itcast.scm.service.impl.BaseServiceImpl
=======父类和泛型的信息:cn.itcast.scm.service.impl.BaseServiceImpl<cn.itcast.scm.entity.BuyOrder>
=======class:class cn.itcast.scm.entity.BuyOrder
=======localField:buyOrderMapper
=======field:protected cn.itcast.scm.dao.BuyOrderMapper cn.itcast.scm.service.impl.BaseServiceImpl.buyOrderMapper
=======field对应的对象:org.apache.ibatis.binding.MapperProxy@7cc946
=======baseField:protected cn.itcast.scm.dao.BaseMapper cn.itcast.scm.service.impl.BaseServiceImpl.baseMapper
=======baseField对应的对象:null
========baseField对应的对象:org.apache.ibatis.binding.MapperProxy@7cc946

这个方法被@PostConstruct注解给修饰着

通过我一阵的梳理,BaseDao的实例化过程是这样的:

其实上面也是通过具体的serviceImpl来对baseDao来进行初始化,不过它这样子做的话就显得更加优雅了。并不需要在每个具体的serviceImpl使用setDao()的方式来进行实例化。

通过上面的解释、我们把注释写上,就很容易理解了。

    /**     * 每当service实例化的时候,这个方法都会被调用     * @throws Exception     */    @PostConstruct    private void initBaseMapper() throws Exception{        //获取泛型的信息        ParameterizedType type =(ParameterizedType) this.getClass().getGenericSuperclass();        Class clazz = (Class)type.getActualTypeArguments()[0];        //拼接成“泛型”Mapper字符串        String localField = clazz.getSimpleName().substring(0,1).toLowerCase()+clazz.getSimpleName().substring(1)+"Mapper";        //通过反射来获取成员变量的值        Field field=this.getClass().getSuperclass().getDeclaredField(localField);        Field baseField = this.getClass().getSuperclass().getDeclaredField("baseMapper");        //将baseDao来进行实例化        baseField.set(this, field.get(this));    }
   @PostConstruct
   private void initBaseMapper() throws Exception{

       //获取泛型的信息
       ParameterizedType type =(ParameterizedType) this.getClass().getGenericSuperclass();
       Class clazz = (Class)type.getActualTypeArguments()[0];

       //拼接成“泛型”Mapper字符串
       String localField = clazz.getSimpleName().substring(0,1).toLowerCase()+clazz.getSimpleName().substring(1)+"Mapper";

       //通过反射来获取成员变量的值
       Field field=this.getClass().getSuperclass().getDeclaredField(localField);
       Field baseField = this.getClass().getSuperclass().getDeclaredField("baseMapper");

       //将baseDao来进行实例化
       baseField.set(this, field.get(this));
   }

分析项目的业务

本项目主要用EASY-UI来作为前段的页面构建。这里就不一一去探究EASY-UI的用法的,当用到这个前段UI的时候再回头看吧。下面就直接分析它的具体逻辑体悟了。

用户登陆

首先,程序的入口是用户登录的界面。用户设计得比较简单,因为只用来做登录。

CREATE TABLE account(    acc_id INT(11) PRIMARY KEY NOT NULL AUTO_INCREMENT,    acc_login VARCHAR(20),    acc_name VARCHAR(20),    acc_pass VARCHAR(20));TABLE account
(
   acc_id INT(11) PRIMARY KEY NOT NULL AUTO_INCREMENT,
   acc_login VARCHAR(20),
   acc_name VARCHAR(20),
   acc_pass VARCHAR(20)
);

对于用户登陆而言,我们已经是非常熟悉这个业务了。只是在数据库中对比一下数据、如果存在这个数据,那么在session域中保存即可!

640?wx_fmt=png

基本数据的数据库表

640?wx_fmt=png
CREATE TABLE supplier(    sup_id INT(11) PRIMARY KEY NOT NULL,    sup_name VARCHAR(20),    sup_linkman VARCHAR(20),    sup_phone VARCHAR(11),    sup_address VARCHAR(100),    sup_remark VARCHAR(100),    sup_pay DECIMAL(12,2),    sup_type VARCHAR(10));TABLE supplier
(
   sup_id INT(11) PRIMARY KEY NOT NULL,
   sup_name VARCHAR(20),
   sup_linkman VARCHAR(20),
   sup_phone VARCHAR(11),
   sup_address VARCHAR(100),
   sup_remark VARCHAR(100),
   sup_pay DECIMAL(12,2),
   sup_type VARCHAR(10)
);
640?wx_fmt=png
CREATE TABLE goods(    goods_Id VARCHAR(36) PRIMARY KEY NOT NULL,    goods_name VARCHAR(20),    goods_unit VARCHAR(10),    goods_type VARCHAR(10),    goods_color VARCHAR(10),    goods_store INT(11),    goods_limit INT(11),    goods_commission DECIMAL(2,2),    goods_producer VARCHAR(50),    goods_remark VARCHAR(100),    goods_sel_price DECIMAL(12,2),    goods_buy_price DECIMAL(12,2));TABLE goods
(
   goods_Id VARCHAR(36) PRIMARY KEY NOT NULL,
   goods_name VARCHAR(20),
   goods_unit VARCHAR(10),
   goods_type VARCHAR(10),
   goods_color VARCHAR(10),
   goods_store INT(11),
   goods_limit INT(11),
   goods_commission DECIMAL(2,2),
   goods_producer VARCHAR(50),
   goods_remark VARCHAR(100),
   goods_sel_price DECIMAL(12,2),
   goods_buy_price DECIMAL(12,2)
);
640?wx_fmt=png
CREATE TABLE store_house(    sh_id VARCHAR(10) PRIMARY KEY NOT NULL,    sh_name VARCHAR(20),    sh_responsible VARCHAR(20),    sh_phone VARCHAR(11),    sh_address VARCHAR(50),    sh_type VARCHAR(10),    sh_remark VARCHAR(100));TABLE store_house
(
   sh_id VARCHAR(10) PRIMARY KEY NOT NULL,
   sh_name VARCHAR(20),
   sh_responsible VARCHAR(20),
   sh_phone VARCHAR(11),
   sh_address VARCHAR(50),
   sh_type VARCHAR(10),
   sh_remark VARCHAR(100)
);

上边这几张表都仅仅是CRUD的操作。

那么这个项目是这样处理的,将经常用到的数据用一张表保存起来。

drop table if exists sys_param;/*====================================系统参数表==============================*//*==============================================================*//* Table: sys_param                                             *//*==============================================================*//*create table sys_param(   sys_param_id         bigint  auto_increment,   sys_param_field      varchar(50),   sys_param_value      varchar(50),   sys_param_text       varchar(50),   primary key (sys_param_id));*/create table sys_param(   sys_param_id         bigint  auto_increment,   sys_param_field      varchar(50),   sys_param_value      varchar(500),   sys_param_text       varchar(50),   sys_param_type       varchar(2),      primary key (sys_param_id));insert into sys_param(sys_param_field,sys_param_value,sys_param_type) values('shId','select s.sh_id as sys_param_value,s.sh_name as sys_param_text from store_house s','1');insert into sys_param(sys_param_field,sys_param_value,sys_param_text) values('supType','1','一级供应商');insert into sys_param(sys_param_field,sys_param_value,sys_param_text) values('supType','2','二级供应商');insert into sys_param(sys_param_field,sys_param_value,sys_param_text) values('supType','3','普通供应商');insert into sys_param(sys_param_field,sys_param_value,sys_param_text) values('goodsColor','1','红色');insert into sys_param(sys_param_field,sys_param_value,sys_param_text) values('goodsColor','2','绿色');insert into sys_param(sys_param_field,sys_param_value,sys_param_text) values('goodsColor','3','蓝色');select * from sys_param;table if exists sys_param;
/*====================================系统参数表==============================*/
/*==============================================================*/
/* Table: sys_param                                             */
/*==============================================================*/
/*
create table sys_param
(
  sys_param_id         bigint  auto_increment,
  sys_param_field      varchar(50),
  sys_param_value      varchar(50),
  sys_param_text       varchar(50),
  primary key (sys_param_id)
);
*/

create table sys_param
(
  sys_param_id         bigint  auto_increment,
  sys_param_field      varchar(50),
  sys_param_value      varchar(500),
  sys_param_text       varchar(50),
  sys_param_type       varchar(2),  
  primary key (sys_param_id)
);
insert into sys_param(sys_param_field,sys_param_value,sys_param_type) values('shId','select s.sh_id as sys_param_value,s.sh_name as sys_param_text from store_house s','1');


insert into sys_param(sys_param_field,sys_param_value,sys_param_text) values('supType','1','一级供应商');
insert into sys_param(sys_param_field,sys_param_value,sys_param_text) values('supType','2','二级供应商');
insert into sys_param(sys_param_field,sys_param_value,sys_param_text) values('supType','3','普通供应商');
insert into sys_param(sys_param_field,sys_param_value,sys_param_text) values('goodsColor','1','红色');
insert into sys_param(sys_param_field,sys_param_value,sys_param_text) values('goodsColor','2','绿色');
insert into sys_param(sys_param_field,sys_param_value,sys_param_text) values('goodsColor','3','蓝色');
select * from sys_param;

上面我们可以看到,除了单单保存了一些的基本属性之外,我们来存储了SQL语句,那么我们怎么将SQL语句转成是我们的数据呢???

640?wx_fmt=png

那它是怎么实现这种玩意的呢??

Mapper查询表的数据

  <select id="selectList" parameterType="String" resultMap="sysParamResultMap">            select * from sys_param  </select>  <!-- 查询其它表的数据,使用${value}格式,允许使用sql语句作为参数执行 -->  <select id="selectOthreTable" parameterType="string" resultMap="sysParamResultMap">      ${value}  </select>
     select * from sys_param
 </select>

 <!-- 查询其它表的数据,使用${value}格式,允许使用sql语句作为参数执行 -->
 <select id="selectOthreTable" parameterType="string" resultMap="sysParamResultMap">
     ${value}
 </select>

Service将数据封装到一个总的Map中。具体的做法是这样子的:

package cn.itcast.scm.service.impl;import cn.itcast.scm.entity.SysParam;import cn.itcast.scm.service.SysParamService;import org.springframework.stereotype.Service;import java.util.HashMap;import java.util.List;import java.util.Map;@Service("sysParamService")public class SysParamServiceImpl extends BaseServiceImpl<SysParam> implements SysParamService {    @Override    public Map<String, Object> selectList() {        //查询出表中所有所有数据        List<SysParam> sysParams = sysParamMapper.selectList("");        //存储属性字段具体的值        Map<String, Object> fieldMap = null;        //最终的Map,key是属性字段,value是一个map(属性字段具体的值)        Map<String, Object> sysParamMap = new HashMap<String, Object>();        //遍历表中的记录,看是否有类型为1的字段数据!也就是SQL数据        for (SysParam sysParam : sysParams) {            if ("1".equals(sysParam.getSysParamType())) {                String sql = sysParam.getSysParamValue();                //执行SQL,得到查询后的记录                List<SysParam> otherList = sysParamMapper.selectOthreTable(sql);                fieldMap = new HashMap<>();                /**                 * select s.sh_id as sys_param_value,s.sh_name as sys_param_text  from store_house s                 */                //遍历查询后的记录,并把数据存到字段MAP                for (SysParam otherSysParam : otherList) {                    /**                     * key = 仓库的具体Id                     * value = 页面显示的仓库名称                     */                    fieldMap.put(otherSysParam.getSysParamValue(), otherSysParam.getSysParamText());                }                /**                 * key = shId                 * value = 存储具体数据的Map集合                 */                sysParamMap.put(sysParam.getSysParamField(), fieldMap);            } else {                //判断系统参数的map中是否存在字段的map,如果不存在,就新建一个                if (sysParamMap.get(sysParam.getSysParamField()) == null) {                    fieldMap = new HashMap<>();                    /**                     * key  = 1                     * value = 一级供应商                     */                    fieldMap.put(sysParam.getSysParamValue(), sysParam.getSysParamText());                    /**                     * key = supType                     * value = 存储具体数据的Map集合                     */                    sysParamMap.put(sysParam.getSysParamField(), fieldMap);                } else {                    //如果存在,那么就在原先的Map集合中添加                    fieldMap = (Map<String, Object>) sysParamMap.get(sysParam.getSysParamField());                    fieldMap.put(sysParam.getSysParamValue(), sysParam.getSysParamText());                }            }        }        /**         * key = shId        value = Map-->(1  主仓库)         *                             (2  分仓库)         *         * key = supType    value= Map-->( 1   一级供应商)         *                              ( 2  二级供应商)...         * key = goodsColor  value = Map--> (1  红色)....         */        return sysParamMap;    }}

import cn.itcast.scm.entity.SysParam;
import cn.itcast.scm.service.SysParamService;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service("sysParamService")
public class SysParamServiceImpl extends BaseServiceImpl<SysParam> implements SysParamService {

   @Override
   public Map<String, Object> selectList() {

       //查询出表中所有所有数据
       List<SysParam> sysParams = sysParamMapper.selectList("");

       //存储属性字段具体的值
       Map<String, Object> fieldMap = null;

       //最终的Map,key是属性字段,value是一个map(属性字段具体的值)
       Map<String, Object> sysParamMap = new HashMap<String, Object>();


       //遍历表中的记录,看是否有类型为1的字段数据!也就是SQL数据
       for (SysParam sysParam : sysParams) {
           if ("1".equals(sysParam.getSysParamType())) {
               String sql = sysParam.getSysParamValue();
               //执行SQL,得到查询后的记录
               List<SysParam> otherList = sysParamMapper.selectOthreTable(sql);
               fieldMap = new HashMap<>();

               /**
                * select s.sh_id as sys_param_value,s.sh_name as sys_param_text  from store_house s
                */

               //遍历查询后的记录,并把数据存到字段MAP
               for (SysParam otherSysParam : otherList) {
                   /**
                    * key = 仓库的具体Id
                    * value = 页面显示的仓库名称
                    */

                   fieldMap.put(otherSysParam.getSysParamValue(), otherSysParam.getSysParamText());
               }
               /**
                * key = shId
                * value = 存储具体数据的Map集合
                */

               sysParamMap.put(sysParam.getSysParamField(), fieldMap);

           } else {
               //判断系统参数的map中是否存在字段的map,如果不存在,就新建一个
               if (sysParamMap.get(sysParam.getSysParamField()) == null) {
                   fieldMap = new HashMap<>();
                   /**
                    * key  = 1
                    * value = 一级供应商
                    */

                   fieldMap.put(sysParam.getSysParamValue(), sysParam.getSysParamText());

                   /**
                    * key = supType
                    * value = 存储具体数据的Map集合
                    */

                   sysParamMap.put(sysParam.getSysParamField(), fieldMap);
               } else {

                   //如果存在,那么就在原先的Map集合中添加
                   fieldMap = (Map<String, Object>) sysParamMap.get(sysParam.getSysParamField());
                   fieldMap.put(sysParam.getSysParamValue(), sysParam.getSysParamText());
               }
           }
       }
       /**
        * key = shId        value = Map-->(1  主仓库)
        *                             (2  分仓库)
        *
        * key = supType    value= Map-->( 1   一级供应商)
        *                              ( 2  二级供应商)...
        * key = goodsColor  value = Map--> (1  红色)....
        */

       return sysParamMap;
   }
}

controller使用@PostConstruct注解,在初始化的时候就把数据加载到application域对象中

    //系统启动时加载参数    @PostConstruct    public void initSysParam(){        loadSysParam();    }    //用来加载系统参数      public void loadSysParam(){        Map<String, Object> sysParamMap = sysParamService.selectList();        application.setAttribute("sysParam", sysParamMap);        System.out.println("===================系统参数加载成功2=====================");    }
   @PostConstruct
   public void initSysParam(){
       loadSysParam();
   }

   //用来加载系统参数  
   public void loadSysParam(){
       Map<String, Object> sysParamMap = sysParamService.selectList();
       application.setAttribute("sysParam", sysParamMap);
       System.out.println("===================系统参数加载成功2=====================");
   }

采购商品

640?wx_fmt=png

采购表buy_order:

单号bo_id,供货商sup_id,仓库sh_id,收货日期bo_date,应付(实付+欠款+优惠)bo_payable,实付bo_paid,欠款bo_Arrears,原始单号bo_original_id,备注bo_remark,经办人bo_attn,操作员operator。

采购明细表buy_order_detail:

编号bod_id:商品名称goods_id,单位goods_unit,数量 bod_amount,进价bod_buy_price,总金额(可无)bod_total_price,    采购单号bo_id,手机串号列表(##分隔)bod_IMEI

账务表account_records:

编号ad_id,供货商编号sup_id,日期ad_date,单号(不同类型单号不一样)ad_order_id,类型(业务类型)ad_bus_type,应付ad_payable,    实付ad_paid,欠款ad_arrears,优惠金额ad_discount,经办人ad_attn,操作员ad_operator。备注ad_remark
640?wx_fmt=png

数据在插入的时候涉及到了这三张的数据库表:

640?wx_fmt=png

至于我们的财务表的数据是用于拓展的,属性的信息基本是在采购表中获取:

    public int insertBuyOrder(BuyOrder buyOrder) throws Exception {        // TODO Auto-generated method stub        System.out.println("service.buyOrder:"+buyOrder);        int i = 0;              //生成采购单号,bo表示采购业务        //bo --商品采购        //ro --商品退货        //        String boId ="bo"+UUID.randomUUID().toString().replace("-", "");        System.out.println("boIduuid:"+boId);        //设置采购单号        buyOrder.setBoId(boId);             i = buyOrderMapper.insert(buyOrder);        //设置采购明细主键及与采购单的外键值        for(BuyOrderDetail bod : buyOrder.getBuyOrderDetails()){            bod.setBodId(UUID.randomUUID().toString().replace("-", ""));            bod.setBoId(boId);        }        buyOrderDetailMapper.insertList(buyOrder.getBuyOrderDetails());        AccountRecords accountRecords = new AccountRecords();        // 生成并设置怅务记录的主键        accountRecords.setArId(String.valueOf("ar"+UUID.randomUUID().toString().replace("-", "")));        accountRecords.setArAttn(buyOrder.getBoAttn());        accountRecords.setArArrears(buyOrder.getBoArrears());        //bo表示商品采购,可以在参数表中加入相关内容        accountRecords.setArBusType("bo");        accountRecords.setArDate(buyOrder.getBoDate());        //优惠金额:用应付金额减去实付金额再减去欠款        accountRecords.setArDiscount(buyOrder.getBoPayable().subtract(buyOrder.getBoPaid()).subtract(buyOrder.getBoArrears()));        accountRecords.setArOperator(buyOrder.getBoOperator());        //采购单号        accountRecords.setArOrderId(buyOrder.getBoId());        accountRecords.setArPaid(buyOrder.getBoPaid());        accountRecords.setArPayable(buyOrder.getBoPayable());        accountRecords.setArRemark(buyOrder.getBoRemark());        accountRecords.setSupId(buyOrder.getSupId());        accountRecordsMapper.insert(accountRecords);        return i;    }
       // TODO Auto-generated method stub
       System.out.println("service.buyOrder:"+buyOrder);
       int i = 0;      
       //生成采购单号,bo表示采购业务

       //bo --商品采购
       //ro --商品退货
       //
       String boId ="bo"+UUID.randomUUID().toString().replace("-", "");
       System.out.println("boIduuid:"+boId);
       //设置采购单号
       buyOrder.setBoId(boId);    
       i = buyOrderMapper.insert(buyOrder);

       //设置采购明细主键及与采购单的外键值
       for(BuyOrderDetail bod : buyOrder.getBuyOrderDetails()){
           bod.setBodId(UUID.randomUUID().toString().replace("-", ""));
           bod.setBoId(boId);
       }
       buyOrderDetailMapper.insertList(buyOrder.getBuyOrderDetails());

       AccountRecords accountRecords = new AccountRecords();
       // 生成并设置怅务记录的主键
       accountRecords.setArId(String.valueOf("ar"+UUID.randomUUID().toString().replace("-", "")));
       accountRecords.setArAttn(buyOrder.getBoAttn());
       accountRecords.setArArrears(buyOrder.getBoArrears());
       //bo表示商品采购,可以在参数表中加入相关内容
       accountRecords.setArBusType("bo");
       accountRecords.setArDate(buyOrder.getBoDate());
       //优惠金额:用应付金额减去实付金额再减去欠款
       accountRecords.setArDiscount(buyOrder.getBoPayable().subtract(buyOrder.getBoPaid()).subtract(buyOrder.getBoArrears()));
       accountRecords.setArOperator(buyOrder.getBoOperator());
       //采购单号
       accountRecords.setArOrderId(buyOrder.getBoId());
       accountRecords.setArPaid(buyOrder.getBoPaid());
       accountRecords.setArPayable(buyOrder.getBoPayable());
       accountRecords.setArRemark(buyOrder.getBoRemark());
       accountRecords.setSupId(buyOrder.getSupId());
       accountRecordsMapper.insert(accountRecords);

       return i;
   }

总结

如果文章有错的地方欢迎指正,大家互相交流。习惯在微信看技术文章,想要获取更多的Java资源的同学,可以关注微信公众号:Java3y


SpringBoot+Vue+Mysql社区医院信息平台(源码+文档) SpringBoot+Vue+Mysql学生宿舍信息管理系统 WEB端软件项目(源码+文档) 项目包含:①完整源码(后端+管理后台+用户前台);②数据库脚本文件;③万字论文文档;④开题报告;⑤答辩PPT;⑥项目运行视频教程。 项目架构: B/S 架构、MVC 分层设计 技术栈: Java、MySQL、SpringBoot、MyBatis-Plus、Token 权限校验、管理后台 Vue+ElementUI+ECharts、用户前台 Layui+jQuery、Maven 构建。 一、角色设计 学生用户: 注册登录、浏览宿舍信息、查询宿舍安排、在线报修、缴费查询、失物招领、桶装水预订、评论交流、收藏等。 商家用户: 注册登录、桶装水品牌与商品信息维护、预订订单查看与处理。 维修人员: 注册登录、查看待处理报修、接单维修、填写报修处理结果与进度反馈。 管理员: 学生管理、班级管理、宿舍信息管理、宿舍安排管理、报修处理管理、缴费信息管理、卫生检查与文明宿舍管理、失物招领管理、桶装水与商家管理、维修人员管理、公告资讯与轮播图管理等。 二、前台功能模块(学生端) 1. 首页展示:轮播图、宿舍公告、最新动态推荐、常用服务快速入口 2. 宿舍信息模块:宿舍列表、楼栋与房间条件筛选、宿舍详情查看、我的宿舍安排查询 3. 在线报修模块:在线提交宿舍设施报修申请、上传故障描述、查看报修进度与维修处理结果 4. 缴费模块:水电等缴费记录查询、缴费状态查看 5. 卫生检查与文明宿舍:宿舍卫生检查结果公示、文明宿舍展示 6. 失物招领模块:失物信息发布、招领信息发布、详情查看、评论互动 7. 桶装水预订:桶装水品牌与商品浏览、在线预订、我的预订记录查询 8. 假期留宿:假期留校申请提交、申请记录查询 9. 评论与收藏:信息评论、查看他人评论、评论回复互动、收藏感兴趣的内容 10. 个人中心... 立即下载

相关推荐

YOLOv8作物病害检测实战源码

这是一套基于YOLOv8n的农田病虫害目标检测系统,对叶片照片做目标检测,识别健康叶片、褐斑病、白粉病、锈病四类,并给出对应防治建议。全流程纯CPU可跑,配套交付完整Python源码、9章实战教程(md/html/pdf三种格式)、100张自造样本及YOLO标签、训练曲线与混淆矩阵截图、Tkinter界面和答辩PPT。 系统围绕五项功能展开:同一套推理逻辑覆盖图像、视频、摄像头三种来源;图形界面选文件即检测,画面叠彩色框标注病名与置信度,右侧面板同步给出症状与防治措施;检测记录自动写入CSV,统计页一键生成四类病害占比饼图;训练结束自动产出损失与精度曲线;内置防治建议文案库,检测命中即回填面板。 选型用YOLOv8n nano档,参数量约320万、权重约6.2MB,CPU单帧几十毫秒,小样本训练5到8分钟完成。数据由data_gen.py程序化绘制100张叶片图,固定随机种子,重跑分布一致,不依赖公开数据集。依赖全部锁版本,教程第7章整理了19条真实报错及排查方法,第8章给出换模型档、换PlantVillage数据集的迁移路径。 适合做计算机视觉方向课程设计或毕业设计的学生,也适合智慧农业方向想了解检测模型如何落进业务面板的学习者。不需要GPU,不需要系统学过目标检测,教程第3章会按需补齐原理。 使用时先pip install -r requirements.txt装好依赖,download_data.py下载预训练权重,data_gen.py生成样本后train.py训练,完成后用main.py infer批量检测或main.py gui启动界面。

阅读SSM项目之scm【第二篇】

tags: SSM整合与阅读项目 阅读SSM项目之scm【第二篇】 采购商品 采购表buy_order: 单号bo_id,供货商sup_id,仓库sh_id,收货日期bo_date,应付(实付+欠款+优惠)bo_payable,实付bo_paid,欠款bo_Arrears,原始单号bo_original_id,备注bo_remark,经办人bo_attn,操作员operator。 复制代码...

weixin_33725270的博客 192

数据挖掘实战:决策树 + 聚类 + 关联规则,零 Key 离线可跑(Python 源码)

数据挖掘实战包。用 Python 标准库实现 CART 风格决策树、K-Means 聚类与 Apriori 关联规则,在虚构「星河便利店」会员表和购物篮上跑通分类、分群与购物篮分析,并给出准确率、轮廓系数、支持度/置信度/提升度。零第三方依赖、零 API Key 即可离线跑通。含 4 个样例、离线冒烟、中文 README(含「使用方法」)。均为作者原创可运行源码。MIT。作者 blog.youkuaiyun.com/mtl1994

阅读SSM项目之scm【第一篇】

tags: SSM整合与阅读项目 导入项目 项目是由eclipse来编写的,我使用的开发环境是Idea,那么就需要将eclipse项目导入进去Idea中。要想项目能够启动起来。是这样干的: 导入eclipse的项目 添加对应的Web Model,添加完毕之后,默认会提示要我们创建对应的Facts的。 接着修改Facets中标出的值,因为我们手动创建的话,指向的是Idea中的web目录的。可...

weixin_34235457的博客 216

科技中介服务机构在技术供需对接中如何实现服务流程的自动化与标准化?.docx

科技中介服务机构在技术供需对接中如何实现服务流程的自动化与标准化?

产业园区如何高效对接企业技术需求与高校科研成果?.docx

科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。

供应链管理(SCM)的两种模式

面对当前全球化市场竞争日益激烈,企业的发展乃至生存在不同程度上受到威胁。在巨大的经济浪潮的冲击下,市场竞争已不再是单纯的企业与企业之间的竞争,而是供应链与供应链之间的竞争。因此,提高管理不同模式的供应链的能力就显得非常重要了。   “推销”模式是传统的供应链模式,指根据商品的库存情况,有计划地将商品推销给客户。而当前更多的是“需求动力”模式,顾名思义,该供应...

weixin_34405925的博客 817

国央企创新负责人如何快速掌握本地科技资源分布与匹配情况?.docx

科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。

网络作家写作平台(ssm,mysql)

网络作家写作平台(ssm,mysql) 本文主要阐述了一个网络作家写作平台,论文首先对系统使用的相关工具和技术进行说明,然后对数据库的结构设计进行说明,对系统模块进行详细设计,并且进行编码实现,最后对系统进行功能模块的测试。 关键词:网络作家写作平台;myeclipse;B/S; java 网络作家写作平台(ssm,mysql)(毕业论文16000字以上,程序代码,MySql数据库,数据库脚本) 开发环境:Eclipse Mars JDK: JDK1.8Web服务器:Tomcat8数据库:MyS

sunboy227的博客 437

国央企创新负责人如何实现科技成果的精准识别与高效筛选?.docx

科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。

高校技术转移办公室人员如何系统化管理科技成果信息?.docx

科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。

【MS SQL】把多个数据库合并为一个新的数据库

【MS SQL】把多个数据库合并为一个新的数据库 原文:【MS SQL】把多个数据库合并为一个新的数据库因应工作要求,需要把两个数据库合并成一个库: 一开始使用"导入数据、导出数据和复制数据库"三个工具时,没有达到要的效果。 后来,使用"生成脚本"来执行,成功!步骤如下: 1、新建一个空白库 -> SCM_KQYY: ...

weixin_30808693的博客 441

科技中介服务机构如何构建标准化、模块化的智能服务工具?.docx

科易网基于AI模型+行业大数据,在技术转移、成果转化、技术经纪、知识产权、产业创新、科技招商等垂直领域的多样化应用场景,推出科技创新领域的AI+工具与数智化解决方案,推动科技创新与产业创新智能化发展。

教你一招最屌的阅读开源项目的姿势

相信自从看了我的 GitHub 教程很多人开始爱上了 GitHub,有些人微博也不刷了,知乎也不刷了,改刷 GitHub 了,而且刷的不亦乐乎。这是好事,多接触多了解一些开源项目,对你之后的项目中的开发效率有很大提高。但是,我要告诉你们的是,你们不是正确的姿势在阅读开源项目,今天就教你们一招最屌的姿势。首先说明下,这里的「阅读」是泛指,对于 Android 来说,除了阅读还有运行 demo 看下项目

stormzhang的专栏 6070

fab-pm-optimizer-python-entry-py39-20261021-v1-1-0

fab-pm-optimizer-python-entry-py39-20261021-v1-1-0

PSIM-三相维也纳VIENNA整流器电压电流双闭环+中点电位平衡SVPWM控制仿真

内容概要:本文档详细介绍了一种基于PSIM软件实现的三相维也纳(VIENNA)整流器仿真模型,重点实现了电压电流双闭环控制与中点电位平衡的SVPWM调制策略。该仿真系统通过精确的控制算法有效提升了整流器的功率因数,降低了输入电流谐波含量,并解决了三电平拓扑中常见的直流侧中点电位偏移问题,具有较高的工程实用价值,适用于高效率、高功率密度的电力电子系统设计与科研验证。文档还整合了丰富的配套资源,涵盖多种电力电子变换器拓扑结构、先进控制算法及典型应用场景,形成了系统化的技术资料体系,有助于深入理解现代整流技术的核心原理与发展动态。; 适合人群:面向从事电力电子、电气工程、新能源变换系统等领域的科研人员、高校研究生以及具备一定仿真基础的工程技术人员。; 使用场景及目标:①深入研究三相VIENNA整流器的工作机理与控制特性;②掌握电压外环、电流内环双闭环控制结构的设计方法;③理解并实现SVPWM调制技术与中点电位平衡控制策略的协同作用;④开展相关控制算法的仿真验证、性能优化与实验对比,为高性能整流装置的研发提供理论支撑和技术原型。; 阅读建议:建议结合文中列出的其他仿真案例(如PWM整流器、LLC谐振变换器、DAB变换器等)进行横向对比学习,充分利用所提供的PSIM、MATLAB/Simulink等多平台仿真资源,重点关注控制逻辑与主电路的耦合关系,通过参数调试与波形分析深化对系统动态响应和稳态性能的理解,强化“理论—建模—仿真—优化”的闭环研究能力。

上一篇: Spring【DAO模块】知识要点
下一篇: 阅读SSH项目之ERP
Java3y
Java3y 领域专家: 后端开发技术领域 领域专家: 后端开发技术领域
博客等级 码龄9年 1万+粉丝 509原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值