ssm项目中Dao,Service抽取

                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;//id
	private 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;
	}

	@Override
	public 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;
    }

	@Override
	public 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;
	@Autowired
	protected  SupplierMapper supplierMapper;
	@Autowired
	protected  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/Account
				Class 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或者accountMapper
				Field 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);
		 
           
	}	
	
	@Override
	public int insert(T entity) throws Exception {
		return baseMapper.insert(entity);
	}

	@Override
	public int update(T entity) throws Exception {
		return baseMapper.update(entity);
	}

	@Override
	public int delete(T entity) throws Exception {
		return baseMapper.delete(entity);
	}

	@Override
	public T select(T entity) {
		return baseMapper.select(entity);
	}

	@Override
	public void selectKeyWordPageList(Page<T> page) {
		page.setList(baseMapper.selectKeyWordPageList(page));
		page.setTotalRecord(baseMapper.selectKeyWordTotalPage(page));
	}

	@Override
	public Integer selectKeyWordTotalPage(Page<T> page) {
		return  baseMapper.selectKeyWordTotalPage(page);
	}

	@Override
	public 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中, 这样我们就可以专注业务了, 

不是很舒服? 

          

    

              

                

   

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值