ssm项目中Dao,Service抽取

来源:互联网 发布:重新加载数据会丢吗 编辑:程序博客网 时间:2024/05/16 15:19

                ssm项目开发, 必须要关注MVC结构的每一个环节. 该文章要说的是不同层级之间的抽取,使得项目有较好的基础。以下编码的思想来自Java设计模式中的"策略模式"

               "策略模式"面向对象原则: (1)封装变化:即把变化与不会变化的分开(2)多用组合(在这里没有体现) (3)针对接口编程,不针对实现编程 

                

                准备二个bean, 分别是Supplier ,Account

             Supplier.java

package cn.itcast.scm.entity;import java.io.Serializable;import java.math.BigDecimal;public class Supplier implements Serializable {/** *  */private static final long serialVersionUID = -3051147093149131879L;private Integer supId;//idprivate String supName;// 供应商名称private String supLinkman;//联系人private String supPhone;  // 联系方式private String supAddress; //地址private String supRemark; //备注    private BigDecimal supPay;  //期初应付    private String supType; //供应商类型public Integer getSupId() {return supId;}public void setSupId(Integer supId) {this.supId = supId;}public String getSupName() {return supName;}public void setSupName(String supName) {this.supName = supName;}public String getSupLinkman() {return supLinkman;}public void setSupLinkman(String supLinkman) {this.supLinkman = supLinkman;}public String getSupPhone() {return supPhone;}public void setSupPhone(String supPhone) {this.supPhone = supPhone;}public String getSupAddress() {return supAddress;}public void setSupAddress(String supAddress) {this.supAddress = supAddress;}public String getSupRemark() {return supRemark;}public void setSupRemark(String supRemark) {this.supRemark = supRemark;}    public BigDecimal getSupPay() {return supPay;}public void setSupPay(BigDecimal supPay) {this.supPay = supPay;}public String getSupType() {return supType;}public void setSupType(String supType) {this.supType = supType;}@Overridepublic String toString() {return "Supplier [supId=" + supId + ", supName=" + supName+ ", supLinkman=" + supLinkman + ", supPhone=" + supPhone+ ", supAddress=" + supAddress + ", supRemark=" + supRemark+ ", supPay=" + supPay + ", supType=" + supType + "]";}}
 

Account.java
package cn.itcast.scm.entity;import java.io.Serializable;public class Account implements Serializable {private static final long serialVersionUID = 8971557569763969226L;private Integer accId;    private String accLogin;    private String accName;    private String accPass;    public Integer getAccId() {        return accId;    }    public void setAccId(Integer accId) {        this.accId = accId;    }    public String getAccLogin() {        return accLogin;    }    public void setAccLogin(String accLogin) {        this.accLogin = accLogin;    }    public String getAccName() {        return accName;    }    public void setAccName(String accName) {        this.accName = accName;    }    public String getAccPass() {        return accPass;    }    public void setAccPass(String accPass) {        this.accPass = accPass;    }@Overridepublic String toString() {return "Account [accId=" + accId + ", accLogin=" + accLogin+ ", accName=" + accName + ", accPass=" + accPass + "]";}   }
   

          

              1  Dao层的抽取 

                       从dao开始, 我们把共同的功能放在一起baseMapper 如CRUD, 把各自的数据库操作放在supplierMapper , accountMapper.  在application.xml中应该配置转换器, 这样我们应该通过注解方式自动生成mapper代理, , 我们将baseMapper抽取出来, 这样子在supplierMapper 中写自己的方法就行了! 

                      baseMapper 代码如下:

                        

package cn.itcast.scm.dao;import java.util.List;import cn.itcast.scm.entity.Page;public interface BaseMapper<T> { /**添加单个对象 * @param entity 需要插入的对象 * */public int insert(T entity);/**修改单个对象 * */public int update(T entity);/**删除单个对象 * */public int delete(T entity);/**查询单个对象 * */public T select(T entity); /** 分页查询  * */public List<T> selectKeyWordPageList(Page<T> page);/** 返回总记录数 * */public Integer selectKeyWordTotalPage(Page<T> page);/** 按照Id批量删除 * */public Integer deleteList(String [] arrays);}

          

package cn.itcast.scm.dao;import cn.itcast.scm.entity.Supplier;public interface SupplierMapper extends BaseMapper<Supplier> {//写自己的业务}

             以上是Dao的抽取, 挺简单

            

        2  Service 抽取

               由于service层有service的实现类, 抽取比较麻烦, 但是非常实用, 

                接口的处理和Dao是一样的! 只展示baseService

              

package cn.itcast.scm.service;import cn.itcast.scm.entity.Page;public interface BaseService<T> {/**添加单个对象 * */public int insert (T entity) throws Exception;/**修改单个对象 * */public int update(T entity) throws Exception;/**删除单个对象 * */public int delete(T entity) throws Exception;/**查询单个对象 * */public T select(T entity);/** 分页查询(page,rows)查询 * */ public void selectKeyWordPageList(Page<T> page);/** 返回总记录数 * */    public Integer selectKeyWordTotalPage(Page<T> page);        /**按照id批量删除     * */    public Integer deleteById(String[] arrays);}

                接下来就是对service实现的抽取, 为什么需要抽取呢?  我们的supplierServiceImpl实现类是需要继承baseService 和supplierService的.那么baseService中的方法都需要实现, 编码角度上看不清晰, oo原则上看, 不符合"封装变化", 于是我们需要写一个baseServiceImpl来处理.

         

               认真看注释, 就知道什么意思! 

               

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.BaseMapper;import cn.itcast.scm.dao.SupplierMapper;import cn.itcast.scm.entity.Page;import cn.itcast.scm.service.BaseService;/** *  * */  public class BaseServiceImpl<T> implements BaseService<T> {protected  BaseMapper<T> baseMapper;@Autowiredprotected  SupplierMapper supplierMapper;@Autowiredprotected  AccountMapper accountMapper;/** 该初始化函数作用是给baseMapper动态确认是哪个mapper; *  baseMapper=Supplier; * */@PostConstruct//在构造方法后,初化前执行private void initBaseMapper() throws Exception{           //完成以下逻辑,需要对研发本身进行命名与使用规范//this关键字指对象本身,这里指的是调用此方法的实现类(子类)       //this 具体来说是指SupplierServiceImpl / AccountserviceImpl/...System.out.println("=======this :"+this);System.out.println("=======父类基本信息:"+this.getClass().getSuperclass());System.out.println("=======父类和泛型的信息:"+this.getClass().getGenericSuperclass());//BaseServiceImpl<Supplier>ParameterizedType type =(ParameterizedType)this.getClass().getGenericSuperclass();//获取第一个参数的class---Supplier/AccountClass clazz = (Class)type.getActualTypeArguments()[0];System.out.println("=======class:"+clazz);//转化为属性名(相关的Mapper子类的引用名)Supplier //localField=supplierMapper/...String localField = clazz.getSimpleName().substring(0,1).toLowerCase()+clazz.getSimpleName().substring(1)+"Mapper";System.out.println("=======localField:"+localField);//getDeclaredField:可以使用于包括私有、默认、受保护、公共字段,但不包括继承的字段//就是该类的属性 supplierMapper或者accountMapperField field=this.getClass().getSuperclass().getDeclaredField(localField);System.out.println("=======field:"+field);System.out.println("=======field对应的对象:"+field.get(this));//baseMaper属性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实例化于容器中//baseMapper= supplierMapper(AccountMapper);baseField.set(this, field.get(this));System.out.println("========baseField对应的对象:"+baseMapper);            }@Overridepublic int insert(T entity) throws Exception {return baseMapper.insert(entity);}@Overridepublic int update(T entity) throws Exception {return baseMapper.update(entity);}@Overridepublic int delete(T entity) throws Exception {return baseMapper.delete(entity);}@Overridepublic T select(T entity) {return baseMapper.select(entity);}@Overridepublic void selectKeyWordPageList(Page<T> page) {page.setList(baseMapper.selectKeyWordPageList(page));page.setTotalRecord(baseMapper.selectKeyWordTotalPage(page));}@Overridepublic Integer selectKeyWordTotalPage(Page<T> page) {return  baseMapper.selectKeyWordTotalPage(page);}@Overridepublic Integer deleteById(String[] arrays) {return  baseMapper.deleteList(arrays);}}

              有了baseServiceImpl ,使用起来, SupplierServiceImpl ,AccountServiceImpl继承他, 那么里面就减少了很多"不必要的代码了", 只需要实现对应service接口中的方法! 

      如下SupplierServcieImpl.java就可以如下这样写了. 清晰美观,感觉好多了! 

            

package cn.itcast.scm.service.impl;import org.springframework.stereotype.Service;import cn.itcast.scm.entity.Supplier;import cn.itcast.scm.service.SupplierService;@Service("supplierService")public class SupplierServiceImpl extends BaseServiceImpl<Supplier>               implements SupplierService  {//写SupplierService实现,               }

        最后看看项目的结构: 发现BaseAction,BaseDao,BaseService,BaseServiecImpl 里面的都是共有的功能, 自己的业务都写在自己的Service中, 这样我们就可以专注业务了, 

不是很舒服? 

          

    

              

                

   

阅读全文
0 0
原创粉丝点击