MyBatis通用dao和通用service

更新於2015/01/29,增長了第三種方法

##更新於2015/02/09,第三種方法方法改進,service實現上不須要加泛型java

概述:

使用通用dao和通用service能夠減小代碼的開發。能夠將經常使用的增刪改查放到通用dao中。對不一樣的or框架,基本上都有本身的實現如SpringJPA的Repository就提供了經常使用的增刪改查方法。而MyBatis藉助代碼生成工具也能夠生成經常使用方法的映射spring

這裏只針對Mybatis。若是使用代碼生成工具,會有一個問題:每一個Mapper裏面都有一些方法(增曬改查)。維護起來的話還好。只是在寫service的時候會有一個問題。好比UserMapper裏面有 insert(User user) , find(Integer id) , delete(Integer id) 等方法,則在service中也要有這些方法的實現。假設每一個Mapper有5個方法。則service也須要有5個方法的實現。若是有10個實體類。mapper能夠省略(由生成工具生成),可是service有50個方法。到後期確定很差進行維護mybatis

使用通用Mapper和Service

該通用Mapper使用了Spring-mybatis。因此沒有實現類,而是直接調用xml文件中的同名方法。之因此將通用Mapper抽出來主要是爲了方便些通用的servicemvc

第一種:須要三個泛型,當前實體對象,主鍵,映射對象,

好處:具體Service實現類簡單,若是本身沒有特殊的方法,繼承BaseServiceImpl以後不須要寫任何東西app

很差之處:框架

  1. 每一個通用方法都須要傳遞映射參數:好比findById,若是是UserService調用,則須要這樣寫:userService.findById(1,UserMapper.class),這樣在BaseMapperImpl中才能夠經過class.getName獲得映射的名稱dom

  2. 並且在BaseMapperImpl中寫得比較死。修改起來比較複雜ide

第二種:

第一:不須要在方法上寫各類泛型參數,同時也不須要在各類方法中傳遞映射參數工具

第二:通用dao也不須要寫實現:mybatis-spring所倡導的的一致this

很差之處:

須要在每一個Service實現類中寫上:

@Autowired
    public void setBaseMapper(UserMapper userMapper){

        super.setBaseMapper(userMapper);
    }

並且關鍵的是@Autowired不能少。這個在開發過程當中很差進行限制

具體代碼

  1. 通用接口,該接口方法的名稱與使用代碼生成工具的名稱徹底相同
package cn.liuyiyou.yishop.mapper;
import java.io.Serializable;
public interface BaseMapper<T,ID extends Serializable> {
  int deleteByPrimaryKey(ID id);
  int insert(T record);
  int insertSelective(T record);
  T selectByPrimaryKey(ID id);
  int updateByPrimaryKeySelective(T record);
  int updateByPrimaryKeyWithBLOBs(T record);
  int updateByPrimaryKey(T record);
}
  1. 通用service接口。爲了方便,名字和通用Mapper同名,其實更傾向於命名add。edit,find這類的命名,顯得更加面向對象
package cn.liuyiyou.yishop.service;
import java.io.Serializable;
public interface BaseService<T,ID extends Serializable> {
  void setBaseMapper();
  int deleteByPrimaryKey(ID id);
  int insert(T record);
  int insertSelective(T record);
  T selectByPrimaryKey(ID id);
  int updateByPrimaryKeySelective(T record);
  int updateByPrimaryKeyWithBLOBs(T record);
  int updateByPrimaryKey(T record);
}
  1. 通用service實現。也很簡單。就是調用通用mapper裏面的方法便可
package cn.liuyiyou.yishop.service.impl;
import java.io.Serializable;
import cn.liuyiyou.yishop.mapper.BaseMapper;
import cn.liuyiyou.yishop.service.BaseService;
public abstract  class AbstractService<T, ID extends Serializable> implements BaseService<T, ID> {
  private BaseMapper<T, ID> baseMapper;
  public void setBaseMapper(BaseMapper<T, ID> baseMapper) {
    this.baseMapper = baseMapper;
  }
  @Override
  public int deleteByPrimaryKey(ID id) {
    return baseMapper.deleteByPrimaryKey(id);
  }
  @Override
  public int insertSelective(T record) {
    return baseMapper.insertSelective(record);
  }
  @Override
  public T selectByPrimaryKey(ID id) {
    return baseMapper.selectByPrimaryKey(id);
  }
  @Override
  public int updateByPrimaryKeySelective(T record) {
    return baseMapper.updateByPrimaryKey(record);
  }
  @Override
  public int updateByPrimaryKeyWithBLOBs(T record) {
    return baseMapper.updateByPrimaryKeyWithBLOBs(record);
  }
  @Override
  public int updateByPrimaryKey(T record) {
    return baseMapper.updateByPrimaryKey(record);
  }
  @Override
  public int insert(T record) {
    return baseMapper.insert(record);
  }
}
  1. 具體的Mapper寫法:
package cn.liuyiyou.yishop.mapper;
import java.util.List;
import org.springframework.stereotype.Repository;
import cn.liuyiyou.yishop.domain.ProductCategory;
@Repository
public interface ProductCategoryMapper extends BaseMapper<ProductCategory, Long>{
  /**
   * 經過父id獲得類目列表
   * @param praentId
   * @return
   */
  List<ProductCategory> selectByParent(Long parent);
}
  1. 具體的Servicd
package cn.liuyiyou.yishop.service.impl;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.liuyiyou.yishop.domain.Ad;
import cn.liuyiyou.yishop.domain.Product;
import cn.liuyiyou.yishop.mapper.AdMapper;
import cn.liuyiyou.yishop.mapper.ProductMapper;
import cn.liuyiyou.yishop.service.ProductService;
@Service
public class ProductServiceImpl extends AbstractService<Product,Long> implements ProductService {
  @Autowired
  private ProductMapper productMapper;
  @Autowired
  private AdMapper adMapper;
  //這句必需要加上。否則會報空指針異常,由於在實際掉用的時候不是BaseMapper調用,而是這個productMapper
  @Autowired
  public void setBaseMapper(){
    super.setBaseMapper(productMapper);
  }
  @Override
  public Map<String,Object> testTwo() {
    Product product = productMapper.selectByPrimaryKey(1l);
    Ad ad = adMapper.selectByPrimaryKey(1l);
    Map<String,Object> map = new HashMap<String,Object>();
    map.put("product", product);
    map.put("ad", ad);
    return map;
  }
}

第三種:更新於2015/01/31,增長了第三種方法

這一種算是第二種的改進。避免了在ServiceImpl中寫@Autowired

去掉,privste BaseMapper<T,ID> baseMapper。

package cn.liuyiyou.yishop.service.impl;
import java.io.Serializable;
import cn.liuyiyou.yishop.mapper.BaseMapper;
import cn.liuyiyou.yishop.service.BaseService;
public abstract class AbstractService<T, ID extends Serializable> implements BaseService<T, ID>{
  @Override
  public abstract BaseMapper<T, ID> getMapper() ;
  @Override
  public int deleteByPrimaryKey(ID id) {
    return getMapper().deleteByPrimaryKey(id);
  }
  @Override
  public int insert(T record) {
    return getMapper().insert(record);
  }
  @Override
  public int insertSelective(T record) {
    return getMapper().insertSelective(record);
  }
  @Override
  public T selectByPrimaryKey(ID id) {
    return getMapper().selectByPrimaryKey(id);
  }
  @Override
  public int updateByPrimaryKeySelective(T record) {
    return getMapper().updateByPrimaryKeySelective(record);
  }
  @Override
  public int updateByPrimaryKeyWithBLOBs(T record) {
    return getMapper().updateByPrimaryKeyWithBLOBs(record);
  }
  @Override
  public int updateByPrimaryKey(T record) {
    return getMapper().updateByPrimaryKey(record);
  }
}

具體的Service實現。在這個裏面,經過抽象的Service,來強制具體Service實現getMapper方法,而不須要在該方法上加@Autowired。

package cn.liuyiyou.yishop.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.liuyiyou.yishop.domain.Ad;
import cn.liuyiyou.yishop.mapper.AdMapper;
import cn.liuyiyou.yishop.mapper.BaseMapper;
import cn.liuyiyou.yishop.service.AdService;
import cn.liuyiyou.yishop.service.BaseService;
@Service
public class AdServiceImpl extends AbstractService<Ad,Long> implements AdService {
  @Autowired
  public AdMapper adMapper;
  @Override
  public BaseMapper<Ad, Long> getMapper() {
    return adMapper;
  }
}

最近更新於2015/02/09,第三種方法方法改進,service實現上不須要加泛型

之因此記錄下來的緣由是由於,在service接口上沒有使用泛型

package cn.liuyiyou.springmvc.mapper;
import java.io.Serializable;
/**
 * User: liuyiyou
 * Date: 14-12-27
 * Time: 下午11:39
 */
public interface BaseMapper<T,ID extends Serializable> {
  //只須要這個就能夠了,並不須要具體的實現,只須要在Service中設置BaseMapper
  T findById(ID id);
  Integer insert(T t);
}
package cn.liuyiyou.springmvc.service;
import java.io.Serializable;
/**
 * User: liuyiyou
 * Date: 14-12-27
 * Time: 下午11:53
 */
public interface BaseService <T,ID extends Serializable>{
  T findById(ID id);
  int insert(T t);
}
package cn.liuyiyou.springmvc.service;
import cn.liuyiyou.springmvc.mapper.BaseMapper;
import java.io.Serializable;
/**
 * User: liuyiyou
 * Date: 14-12-27
 * Time: 下午11:54
 */
public abstract class BaseServiceImpl<T,ID extends Serializable> implements BaseService<T,ID> {
   public abstract  BaseMapper getMapper();
  @Override
  public T findById(ID id) {
    return (T) getMapper().findById(id);
  }
  @Override
  public int insert(T t) {
    return getMapper().insert(t);
  }
}
package cn.liuyiyou.springmvc.service;
import cn.liuyiyou.springmvc.domain.User;
public interface UserService extends BaseService {
  boolean addUser(User user);
}
package cn.liuyiyou.springmvc.service;
import cn.liuyiyou.springmvc.mapper.BaseMapper;
import cn.liuyiyou.springmvc.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import cn.liuyiyou.springmvc.domain.User;
@Service
@Transactional(value="transactionManager")
public class UserServiceImpl extends BaseServiceImpl  implements UserService{
  @Autowired
  private UserMapper userMapper;
  @Override
  public BaseMapper getMapper(){
    return userMapper;
  }
  public boolean addUser(User user) {
    int reuslt = userMapper.insert(user);
    if (reuslt>0)
      return true;
    return	false;
  }
}
相關文章
相關標籤/搜索